import { createFileRoute } from "@tanstack/react-router";
import { useQuery, useMutation, useQueryClient } from "@tanstack/react-query";
import { useEffect, useMemo, useState } from "react";
import { supabase } from "@/integrations/supabase/client";
import { Button } from "@/components/ui/button";
import { Card, CardContent, CardHeader, CardTitle, CardDescription } from "@/components/ui/card";
import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "@/components/ui/table";
import { Badge } from "@/components/ui/badge";
import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";
import { Textarea } from "@/components/ui/textarea";
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select";
import {
  Dialog, DialogContent, DialogFooter, DialogHeader, DialogTitle, DialogTrigger,
} from "@/components/ui/dialog";
import {
  AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent,
  AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogTitle, AlertDialogTrigger,
} from "@/components/ui/alert-dialog";
import {
  Plus, Trash2, Pencil, CalendarDays, ChevronLeft, ChevronRight,
  LayoutGrid, List, Download, Sun, Sunset, Moon, Clock, Users, MapPin, Filter,
} from "lucide-react";
import { toast } from "sonner";

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

type Roster = {
  id: string;
  guard_id: string;
  shift_date: string;
  shift_start: string;
  shift_end: string;
  location: string | null;
  notes: string | null;
  status: string;
  duty_post_id: string | null;
};

type RosterForm = {
  guard_id: string;
  shift_date: string;
  shift_start: string;
  shift_end: string;
  location: string;
  notes: string;
  status: string;
  duty_post_id: string;
};

const empty: RosterForm = {
  guard_id: "",
  shift_date: new Date().toISOString().slice(0, 10),
  shift_start: "08:00",
  shift_end: "16:00",
  location: "",
  notes: "",
  status: "scheduled",
  duty_post_id: "",
};

const SHIFTS = {
  A: { label: "Shift A (Morning)", start: "06:00", end: "14:00" },
  B: { label: "Shift B (Evening)", start: "14:00", end: "22:00" },
  C: { label: "Shift C (Night)", start: "22:00", end: "06:00" },
} as const;
type ShiftKey = keyof typeof SHIFTS | "custom";

function detectShift(start: string, end: string): ShiftKey {
  const s = start.slice(0, 5), e = end.slice(0, 5);
  for (const k of ["A", "B", "C"] as const) {
    if (SHIFTS[k].start === s && SHIFTS[k].end === e) return k;
  }
  return "custom";
}

const SHIFT_TONE: Record<Exclude<ShiftKey, "custom">, { ring: string; chip: string; icon: typeof Sun }> = {
  A: { ring: "border-amber-500/40 bg-amber-500/10 text-amber-700 dark:text-amber-300", chip: "bg-amber-500/15 text-amber-700 dark:text-amber-300", icon: Sun },
  B: { ring: "border-orange-500/40 bg-orange-500/10 text-orange-700 dark:text-orange-300", chip: "bg-orange-500/15 text-orange-700 dark:text-orange-300", icon: Sunset },
  C: { ring: "border-indigo-500/40 bg-indigo-500/10 text-indigo-700 dark:text-indigo-300", chip: "bg-indigo-500/15 text-indigo-700 dark:text-indigo-300", icon: Moon },
};

const STATUS_TONE: Record<string, string> = {
  scheduled: "bg-sky-500/15 text-sky-700 dark:text-sky-300",
  completed: "bg-emerald-500/15 text-emerald-700 dark:text-emerald-300",
  cancelled: "bg-rose-500/15 text-rose-700 dark:text-rose-300",
};

const DAY_NAMES = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"];

function startOfWeek(d: Date) {
  const x = new Date(d);
  x.setHours(0, 0, 0, 0);
  x.setDate(x.getDate() - x.getDay());
  return x;
}
function addDays(d: Date, n: number) {
  const x = new Date(d);
  x.setDate(x.getDate() + n);
  return x;
}
function ymd(d: Date) {
  const y = d.getFullYear();
  const m = String(d.getMonth() + 1).padStart(2, "0");
  const day = String(d.getDate()).padStart(2, "0");
  return `${y}-${m}-${day}`;
}
function fmtDayLabel(d: Date) {
  return `${DAY_NAMES[d.getDay()]} ${d.getDate()}`;
}

type RosterRow = Roster & {
  security_guards: { full_name: string; employee_id: string } | null;
  duty_posts: { name: string; client_name: string | null } | null;
};

function downloadCSV(filename: string, rows: (string | number)[][]) {
  const esc = (v: string | number) => {
    const s = String(v ?? "");
    return /[",\n]/.test(s) ? `"${s.replace(/"/g, '""')}"` : s;
  };
  const csv = rows.map((r) => r.map(esc).join(",")).join("\n");
  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 = filename;
  a.click();
  URL.revokeObjectURL(url);
}

function RostersPage() {
  const qc = useQueryClient();
  const [open, setOpen] = useState(false);
  const [editing, setEditing] = useState<Roster | null>(null);
  const [form, setForm] = useState<RosterForm>(empty);
  const [view, setView] = useState<"week" | "list">("week");
  const [weekStart, setWeekStart] = useState<Date>(() => startOfWeek(new Date()));
  const [postFilter, setPostFilter] = useState<string>("all");
  const [statusFilter, setStatusFilter] = useState<string>("all");
  const [search, setSearch] = useState("");
  const currentShift = detectShift(form.shift_start, form.shift_end);

  const applyShift = (k: ShiftKey) => {
    if (k === "custom") return;
    setForm((f) => ({ ...f, shift_start: SHIFTS[k].start, shift_end: SHIFTS[k].end }));
  };

  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 postsQ = useQuery({
    queryKey: ["duty_posts", "min"],
    queryFn: async () => {
      const { data, error } = await supabase
        .from("duty_posts")
        .select("id, name, client_name, address")
        .eq("status", "active")
        .order("name");
      if (error) throw error;
      return data;
    },
  });

  const rostersQ = useQuery({
    queryKey: ["rosters"],
    queryFn: async () => {
      const { data, error } = await supabase
        .from("duty_rosters")
        .select("*, security_guards(full_name, employee_id), duty_posts(name, client_name)")
        .order("shift_date", { ascending: false })
        .order("shift_start", { ascending: true });
      if (error) throw error;
      return data;
    },
  });

  const save = useMutation({
    mutationFn: async () => {
      if (!form.guard_id) throw new Error("Select a guard");
      const payload = {
        guard_id: form.guard_id,
        shift_date: form.shift_date,
        shift_start: form.shift_start,
        shift_end: form.shift_end,
        location: form.location || null,
        notes: form.notes || null,
        status: form.status,
        duty_post_id: form.duty_post_id || null,
      };
      if (editing) {
        const { error } = await supabase.from("duty_rosters").update(payload).eq("id", editing.id);
        if (error) throw error;
      } else {
        const { data: u } = await supabase.auth.getUser();
        const { error } = await supabase
          .from("duty_rosters")
          .insert({ ...payload, created_by: u.user?.id });
        if (error) throw error;
      }
    },
    onSuccess: () => {
      toast.success(editing ? "Shift updated" : "Shift scheduled");
      qc.invalidateQueries({ queryKey: ["rosters"] });
      setOpen(false);
      setEditing(null);
      setForm(empty);
    },
    onError: (e: Error) => toast.error(e.message),
  });

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

  const openNew = () => {
    setEditing(null);
    setForm(empty);
    setOpen(true);
  };
  const openEdit = (r: Roster) => {
    setEditing(r);
    setForm({
      guard_id: r.guard_id,
      shift_date: r.shift_date,
      shift_start: r.shift_start.slice(0, 5),
      shift_end: r.shift_end.slice(0, 5),
      location: r.location ?? "",
      notes: r.notes ?? "",
      status: r.status,
      duty_post_id: r.duty_post_id ?? "",
    });
    setOpen(true);
  };

  useEffect(() => {
    const ch = supabase
      .channel("rosters_rt")
      .on("postgres_changes", { event: "*", schema: "public", table: "duty_rosters" }, () => {
        qc.invalidateQueries({ queryKey: ["rosters"] });
      })
      .subscribe();
    return () => { supabase.removeChannel(ch); };
  }, [qc]);

  const weekDays = useMemo(() => Array.from({ length: 7 }, (_, i) => addDays(weekStart, i)), [weekStart]);
  const weekEnd = addDays(weekStart, 6);

  const rosters = (rostersQ.data ?? []) as RosterRow[];

  const filtered = useMemo(() => {
    const q = search.trim().toLowerCase();
    return rosters.filter((r) => {
      if (postFilter !== "all" && (r.duty_post_id ?? "none") !== postFilter) return false;
      if (statusFilter !== "all" && r.status !== statusFilter) return false;
      if (!q) return true;
      const hay = `${r.security_guards?.full_name ?? ""} ${r.security_guards?.employee_id ?? ""} ${r.duty_posts?.name ?? ""} ${r.location ?? ""}`.toLowerCase();
      return hay.includes(q);
    });
  }, [rosters, postFilter, statusFilter, search]);

  const weekFiltered = useMemo(() => {
    const a = ymd(weekStart), b = ymd(weekEnd);
    return filtered.filter((r) => r.shift_date >= a && r.shift_date <= b);
  }, [filtered, weekStart, weekEnd]);

  const stats = useMemo(() => {
    const total = weekFiltered.length;
    const scheduled = weekFiltered.filter((r) => r.status === "scheduled").length;
    const completed = weekFiltered.filter((r) => r.status === "completed").length;
    const cancelled = weekFiltered.filter((r) => r.status === "cancelled").length;
    const coverage: Record<string, number> = { A: 0, B: 0, C: 0, custom: 0 };
    for (const r of weekFiltered) coverage[detectShift(r.shift_start, r.shift_end)]++;
    return { total, scheduled, completed, cancelled, coverage };
  }, [weekFiltered]);

  const byDay = useMemo(() => {
    const m = new Map<string, RosterRow[]>();
    for (const d of weekDays) m.set(ymd(d), []);
    for (const r of weekFiltered) {
      const arr = m.get(r.shift_date);
      if (arr) arr.push(r);
    }
    for (const arr of m.values()) arr.sort((a, b) => a.shift_start.localeCompare(b.shift_start));
    return m;
  }, [weekFiltered, weekDays]);

  const exportCSV = () => {
    const rows: (string | number)[][] = [["Date", "Shift", "Start", "End", "Guard", "Employee ID", "Post", "Location", "Status", "Notes"]];
    for (const r of filtered) {
      const k = detectShift(r.shift_start, r.shift_end);
      rows.push([
        r.shift_date, k,
        r.shift_start.slice(0, 5), r.shift_end.slice(0, 5),
        r.security_guards?.full_name ?? "",
        r.security_guards?.employee_id ?? "",
        r.duty_posts?.name ?? "",
        r.location ?? "",
        r.status,
        r.notes ?? "",
      ]);
    }
    downloadCSV(`duty-roster-${ymd(weekStart)}.csv`, rows);
  };

  const quickCreate = (date: string, shiftKey: Exclude<ShiftKey, "custom">) => {
    setEditing(null);
    setForm({
      ...empty,
      shift_date: date,
      shift_start: SHIFTS[shiftKey].start,
      shift_end: SHIFTS[shiftKey].end,
    });
    setOpen(true);
  };

  return (
    <div className="space-y-6">
      <div className="relative overflow-hidden rounded-2xl border bg-gradient-to-br from-primary/10 via-background to-background p-6">
        <div className="flex flex-col gap-4 md:flex-row md:items-center md:justify-between">
          <div className="space-y-1">
            <div className="inline-flex items-center gap-2 rounded-full border bg-background/70 px-3 py-1 text-xs text-muted-foreground backdrop-blur">
              <CalendarDays className="h-3.5 w-3.5" /> Digital duty roster
            </div>
            <h1 className="text-3xl font-bold tracking-tight">Duty Rosters</h1>
            <p className="text-muted-foreground">
              Week of {weekStart.toLocaleDateString(undefined, { month: "short", day: "numeric" })} –{" "}
              {weekEnd.toLocaleDateString(undefined, { month: "short", day: "numeric", year: "numeric" })}
            </p>
          </div>
          <div className="flex flex-wrap items-center gap-2">
            <div className="inline-flex rounded-md border bg-background/70 p-0.5 backdrop-blur">
              <Button size="sm" variant={view === "week" ? "default" : "ghost"} onClick={() => setView("week")} className="h-8">
                <LayoutGrid className="h-4 w-4 mr-1" /> Week
              </Button>
              <Button size="sm" variant={view === "list" ? "default" : "ghost"} onClick={() => setView("list")} className="h-8">
                <List className="h-4 w-4 mr-1" /> List
              </Button>
            </div>
            <div className="inline-flex items-center rounded-md border bg-background/70 backdrop-blur">
              <Button size="sm" variant="ghost" className="h-8" onClick={() => setWeekStart(addDays(weekStart, -7))}>
                <ChevronLeft className="h-4 w-4" />
              </Button>
              <Button size="sm" variant="ghost" className="h-8" onClick={() => setWeekStart(startOfWeek(new Date()))}>
                Today
              </Button>
              <Button size="sm" variant="ghost" className="h-8" onClick={() => setWeekStart(addDays(weekStart, 7))}>
                <ChevronRight className="h-4 w-4" />
              </Button>
            </div>
            <Button size="sm" variant="outline" onClick={exportCSV}><Download className="h-4 w-4 mr-1" /> Export</Button>
        <Dialog open={open} onOpenChange={(o) => { setOpen(o); if (!o) { setEditing(null); setForm(empty); } }}>
          <DialogTrigger asChild>
            <Button onClick={openNew}><Plus className="h-4 w-4 mr-1" /> Schedule Shift</Button>
          </DialogTrigger>
          <DialogContent>
            <DialogHeader>
              <DialogTitle>{editing ? "Edit Shift" : "Schedule Shift"}</DialogTitle>
            </DialogHeader>
            <div className="grid gap-4 py-2">
              <div className="grid gap-2">
                <Label>Guard</Label>
                <Select value={form.guard_id} onValueChange={(v) => setForm({ ...form, guard_id: v })}>
                  <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>Duty Post</Label>
                <Select
                  value={form.duty_post_id || "none"}
                  onValueChange={(v) => {
                    if (v === "none") {
                      setForm({ ...form, duty_post_id: "" });
                    } else {
                      const p = postsQ.data?.find((x) => x.id === v);
                      setForm({
                        ...form,
                        duty_post_id: v,
                        location: p ? `${p.name}${p.client_name ? ` · ${p.client_name}` : ""}` : form.location,
                      });
                    }
                  }}
                >
                  <SelectTrigger><SelectValue placeholder="Assign duty post" /></SelectTrigger>
                  <SelectContent>
                    <SelectItem value="none">— None —</SelectItem>
                    {postsQ.data?.map((p) => (
                      <SelectItem key={p.id} value={p.id}>
                        {p.name}{p.client_name ? ` · ${p.client_name}` : ""}
                      </SelectItem>
                    ))}
                  </SelectContent>
                </Select>
              </div>
              <div className="grid grid-cols-1 sm:grid-cols-3 gap-3">
                <div className="grid gap-2">
                  <Label>Date</Label>
                  <Input type="date" value={form.shift_date} onChange={(e) => setForm({ ...form, shift_date: e.target.value })} />
                </div>
                <div className="grid gap-2">
                  <Label>Start</Label>
                  <Input type="time" value={form.shift_start} onChange={(e) => setForm({ ...form, shift_start: e.target.value })} />
                </div>
                <div className="grid gap-2">
                  <Label>End</Label>
                  <Input type="time" value={form.shift_end} onChange={(e) => setForm({ ...form, shift_end: e.target.value })} />
                </div>
              </div>
              <div className="grid gap-2">
                <Label>Shift</Label>
                <Select value={currentShift} onValueChange={(v) => applyShift(v as ShiftKey)}>
                  <SelectTrigger><SelectValue /></SelectTrigger>
                  <SelectContent>
                    <SelectItem value="A">{SHIFTS.A.label} · 06:00–14:00</SelectItem>
                    <SelectItem value="B">{SHIFTS.B.label} · 14:00–22:00</SelectItem>
                    <SelectItem value="C">{SHIFTS.C.label} · 22:00–06:00</SelectItem>
                    <SelectItem value="custom">Custom</SelectItem>
                  </SelectContent>
                </Select>
              </div>
              <div className="grid gap-2">
                <Label>Location</Label>
                <Input value={form.location} onChange={(e) => setForm({ ...form, location: e.target.value })} placeholder="Site / Post" />
              </div>
              <div className="grid gap-2">
                <Label>Status</Label>
                <Select value={form.status} onValueChange={(v) => setForm({ ...form, status: v })}>
                  <SelectTrigger><SelectValue /></SelectTrigger>
                  <SelectContent>
                    <SelectItem value="scheduled">Scheduled</SelectItem>
                    <SelectItem value="completed">Completed</SelectItem>
                    <SelectItem value="cancelled">Cancelled</SelectItem>
                  </SelectContent>
                </Select>
              </div>
              <div className="grid gap-2">
                <Label>Notes</Label>
                <Textarea value={form.notes} onChange={(e) => setForm({ ...form, notes: e.target.value })} rows={2} />
              </div>
            </div>
            <DialogFooter>
              <Button variant="outline" onClick={() => setOpen(false)}>Cancel</Button>
              <Button onClick={() => save.mutate()} disabled={save.isPending}>
                {save.isPending ? "Saving…" : "Save"}
              </Button>
            </DialogFooter>
          </DialogContent>
        </Dialog>
          </div>
        </div>
      </div>

      {/* Stats */}
      <div className="grid grid-cols-2 gap-3 md:grid-cols-4">
        {([
          { label: "Total this week", value: stats.total, icon: CalendarDays, tone: "from-sky-500/15 to-sky-500/0 text-sky-600" },
          { label: "Scheduled", value: stats.scheduled, icon: Clock, tone: "from-primary/15 to-primary/0 text-primary" },
          { label: "Completed", value: stats.completed, icon: Users, tone: "from-emerald-500/15 to-emerald-500/0 text-emerald-600" },
          { label: "Cancelled", value: stats.cancelled, icon: Trash2, tone: "from-rose-500/15 to-rose-500/0 text-rose-600" },
        ] as const).map((s) => (
          <Card key={s.label} className={`relative overflow-hidden bg-gradient-to-br ${s.tone}`}>
            <CardContent className="flex items-center justify-between p-4">
              <div>
                <div className="text-xs uppercase tracking-wide text-muted-foreground">{s.label}</div>
                <div className="mt-1 text-2xl font-bold">{s.value}</div>
              </div>
              <div className="rounded-xl bg-background/70 p-2 ring-1 ring-border backdrop-blur">
                <s.icon className="h-5 w-5" />
              </div>
            </CardContent>
          </Card>
        ))}
      </div>

      {/* Shift coverage */}
      <div className="grid grid-cols-1 gap-3 md:grid-cols-3">
        {(["A", "B", "C"] as const).map((k) => {
          const Icon = SHIFT_TONE[k].icon;
          return (
            <div key={k} className={`rounded-xl border p-4 ${SHIFT_TONE[k].ring}`}>
              <div className="flex items-center justify-between">
                <div className="flex items-center gap-2">
                  <Icon className="h-4 w-4" />
                  <span className="font-medium">{SHIFTS[k].label}</span>
                </div>
                <Badge variant="outline" className="bg-background/70">{stats.coverage[k]} shifts</Badge>
              </div>
              <div className="mt-2 font-mono text-xs opacity-80">{SHIFTS[k].start} – {SHIFTS[k].end}</div>
            </div>
          );
        })}
      </div>

      {/* Filters */}
      <Card>
        <CardContent className="flex flex-wrap items-center gap-3 p-4">
          <div className="flex items-center gap-2 text-sm text-muted-foreground">
            <Filter className="h-4 w-4" /> Filters
          </div>
          <Input
            placeholder="Search guard, post, location…"
            value={search}
            onChange={(e) => setSearch(e.target.value)}
            className="h-9 max-w-xs"
          />
          <Select value={postFilter} onValueChange={setPostFilter}>
            <SelectTrigger className="h-9 w-[200px]"><SelectValue placeholder="All posts" /></SelectTrigger>
            <SelectContent>
              <SelectItem value="all">All posts</SelectItem>
              <SelectItem value="none">— Unassigned —</SelectItem>
              {postsQ.data?.map((p) => (
                <SelectItem key={p.id} value={p.id}>{p.name}</SelectItem>
              ))}
            </SelectContent>
          </Select>
          <Select value={statusFilter} onValueChange={setStatusFilter}>
            <SelectTrigger className="h-9 w-[160px]"><SelectValue placeholder="All statuses" /></SelectTrigger>
            <SelectContent>
              <SelectItem value="all">All statuses</SelectItem>
              <SelectItem value="scheduled">Scheduled</SelectItem>
              <SelectItem value="completed">Completed</SelectItem>
              <SelectItem value="cancelled">Cancelled</SelectItem>
            </SelectContent>
          </Select>
        </CardContent>
      </Card>

      {view === "week" ? (
        <Card>
          <CardHeader className="pb-3">
            <CardTitle className="flex items-center gap-2"><LayoutGrid className="h-4 w-4" /> Weekly board</CardTitle>
            <CardDescription>Click an empty slot to schedule a shift instantly.</CardDescription>
          </CardHeader>
          <CardContent className="p-0">
            <div className="w-full overflow-x-auto">
              <div className="grid min-w-[980px] grid-cols-7 gap-px bg-border">
                {weekDays.map((d) => {
                  const key = ymd(d);
                  const isToday = key === ymd(new Date());
                  const items = byDay.get(key) ?? [];
                  return (
                    <div key={key} className="min-h-[260px] bg-background p-2">
                      <div className="mb-2 flex items-center justify-between">
                        <div className={`text-sm font-medium ${isToday ? "text-primary" : ""}`}>{fmtDayLabel(d)}</div>
                        {isToday && <Badge variant="default" className="h-5 px-1.5 text-[10px]">Today</Badge>}
                      </div>
                      <div className="space-y-1.5">
                        {items.length === 0 && (
                          <div className="rounded-md border border-dashed py-3 text-center text-xs text-muted-foreground">
                            No shifts
                          </div>
                        )}
                        {items.map((r) => {
                          const k = detectShift(r.shift_start, r.shift_end);
                          const tone = k === "custom"
                            ? "border-muted bg-muted/40 text-foreground"
                            : SHIFT_TONE[k].ring;
                          const Icon = k === "custom" ? Clock : SHIFT_TONE[k].icon;
                          return (
                            <button
                              key={r.id}
                              onClick={() => openEdit(r)}
                              className={`group w-full rounded-md border p-2 text-left transition hover:shadow-sm ${tone}`}
                            >
                              <div className="flex items-center justify-between text-[11px] font-mono">
                                <span className="inline-flex items-center gap-1"><Icon className="h-3 w-3" /> {k !== "custom" ? k : "·"} · {r.shift_start.slice(0,5)}–{r.shift_end.slice(0,5)}</span>
                                <span className={`rounded px-1 ${STATUS_TONE[r.status] ?? ""}`}>{r.status}</span>
                              </div>
                              <div className="mt-1 truncate text-xs font-medium">{r.security_guards?.full_name ?? "Unassigned"}</div>
                              {(r.duty_posts?.name || r.location) && (
                                <div className="mt-0.5 flex items-center gap-1 truncate text-[11px] opacity-80">
                                  <MapPin className="h-3 w-3" /> {r.duty_posts?.name ?? r.location}
                                </div>
                              )}
                            </button>
                          );
                        })}
                        <div className="flex gap-1 pt-1">
                          {(["A","B","C"] as const).map((k) => (
                            <button
                              key={k}
                              onClick={() => quickCreate(key, k)}
                              className={`flex-1 rounded border border-dashed py-1 text-[10px] opacity-60 hover:opacity-100 ${SHIFT_TONE[k].chip}`}
                              title={`Add ${SHIFTS[k].label}`}
                            >
                              + {k}
                            </button>
                          ))}
                        </div>
                      </div>
                    </div>
                  );
                })}
              </div>
            </div>
          </CardContent>
        </Card>
      ) : (
        <Card>
          <CardHeader className="pb-3">
            <CardTitle className="flex items-center gap-2"><List className="h-4 w-4" /> All shifts</CardTitle>
            <CardDescription>{filtered.length} result{filtered.length === 1 ? "" : "s"}</CardDescription>
          </CardHeader>
          <CardContent className="p-0">
            <div className="w-full overflow-x-auto"><Table>
              <TableHeader>
                <TableRow>
                  <TableHead>Date</TableHead>
                  <TableHead>Shift</TableHead>
                  <TableHead>Guard</TableHead>
                  <TableHead>Location</TableHead>
                  <TableHead>Status</TableHead>
                  <TableHead className="text-right">Actions</TableHead>
                </TableRow>
              </TableHeader>
              <TableBody>
                {rostersQ.isLoading && (
                  <TableRow><TableCell colSpan={6} className="text-center text-muted-foreground py-8">Loading…</TableCell></TableRow>
                )}
                {!rostersQ.isLoading && filtered.length === 0 && (
                  <TableRow><TableCell colSpan={6} className="text-center text-muted-foreground py-8">
                    No shifts match your filters.
                  </TableCell></TableRow>
                )}
                {filtered.map((r) => {
                  const k = detectShift(r.shift_start, r.shift_end);
                  return (
                    <TableRow key={r.id}>
                      <TableCell>{r.shift_date}</TableCell>
                      <TableCell className="font-mono text-xs">
                        <span className="flex items-center gap-2">
                          {k !== "custom" && <Badge className={SHIFT_TONE[k].chip} variant="outline">{k}</Badge>}
                          {r.shift_start.slice(0,5)} – {r.shift_end.slice(0,5)}
                        </span>
                      </TableCell>
                      <TableCell>{r.security_guards?.full_name ?? "—"} <span className="text-muted-foreground text-xs">({r.security_guards?.employee_id})</span></TableCell>
                      <TableCell>
                        {r.duty_posts?.name ? (
                          <span className="flex flex-col">
                            <span className="font-medium">{r.duty_posts.name}</span>
                            {r.duty_posts.client_name && <span className="text-xs text-muted-foreground">{r.duty_posts.client_name}</span>}
                          </span>
                        ) : (r.location ?? "—")}
                      </TableCell>
                      <TableCell>
                        <Badge className={STATUS_TONE[r.status]} variant="outline">{r.status}</Badge>
                      </TableCell>
                      <TableCell className="text-right space-x-1">
                        <Button size="sm" variant="ghost" onClick={() => openEdit(r)}><Pencil className="h-4 w-4" /></Button>
                        <AlertDialog>
                          <AlertDialogTrigger asChild>
                            <Button size="sm" variant="ghost"><Trash2 className="h-4 w-4 text-destructive" /></Button>
                          </AlertDialogTrigger>
                          <AlertDialogContent>
                            <AlertDialogHeader>
                              <AlertDialogTitle>Remove shift?</AlertDialogTitle>
                              <AlertDialogDescription>This shift will be deleted.</AlertDialogDescription>
                            </AlertDialogHeader>
                            <AlertDialogFooter>
                              <AlertDialogCancel>Cancel</AlertDialogCancel>
                              <AlertDialogAction onClick={() => del.mutate(r.id)}>Delete</AlertDialogAction>
                            </AlertDialogFooter>
                          </AlertDialogContent>
                        </AlertDialog>
                      </TableCell>
                    </TableRow>
                  );
                })}
              </TableBody>
            </Table></div>
          </CardContent>
        </Card>
      )}
    </div>
  );
}