import { ReactNode, useState } from "react";
import { Head } from "@inertiajs/react";
import { useQuery, useMutation, useQueryClient } from "@tanstack/react-query";
import AdminLayout from "@/layouts/AdminLayout";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";
import {
  Dialog, DialogContent, DialogHeader, DialogTitle, DialogFooter,
} from "@/components/ui/dialog";
import {
  AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent,
  AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogTitle,
} from "@/components/ui/alert-dialog";
import {
  Table, TableBody, TableCell, TableHead, TableHeader, TableRow,
} from "@/components/ui/table";
import { Plus, Pencil, Trash2, CalendarDays } from "lucide-react";
import { format, parseISO, isBefore, startOfDay } from "date-fns";
import { toast } from "sonner";

const csrfToken = () =>
  (document.querySelector('meta[name="csrf-token"]') as HTMLMetaElement | null)?.content ?? "";

interface BankHolidayRow {
  id: string;
  date: string;
  name: string;
}

const emptyForm = (): Partial<BankHolidayRow> => ({ date: "", name: "" });

const BankHolidaysPage = () => {
  const qc = useQueryClient();
  const [dialogOpen, setDialogOpen] = useState(false);
  const [editing, setEditing] = useState<BankHolidayRow | null>(null);
  const [form, setForm] = useState<Partial<BankHolidayRow>>(emptyForm());
  const [deleteRow, setDeleteRow] = useState<BankHolidayRow | null>(null);

  const { data: holidays = [], isLoading } = useQuery({
    queryKey: ["admin-bank-holidays"],
    queryFn: async (): Promise<BankHolidayRow[]> => {
      const res = await fetch("/api/admin/bank-holidays");
      if (!res.ok) return [];
      return res.json();
    },
  });

  const invalidate = () => {
    qc.invalidateQueries({ queryKey: ["admin-bank-holidays"] });
    qc.invalidateQueries({ queryKey: ["bank-holidays"] }); // public read used by availability/calendar
  };

  const saveMutation = useMutation({
    mutationFn: async (payload: Partial<BankHolidayRow>) => {
      const url = editing ? `/api/admin/bank-holidays/${editing.id}` : `/api/admin/bank-holidays`;
      const res = await fetch(url, {
        method: editing ? "PATCH" : "POST",
        headers: { "Content-Type": "application/json", "X-CSRF-TOKEN": csrfToken() },
        body: JSON.stringify(payload),
      });
      if (!res.ok) {
        const err = await res.json().catch(() => ({}));
        throw new Error(err.error || err.message || "Failed to save bank holiday");
      }
      return res.json();
    },
    onSuccess: () => {
      toast.success(editing ? "Bank holiday updated" : "Bank holiday added");
      invalidate();
      setDialogOpen(false);
      setEditing(null);
    },
    onError: (e: Error) => toast.error(e.message),
  });

  const deleteMutation = useMutation({
    mutationFn: async (id: string) => {
      const res = await fetch(`/api/admin/bank-holidays/${id}`, {
        method: "DELETE",
        headers: { "X-CSRF-TOKEN": csrfToken() },
      });
      if (!res.ok) throw new Error("Failed to delete bank holiday");
      return res.json();
    },
    onSuccess: () => {
      toast.success("Bank holiday deleted");
      invalidate();
      setDeleteRow(null);
    },
    onError: (e: Error) => toast.error(e.message),
  });

  const openCreate = () => {
    setEditing(null);
    setForm(emptyForm());
    setDialogOpen(true);
  };

  const openEdit = (row: BankHolidayRow) => {
    setEditing(row);
    setForm({ ...row });
    setDialogOpen(true);
  };

  const onSubmit = () => {
    if (!form.date) {
      toast.error("Please pick a date");
      return;
    }
    if (!form.name?.trim()) {
      toast.error("Name is required");
      return;
    }
    saveMutation.mutate({ date: form.date, name: form.name.trim() });
  };

  const today = startOfDay(new Date());
  const rows = holidays
    .slice()
    .sort((a, b) => a.date.localeCompare(b.date));

  return (
    <>
      <Head title="Bank Holidays" />
      <div>
        <div className="flex items-center justify-between mb-6">
          <div>
            <h1 className="text-2xl font-bold text-foreground flex items-center gap-2">
              <CalendarDays className="w-5 h-5 text-primary" /> Bank Holidays
            </h1>
            <p className="text-sm text-muted-foreground mt-1">
              Non-working days applied across trainer availability, the training calendar, and public course booking. Manage the list here — nothing is hard-coded.
            </p>
          </div>
          <Button onClick={openCreate}>
            <Plus className="w-4 h-4 mr-1.5" /> Add Bank Holiday
          </Button>
        </div>

        <div className="bg-card border border-border rounded-xl overflow-hidden">
          <Table>
            <TableHeader>
              <TableRow>
                <TableHead className="w-[200px]">Date</TableHead>
                <TableHead>Name</TableHead>
                <TableHead className="text-right">Actions</TableHead>
              </TableRow>
            </TableHeader>
            <TableBody>
              {isLoading ? (
                <TableRow>
                  <TableCell colSpan={3} className="text-center text-muted-foreground py-12">Loading…</TableCell>
                </TableRow>
              ) : rows.length === 0 ? (
                <TableRow>
                  <TableCell colSpan={3} className="text-center text-muted-foreground py-12">
                    No bank holidays yet. Add one to get started.
                  </TableCell>
                </TableRow>
              ) : (
                rows.map((row) => {
                  const past = isBefore(parseISO(row.date), today);
                  return (
                    <TableRow key={row.id} className={past ? "opacity-50" : ""}>
                      <TableCell className="font-medium">
                        {format(parseISO(row.date), "EEE d MMM yyyy")}
                        {past && <span className="ml-2 text-[10px] text-muted-foreground">(past)</span>}
                      </TableCell>
                      <TableCell>{row.name}</TableCell>
                      <TableCell className="text-right">
                        <div className="flex items-center gap-1 justify-end">
                          <Button variant="ghost" size="sm" className="h-7" onClick={() => openEdit(row)}>
                            <Pencil className="w-3.5 h-3.5" />
                          </Button>
                          <Button
                            variant="ghost"
                            size="sm"
                            className="h-7 text-destructive hover:text-destructive"
                            onClick={() => setDeleteRow(row)}
                          >
                            <Trash2 className="w-3.5 h-3.5" />
                          </Button>
                        </div>
                      </TableCell>
                    </TableRow>
                  );
                })
              )}
            </TableBody>
          </Table>
        </div>
      </div>

      {/* Create / Edit dialog */}
      <Dialog open={dialogOpen} onOpenChange={setDialogOpen}>
        <DialogContent className="sm:max-w-md">
          <DialogHeader>
            <DialogTitle>{editing ? "Edit Bank Holiday" : "Add Bank Holiday"}</DialogTitle>
          </DialogHeader>
          <div className="space-y-4">
            <div>
              <Label>Date *</Label>
              <Input
                type="date"
                value={form.date || ""}
                onChange={(e) => setForm((f) => ({ ...f, date: e.target.value }))}
              />
            </div>
            <div>
              <Label>Name *</Label>
              <Input
                value={form.name || ""}
                onChange={(e) => setForm((f) => ({ ...f, name: e.target.value }))}
                placeholder="e.g. Christmas Day"
              />
            </div>
          </div>
          <DialogFooter>
            <Button variant="outline" onClick={() => setDialogOpen(false)}>Cancel</Button>
            <Button onClick={onSubmit} disabled={saveMutation.isPending}>
              {saveMutation.isPending ? "Saving…" : editing ? "Save Changes" : "Add"}
            </Button>
          </DialogFooter>
        </DialogContent>
      </Dialog>

      {/* Delete confirm */}
      <AlertDialog open={!!deleteRow} onOpenChange={(open) => !open && setDeleteRow(null)}>
        <AlertDialogContent>
          <AlertDialogHeader>
            <AlertDialogTitle>Delete bank holiday?</AlertDialogTitle>
            <AlertDialogDescription>
              {deleteRow && `"${deleteRow.name}" (${format(parseISO(deleteRow.date), "d MMM yyyy")}) will be removed. Dates will become bookable again.`}
            </AlertDialogDescription>
          </AlertDialogHeader>
          <AlertDialogFooter>
            <AlertDialogCancel>Cancel</AlertDialogCancel>
            <AlertDialogAction
              className="bg-destructive text-destructive-foreground hover:bg-destructive/90"
              disabled={deleteMutation.isPending}
              onClick={() => deleteRow && deleteMutation.mutate(deleteRow.id)}
            >
              {deleteMutation.isPending ? "Deleting…" : "Delete"}
            </AlertDialogAction>
          </AlertDialogFooter>
        </AlertDialogContent>
      </AlertDialog>
    </>
  );
};

BankHolidaysPage.layout = (page: ReactNode) => <AdminLayout>{page}</AdminLayout>;

export default BankHolidaysPage;
