import { createFileRoute } from "@tanstack/react-router";
import { useMemo, useState } from "react";
import { useMutation, 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 { Textarea } from "@/components/ui/textarea";
import { Badge } from "@/components/ui/badge";
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select";
import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "@/components/ui/table";
import { Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle, DialogTrigger } from "@/components/ui/dialog";
import { Ban, CalendarDays, Check, Plus, Search, Trash2, X } from "lucide-react";
import { toast } from "sonner";

export const Route = createFileRoute("/_authenticated/leaves")({
  component: LeavesPage,
});

type LeaveType = "casual" | "sick" | "annual" | "unpaid" | "other";
type LeaveStatus = "pending" | "approved" | "rejected" | "cancelled";

function daysBetween(a: string, b: string) {
  if (!a || !b) return 0;
  const ms = new Date(b).getTime() - new Date(a).getTime();
  return Math.max(1, Math.round(ms / 86400000) + 1);
}

function StatusPill({ status }: { status: LeaveStatus }) {
  const map: Record<LeaveStatus, string> = {
    pending: "bg-amber-500/10 text-amber-600 dark:text-amber-400",
    approved: "bg-emerald-500/10 text-emerald-600 dark:text-emerald-400",
    rejected: "bg-destructive/10 text-destructive",
    cancelled: "bg-muted text-muted-foreground",
  };
  return (
    <span className={`inline-flex items-center gap-1 rounded-full px-2 py-0.5 text-xs font-medium capitalize ${map[status]}`}>
      <span className="h-1.5 w-1.5 rounded-full bg-current" /> {status}
    </span>
  );
}

function LeavesPage() {
  const qc = useQueryClient();
  const [open, setOpen] = useState(false);
  const [guardId, setGuardId] = useState("");
  const [leaveType, setLeaveType] = useState<LeaveType>("casual");
  const [start, setStart] = useState("");
  const [end, setEnd] = useState("");
  const [reason, setReason] = useState("");
  const [search, setSearch] = useState("");
  const [statusFilter, setStatusFilter] = useState<string>("all");

  const guardsQ = useQuery({
    queryKey: ["guards", "min"],
    queryFn: async () => {
      const { data, error } = await supabase
        .from("security_guards")
        .select("id, full_name, employee_id")
        .order("full_name");
      if (error) throw error;
      return data;
    },
  });

  const leavesQ = useQuery({
    queryKey: ["leave_requests"],
    queryFn: async () => {
      const { data, error } = await supabase
        .from("leave_requests")
        .select("*, security_guards(full_name, employee_id)")
        .order("created_at", { ascending: false });
      if (error) throw error;
      return data;
    },
  });

  const createLeave = useMutation({
    mutationFn: async () => {
      if (!guardId) throw new Error("Select a guard");
      if (!start || !end) throw new Error("Pick start and end dates");
      if (end < start) throw new Error("End date must be after start date");
      const { data: u } = await supabase.auth.getUser();
      const { error } = await supabase.from("leave_requests").insert({
        guard_id: guardId,
        leave_type: leaveType,
        start_date: start,
        end_date: end,
        days: daysBetween(start, end),
        reason: reason || null,
        created_by: u.user?.id ?? null,
      });
      if (error) throw error;
    },
    onSuccess: () => {
      toast.success("Leave request submitted");
      setOpen(false);
      setGuardId(""); setLeaveType("casual"); setStart(""); setEnd(""); setReason("");
      qc.invalidateQueries({ queryKey: ["leave_requests"] });
    },
    onError: (e: Error) => toast.error(e.message),
  });

  const setStatus = useMutation({
    mutationFn: async ({ id, status, note }: { id: string; status: LeaveStatus; note?: string | null }) => {
      const { data: u } = await supabase.auth.getUser();
      const { error } = await supabase
        .from("leave_requests")
        .update({
          status,
          reviewer_id: u.user?.id ?? null,
          reviewer_note: note ?? null,
          reviewed_at: new Date().toISOString(),
        })
        .eq("id", id);
      if (error) throw error;
    },
    onSuccess: (_d, v) => {
      toast.success(`Request ${v.status}`);
      qc.invalidateQueries({ queryKey: ["leave_requests"] });
    },
    onError: (e: Error) => toast.error(e.message),
  });

  const review = (id: string, status: LeaveStatus) => {
    const note = window.prompt(`Optional note for ${status} request:`, "") ?? "";
    setStatus.mutate({ id, status, note: note.trim() || null });
  };

  const removeLeave = useMutation({
    mutationFn: async (id: string) => {
      const { error } = await supabase.from("leave_requests").delete().eq("id", id);
      if (error) throw error;
    },
    onSuccess: () => {
      toast.success("Deleted");
      qc.invalidateQueries({ queryKey: ["leave_requests"] });
    },
    onError: (e: Error) => toast.error(e.message),
  });

  const rows = leavesQ.data ?? [];
  const filtered = useMemo(() => {
    const q = search.trim().toLowerCase();
    return rows.filter((r: { status: string; security_guards: { full_name: string; employee_id: string } | null }) => {
      if (statusFilter !== "all" && r.status !== statusFilter) return false;
      if (!q) return true;
      const hay = `${r.security_guards?.full_name ?? ""} ${r.security_guards?.employee_id ?? ""}`.toLowerCase();
      return hay.includes(q);
    });
  }, [rows, search, statusFilter]);

  const stats = useMemo(() => {
    const r = rows as Array<{ status: LeaveStatus }>;
    return {
      pending: r.filter((x) => x.status === "pending").length,
      approved: r.filter((x) => x.status === "approved").length,
      rejected: r.filter((x) => x.status === "rejected").length,
      total: r.length,
    };
  }, [rows]);

  const tiles = [
    { label: "Total requests", value: stats.total },
    { label: "Pending", value: stats.pending },
    { label: "Approved", value: stats.approved },
    { label: "Rejected", value: stats.rejected },
  ];

  return (
    <div className="space-y-6">
      <section className="relative overflow-hidden rounded-3xl border bg-gradient-primary text-primary-foreground shadow-elegant">
        <div className="absolute inset-0 bg-grid opacity-30" aria-hidden />
        <div className="absolute -top-16 -right-16 h-64 w-64 rounded-full bg-white/10 blur-3xl" aria-hidden />
        <div className="relative p-6 sm:p-8 flex flex-wrap items-end justify-between gap-4">
          <div className="min-w-0">
            <div className="flex items-center gap-2 text-xs uppercase tracking-[0.18em] text-primary-foreground/80">
              <CalendarDays className="h-3.5 w-3.5" /> Leave management
            </div>
            <h1 className="mt-2 text-3xl sm:text-4xl font-extrabold tracking-tight">Leaves</h1>
            <p className="mt-1 text-sm text-primary-foreground/85">Submit, review and approve guard leave requests</p>
          </div>
          <Dialog open={open} onOpenChange={setOpen}>
            <DialogTrigger asChild>
              <Button variant="secondary" className="rounded-full">
                <Plus className="h-4 w-4 mr-1" /> New request
              </Button>
            </DialogTrigger>
            <DialogContent>
              <DialogHeader>
                <DialogTitle>New leave request</DialogTitle>
                <DialogDescription>Submit a leave request for a guard.</DialogDescription>
              </DialogHeader>
              <div className="grid gap-4">
                <div className="grid gap-2">
                  <Label>Guard</Label>
                  <Select value={guardId} onValueChange={setGuardId}>
                    <SelectTrigger><SelectValue placeholder="Select guard" /></SelectTrigger>
                    <SelectContent>
                      {guardsQ.data?.map((g) => (
                        <SelectItem key={g.id} value={g.id}>{g.full_name} ({g.employee_id})</SelectItem>
                      ))}
                    </SelectContent>
                  </Select>
                </div>
                <div className="grid gap-2">
                  <Label>Leave type</Label>
                  <Select value={leaveType} onValueChange={(v) => setLeaveType(v as LeaveType)}>
                    <SelectTrigger><SelectValue /></SelectTrigger>
                    <SelectContent>
                      <SelectItem value="casual">Casual</SelectItem>
                      <SelectItem value="sick">Sick</SelectItem>
                      <SelectItem value="annual">Annual</SelectItem>
                      <SelectItem value="unpaid">Unpaid</SelectItem>
                      <SelectItem value="other">Other</SelectItem>
                    </SelectContent>
                  </Select>
                </div>
                <div className="grid grid-cols-2 gap-3">
                  <div className="grid gap-2">
                    <Label>Start date</Label>
                    <Input type="date" value={start} onChange={(e) => setStart(e.target.value)} />
                  </div>
                  <div className="grid gap-2">
                    <Label>End date</Label>
                    <Input type="date" value={end} onChange={(e) => setEnd(e.target.value)} />
                  </div>
                </div>
                {start && end && (
                  <p className="text-xs text-muted-foreground">Total: <span className="font-semibold">{daysBetween(start, end)}</span> day(s)</p>
                )}
                <div className="grid gap-2">
                  <Label>Reason</Label>
                  <Textarea value={reason} onChange={(e) => setReason(e.target.value)} placeholder="Optional reason" rows={3} />
                </div>
              </div>
              <DialogFooter>
                <Button variant="outline" onClick={() => setOpen(false)}>Cancel</Button>
                <Button onClick={() => createLeave.mutate()} disabled={createLeave.isPending}>
                  {createLeave.isPending ? "Submitting…" : "Submit"}
                </Button>
              </DialogFooter>
            </DialogContent>
          </Dialog>
        </div>
      </section>

      <div className="grid gap-4 grid-cols-2 lg:grid-cols-4">
        {tiles.map((t) => (
          <Card key={t.label} className="shadow-elegant border-border/60 rounded-2xl">
            <CardContent className="p-5">
              <div className="text-xs text-muted-foreground">{t.label}</div>
              <div className="text-3xl font-bold tabular-nums mt-1">{t.value}</div>
            </CardContent>
          </Card>
        ))}
      </div>

      <Card className="shadow-elegant border-border/60 rounded-2xl overflow-hidden">
        <CardHeader>
          <CardTitle>Leave requests</CardTitle>
          <CardDescription>All submitted requests</CardDescription>
        </CardHeader>
        <CardContent className="pb-2 flex flex-col sm:flex-row gap-3 border-b">
          <div className="relative flex-1">
            <Search className="absolute left-3 top-1/2 -translate-y-1/2 h-4 w-4 text-muted-foreground" />
            <Input
              value={search}
              onChange={(e) => setSearch(e.target.value)}
              placeholder="Search guard or employee ID"
              className="pl-9"
            />
          </div>
          <Select value={statusFilter} onValueChange={setStatusFilter}>
            <SelectTrigger className="w-full sm:w-48"><SelectValue /></SelectTrigger>
            <SelectContent>
              <SelectItem value="all">All statuses</SelectItem>
              <SelectItem value="pending">Pending</SelectItem>
              <SelectItem value="approved">Approved</SelectItem>
              <SelectItem value="rejected">Rejected</SelectItem>
              <SelectItem value="cancelled">Cancelled</SelectItem>
            </SelectContent>
          </Select>
        </CardContent>
        <CardContent className="p-0">
          <div className="w-full overflow-x-auto"><Table>
            <TableHeader className="bg-muted/40">
              <TableRow className="hover:bg-transparent">
                <TableHead>Guard</TableHead>
                <TableHead>Type</TableHead>
                <TableHead>From</TableHead>
                <TableHead>To</TableHead>
                <TableHead>Days</TableHead>
                <TableHead>Reason</TableHead>
                <TableHead>Status</TableHead>
                <TableHead className="text-right">Actions</TableHead>
              </TableRow>
            </TableHeader>
            <TableBody>
              {leavesQ.isLoading && (
                <TableRow><TableCell colSpan={8} className="text-center text-muted-foreground py-8">Loading…</TableCell></TableRow>
              )}
              {!leavesQ.isLoading && filtered.length === 0 && (
                <TableRow><TableCell colSpan={8} className="text-center text-muted-foreground py-8">No leave requests.</TableCell></TableRow>
              )}
              {filtered.map((r: {
                id: string; leave_type: LeaveType; start_date: string; end_date: string; days: number;
                reason: string | null; status: LeaveStatus;
                reviewer_note: string | null;
                security_guards: { full_name: string; employee_id: string } | null;
              }) => (
                <TableRow key={r.id} className="hover:bg-muted/30">
                  <TableCell>
                    <div className="font-medium">{r.security_guards?.full_name ?? "—"}</div>
                    <div className="text-xs text-muted-foreground">{r.security_guards?.employee_id}</div>
                  </TableCell>
                  <TableCell><Badge variant="outline" className="capitalize">{r.leave_type}</Badge></TableCell>
                  <TableCell className="tabular-nums text-xs">{r.start_date}</TableCell>
                  <TableCell className="tabular-nums text-xs">{r.end_date}</TableCell>
                  <TableCell className="tabular-nums">{r.days}</TableCell>
                  <TableCell className="max-w-[260px] truncate text-xs text-muted-foreground">{r.reason ?? "—"}</TableCell>
                  <TableCell>
                    <StatusPill status={r.status} />
                    {r.reviewer_note && (
                      <div className="text-[10px] text-muted-foreground mt-1 truncate max-w-[160px]" title={r.reviewer_note}>
                        Note: {r.reviewer_note}
                      </div>
                    )}
                  </TableCell>
                  <TableCell className="text-right">
                    <div className="flex justify-end gap-1">
                      {r.status === "pending" && (
                        <>
                          <Button size="sm" variant="ghost" title="Approve" onClick={() => review(r.id, "approved")}>
                            <Check className="h-4 w-4 text-emerald-600" />
                          </Button>
                          <Button size="sm" variant="ghost" title="Reject" onClick={() => review(r.id, "rejected")}>
                            <X className="h-4 w-4 text-destructive" />
                          </Button>
                          <Button size="sm" variant="ghost" title="Cancel" onClick={() => setStatus.mutate({ id: r.id, status: "cancelled" })}>
                            <Ban className="h-4 w-4 text-muted-foreground" />
                          </Button>
                        </>
                      )}
                      <Button size="sm" variant="ghost" title="Delete" onClick={() => { if (confirm("Delete this request?")) removeLeave.mutate(r.id); }}>
                        <Trash2 className="h-4 w-4" />
                      </Button>
                    </div>
                  </TableCell>
                </TableRow>
              ))}
            </TableBody>
          </Table></div>
        </CardContent>
      </Card>
    </div>
  );
}