import { createFileRoute } from "@tanstack/react-router";
import { RequireRole } from "@/hooks/use-roles";
import { useEffect, useMemo, useState } from "react";
import { useQuery, useQueryClient } from "@tanstack/react-query";
import { supabase } from "@/integrations/supabase/client";
import { Button } from "@/components/ui/button";
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card";
import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";
import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "@/components/ui/table";
import { BarChart3, Download, FileText, RefreshCw } from "lucide-react";

export const Route = createFileRoute("/_authenticated/reports")({
  component: () => (<RequireRole any={["super_admin","admin","company_admin","ops_manager"]}><ReportsPage /></RequireRole>),
});

function toCSV(rows: Record<string, unknown>[]) {
  if (!rows.length) return "";
  const headers = Object.keys(rows[0]);
  const escape = (v: unknown) => {
    const s = v == null ? "" : String(v);
    return /[",\n]/.test(s) ? `"${s.replace(/"/g, '""')}"` : s;
  };
  return [headers.join(","), ...rows.map((r) => headers.map((h) => escape(r[h])).join(","))].join("\n");
}

function download(name: string, csv: string) {
  const blob = new Blob([csv], { type: "text/csv;charset=utf-8" });
  const url = URL.createObjectURL(blob);
  const a = document.createElement("a");
  a.href = url;
  a.download = name;
  a.click();
  URL.revokeObjectURL(url);
}

function startOfMonth() {
  const d = new Date();
  return new Date(d.getFullYear(), d.getMonth(), 1).toISOString().slice(0, 10);
}
function today() {
  return new Date().toISOString().slice(0, 10);
}

function ReportsPage() {
  const qc = useQueryClient();
  const [from, setFrom] = useState(startOfMonth());
  const [to, setTo] = useState(today());
  const [expand, setExpand] = useState<Record<string, boolean>>({});
  const toggle = (k: string) => setExpand((s) => ({ ...s, [k]: !s[k] }));

  const setPreset = (kind: "today" | "7d" | "30d" | "month") => {
    const now = new Date();
    const t = now.toISOString().slice(0, 10);
    if (kind === "today") { setFrom(t); setTo(t); return; }
    if (kind === "month") { setFrom(startOfMonth()); setTo(t); return; }
    const days = kind === "7d" ? 6 : 29;
    const start = new Date(now.getTime() - days * 86400000).toISOString().slice(0, 10);
    setFrom(start); setTo(t);
  };

  const fromIso = useMemo(() => new Date(from + "T00:00:00").toISOString(), [from]);
  const toIso = useMemo(() => new Date(to + "T23:59:59").toISOString(), [to]);

  useEffect(() => {
    const ch = supabase
      .channel("reports_rt")
      .on("postgres_changes", { event: "*", schema: "public", table: "attendance" }, () => qc.invalidateQueries({ queryKey: ["report", "attendance"] }))
      .on("postgres_changes", { event: "*", schema: "public", table: "leave_requests" }, () => qc.invalidateQueries({ queryKey: ["report", "leaves"] }))
      .on("postgres_changes", { event: "*", schema: "public", table: "supervisor_visits" }, () => qc.invalidateQueries({ queryKey: ["report", "visits"] }))
      .subscribe();
    return () => { supabase.removeChannel(ch); };
  }, [qc]);

  const attendanceQ = useQuery({
    queryKey: ["report", "attendance", from, to],
    queryFn: async () => {
      const { data, error } = await supabase
        .from("attendance")
        .select("id, check_in_at, check_out_at, status, method, shift, guard:security_guards(full_name, employee_id), post:duty_posts(name)")
        .gte("check_in_at", fromIso)
        .lte("check_in_at", toIso)
        .order("check_in_at", { ascending: false });
      if (error) throw error;
      return data ?? [];
    },
  });

  const leavesQ = useQuery({
    queryKey: ["report", "leaves", from, to],
    queryFn: async () => {
      const { data, error } = await supabase
        .from("leave_requests")
        .select("id, leave_type, status, start_date, end_date, reason, guard:security_guards(full_name, employee_id)")
        .gte("start_date", from)
        .lte("start_date", to)
        .order("start_date", { ascending: false });
      if (error) throw error;
      return data ?? [];
    },
  });

  const visitsQ = useQuery({
    queryKey: ["report", "visits", from, to],
    queryFn: async () => {
      const { data, error } = await supabase
        .from("supervisor_visits")
        .select("id, status, rating, notes, created_at, post:duty_posts(name)")
        .gte("created_at", fromIso)
        .lte("created_at", toIso)
        .order("created_at", { ascending: false });
      if (error) throw error;
      return data ?? [];
    },
  });

  const att = attendanceQ.data ?? [];
  const leaves = leavesQ.data ?? [];
  const visits = visitsQ.data ?? [];

  const stats = useMemo(() => {
    const checkedIn = att.filter((a) => a.status === "checked_in").length;
    const checkedOut = att.filter((a) => a.status === "checked_out").length;
    const flagged = att.filter((a) => a.status === "flagged").length;
    const approved = leaves.filter((l) => l.status === "approved").length;
    const pending = leaves.filter((l) => l.status === "pending").length;
    const critical = visits.filter((v) => v.status === "critical").length;
    const issue = visits.filter((v) => v.status === "issue").length;
    const ok = visits.filter((v) => v.status === "ok").length;
    return { checkedIn, checkedOut, flagged, approved, pending, critical, issue, ok };
  }, [att, leaves, visits]);

  const exportAttendance = () =>
    download(
      `attendance_${from}_${to}.csv`,
      toCSV(
        att.map((a: any) => ({
          employee_id: a.guard?.employee_id ?? "",
          name: a.guard?.full_name ?? "",
          post: a.post?.name ?? "",
          shift: a.shift ?? "",
          method: a.method,
          status: a.status,
          check_in_at: a.check_in_at,
          check_out_at: a.check_out_at ?? "",
        })),
      ),
    );

  const exportLeaves = () =>
    download(
      `leaves_${from}_${to}.csv`,
      toCSV(
        leaves.map((l: any) => ({
          employee_id: l.guard?.employee_id ?? "",
          name: l.guard?.full_name ?? "",
          leave_type: l.leave_type,
          status: l.status,
          start_date: l.start_date,
          end_date: l.end_date,
          reason: l.reason ?? "",
        })),
      ),
    );

  const exportVisits = () =>
    download(
      `supervisor_visits_${from}_${to}.csv`,
      toCSV(
        visits.map((v: any) => ({
          post: v.post?.name ?? "",
          status: v.status,
          rating: v.rating ?? "",
          notes: v.notes ?? "",
          created_at: v.created_at,
        })),
      ),
    );

  return (
    <div className="space-y-6">
      <div className="relative overflow-hidden rounded-2xl bg-gradient-primary p-6 sm:p-8 text-primary-foreground shadow-elegant">
        <div className="absolute inset-0 bg-grid opacity-20" />
        <div className="relative flex flex-col sm:flex-row sm:items-end sm:justify-between gap-4">
          <div>
            <div className="flex items-center gap-2 text-sm opacity-90">
              <BarChart3 className="h-4 w-4" /> Reports & Analytics
            </div>
            <h1 className="text-2xl sm:text-3xl font-bold mt-1">Operations Report</h1>
            <p className="text-sm opacity-90 mt-1">Date range summary across attendance, leaves and supervisor visits.</p>
          </div>
          <div className="flex flex-wrap items-end gap-3 bg-background/10 backdrop-blur rounded-xl p-3">
            <div>
              <Label className="text-primary-foreground/90 text-xs">From</Label>
              <Input type="date" value={from} onChange={(e) => setFrom(e.target.value)} className="bg-background text-foreground h-9" />
            </div>
            <div>
              <Label className="text-primary-foreground/90 text-xs">To</Label>
              <Input type="date" value={to} onChange={(e) => setTo(e.target.value)} className="bg-background text-foreground h-9" />
            </div>
          </div>
        </div>
        <div className="relative mt-4 flex flex-wrap items-center gap-2">
          {(["today","7d","30d","month"] as const).map((k) => (
            <Button key={k} size="sm" variant="secondary" className="h-8" onClick={() => setPreset(k)}>
              {k === "today" ? "Today" : k === "7d" ? "Last 7d" : k === "30d" ? "Last 30d" : "This month"}
            </Button>
          ))}
          <Button size="sm" variant="secondary" className="h-8" onClick={() => qc.invalidateQueries({ queryKey: ["report"] })}>
            <RefreshCw className="h-3.5 w-3.5 mr-1" /> Refresh
          </Button>
          <Button
            size="sm"
            variant="secondary"
            className="h-8"
            disabled={!att.length && !leaves.length && !visits.length}
            onClick={() => {
              exportAttendance();
              exportLeaves();
              exportVisits();
            }}
          >
            <Download className="h-3.5 w-3.5 mr-1" /> Export all
          </Button>
        </div>
      </div>

      <div className="grid grid-cols-2 sm:grid-cols-4 gap-3">
        <StatTile label="Checked In" value={stats.checkedIn} tone="emerald" />
        <StatTile label="Checked Out" value={stats.checkedOut} tone="sky" />
        <StatTile label="Flagged" value={stats.flagged} tone="rose" />
        <StatTile label="Approved Leaves" value={stats.approved} tone="emerald" />
        <StatTile label="Pending Leaves" value={stats.pending} tone="amber" />
        <StatTile label="Visits OK" value={stats.ok} tone="emerald" />
        <StatTile label="Visit Issues" value={stats.issue} tone="amber" />
        <StatTile label="Critical" value={stats.critical} tone="rose" />
      </div>

      <ReportCard
        title="Attendance"
        description={`${att.length} records between ${from} and ${to}`}
        onExport={exportAttendance}
        disabled={!att.length}
      >
        <Table>
          <TableHeader>
            <TableRow>
              <TableHead>Guard</TableHead>
              <TableHead>Post</TableHead>
              <TableHead>Status</TableHead>
              <TableHead>Check-in</TableHead>
              <TableHead>Check-out</TableHead>
            </TableRow>
          </TableHeader>
          <TableBody>
            {(expand.att ? att : att.slice(0, 10)).map((a: any) => (
              <TableRow key={a.id}>
                <TableCell>{a.guard?.full_name ?? "—"}</TableCell>
                <TableCell>{a.post?.name ?? "—"}</TableCell>
                <TableCell className="capitalize">{a.status.replace("_", " ")}</TableCell>
                <TableCell>{new Date(a.check_in_at).toLocaleString()}</TableCell>
                <TableCell>{a.check_out_at ? new Date(a.check_out_at).toLocaleString() : "—"}</TableCell>
              </TableRow>
            ))}
            {!att.length && (
              <TableRow><TableCell colSpan={5} className="text-center text-muted-foreground py-6">No records</TableCell></TableRow>
            )}
          </TableBody>
        </Table>
        {att.length > 10 && (
          <div className="pt-2 text-center">
            <Button variant="ghost" size="sm" onClick={() => toggle("att")}>
              {expand.att ? "Show less" : `Show all ${att.length}`}
            </Button>
          </div>
        )}
      </ReportCard>

      <ReportCard
        title="Leave Requests"
        description={`${leaves.length} requests in range`}
        onExport={exportLeaves}
        disabled={!leaves.length}
      >
        <Table>
          <TableHeader>
            <TableRow>
              <TableHead>Guard</TableHead>
              <TableHead>Type</TableHead>
              <TableHead>Status</TableHead>
              <TableHead>Start</TableHead>
              <TableHead>End</TableHead>
            </TableRow>
          </TableHeader>
          <TableBody>
            {(expand.leaves ? leaves : leaves.slice(0, 10)).map((l: any) => (
              <TableRow key={l.id}>
                <TableCell>{l.guard?.full_name ?? "—"}</TableCell>
                <TableCell className="capitalize">{l.leave_type}</TableCell>
                <TableCell className="capitalize">{l.status}</TableCell>
                <TableCell>{l.start_date}</TableCell>
                <TableCell>{l.end_date}</TableCell>
              </TableRow>
            ))}
            {!leaves.length && (
              <TableRow><TableCell colSpan={5} className="text-center text-muted-foreground py-6">No records</TableCell></TableRow>
            )}
          </TableBody>
        </Table>
        {leaves.length > 10 && (
          <div className="pt-2 text-center">
            <Button variant="ghost" size="sm" onClick={() => toggle("leaves")}>
              {expand.leaves ? "Show less" : `Show all ${leaves.length}`}
            </Button>
          </div>
        )}
      </ReportCard>

      <ReportCard
        title="Supervisor Visits"
        description={`${visits.length} inspections in range`}
        onExport={exportVisits}
        disabled={!visits.length}
      >
        <Table>
          <TableHeader>
            <TableRow>
              <TableHead>Post</TableHead>
              <TableHead>Status</TableHead>
              <TableHead>Rating</TableHead>
              <TableHead>Logged</TableHead>
            </TableRow>
          </TableHeader>
          <TableBody>
            {(expand.visits ? visits : visits.slice(0, 10)).map((v: any) => (
              <TableRow key={v.id}>
                <TableCell>{v.post?.name ?? "—"}</TableCell>
                <TableCell className="capitalize">{v.status}</TableCell>
                <TableCell>{v.rating ?? "—"}</TableCell>
                <TableCell>{new Date(v.created_at).toLocaleString()}</TableCell>
              </TableRow>
            ))}
            {!visits.length && (
              <TableRow><TableCell colSpan={4} className="text-center text-muted-foreground py-6">No records</TableCell></TableRow>
            )}
          </TableBody>
        </Table>
        {visits.length > 10 && (
          <div className="pt-2 text-center">
            <Button variant="ghost" size="sm" onClick={() => toggle("visits")}>
              {expand.visits ? "Show less" : `Show all ${visits.length}`}
            </Button>
          </div>
        )}
      </ReportCard>
    </div>
  );
}

function StatTile({ label, value, tone }: { label: string; value: number; tone: "emerald" | "sky" | "rose" | "amber" }) {
  const toneMap = {
    emerald: "from-emerald-500/15 to-emerald-500/5 text-emerald-600 dark:text-emerald-400",
    sky: "from-sky-500/15 to-sky-500/5 text-sky-600 dark:text-sky-400",
    rose: "from-rose-500/15 to-rose-500/5 text-rose-600 dark:text-rose-400",
    amber: "from-amber-500/15 to-amber-500/5 text-amber-600 dark:text-amber-400",
  } as const;
  return (
    <div className={`rounded-xl border bg-gradient-to-br p-4 ${toneMap[tone]}`}>
      <div className="text-xs uppercase tracking-wide opacity-80">{label}</div>
      <div className="text-2xl font-bold mt-1 text-foreground">{value}</div>
    </div>
  );
}

function ReportCard({
  title,
  description,
  onExport,
  disabled,
  children,
}: {
  title: string;
  description: string;
  onExport: () => void;
  disabled?: boolean;
  children: React.ReactNode;
}) {
  return (
    <Card>
      <CardHeader className="flex flex-row items-start justify-between gap-3 space-y-0">
        <div>
          <CardTitle className="flex items-center gap-2"><FileText className="h-4 w-4" /> {title}</CardTitle>
          <CardDescription>{description}</CardDescription>
        </div>
        <Button variant="outline" size="sm" onClick={onExport} disabled={disabled}>
          <Download className="h-4 w-4 mr-1" /> Export CSV
        </Button>
      </CardHeader>
      <CardContent className="overflow-x-auto">{children}</CardContent>
    </Card>
  );
}