import { createFileRoute, Link } from "@tanstack/react-router";
import { useQuery, useMutation, useQueryClient } from "@tanstack/react-query";
import { useEffect, useMemo, useRef, 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 } from "@/components/ui/dialog";
import { QrCode, MapPin, Search, Users, ClipboardCheck, Clock, Activity, ShieldCheck, Crosshair, Calendar, Download, Flag, FlagOff, Plus, Pencil, LogOut, Trash2 } from "lucide-react";
import { toast } from "sonner";
import { toPng } from "html-to-image";
import { NewCheckInPage } from "./attendance.new";

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

type Coords = { lat: number; lng: number; accuracy?: number };

type AttendanceStatus = "checked_in" | "checked_out" | "flagged";
type AttendanceMethod = "qr" | "gps" | "manual";
type AttendanceRow = {
  id: string;
  guard_id: string;
  method: AttendanceMethod;
  status: AttendanceStatus;
  check_in_at: string;
  check_out_at: string | null;
  check_in_lat: number | null;
  check_in_lng: number | null;
  check_out_lat: number | null;
  check_out_lng: number | null;
  location: string | null;
  notes: string | null;
  shift: string | null;
  duty_post_id: string | null;
  duty_posts: { name: string; client_name: string | null } | null;
  security_guards: { full_name: string; employee_id: string } | null;
};

type EditForm = {
  guard_id: string;
  duty_post_id: string;
  method: AttendanceMethod;
  status: AttendanceStatus;
  shift: string;
  check_in_at: string;
  check_out_at: string;
  check_in_lat: string;
  check_in_lng: string;
  check_out_lat: string;
  check_out_lng: string;
  location: string;
  notes: string;
};

const SHIFTS = {
  A: { label: "Shift A", time: "06:00 – 14:00" },
  B: { label: "Shift B", time: "14:00 – 22:00" },
  C: { label: "Shift C", time: "22:00 – 06:00" },
} as const;

function detectShiftFromNow(): "A" | "B" | "C" {
  const h = new Date().getHours();
  if (h >= 6 && h < 14) return "A";
  if (h >= 14 && h < 22) return "B";
  return "C";
}

function toDateTimeLocal(value: string | null) {
  if (!value) return "";
  const d = new Date(value);
  if (Number.isNaN(d.getTime())) return "";
  const pad = (n: number) => String(n).padStart(2, "0");
  return `${d.getFullYear()}-${pad(d.getMonth() + 1)}-${pad(d.getDate())}T${pad(d.getHours())}:${pad(d.getMinutes())}`;
}

function toIsoOrNull(value: string) {
  if (!value) return null;
  const d = new Date(value);
  return Number.isNaN(d.getTime()) ? null : d.toISOString();
}

function numberOrNull(value: string) {
  if (value.trim() === "") return null;
  const n = Number(value);
  if (!Number.isFinite(n)) throw new Error("Coordinates must be valid numbers");
  return n;
}

function AttendancePage() {
  const qc = useQueryClient();
  const [search, setSearch] = useState("");
  const [idSearch, setIdSearch] = useState("");
  const [showNewCheckIn, setShowNewCheckIn] = useState(false);
  const [statusFilter, setStatusFilter] = useState<string>("all");
  const [shiftFilter, setShiftFilter] = useState<string>("all");
  const todayYmd = () => {
    const d = new Date();
    const pad = (n: number) => String(n).padStart(2, "0");
    return `${d.getFullYear()}-${pad(d.getMonth() + 1)}-${pad(d.getDate())}`;
  };
  const [dateFrom, setDateFrom] = useState<string>(todayYmd);
  const [dateTo, setDateTo] = useState<string>(todayYmd);
  const tableRef = useRef<HTMLDivElement | null>(null);
  const [exportingImg, setExportingImg] = useState(false);
  const [editing, setEditing] = useState<AttendanceRow | null>(null);
  const [deleting, setDeleting] = useState<AttendanceRow | null>(null);
  const [editForm, setEditForm] = useState<EditForm | null>(null);
  const [now, setNow] = useState<Date>(() => new Date());
  useEffect(() => {
    const t = setInterval(() => setNow(new Date()), 1000);
    return () => clearInterval(t);
  }, []);

  const attendanceQ = useQuery({
    queryKey: ["attendance", dateFrom, dateTo],
    queryFn: async () => {
      let q = supabase
        .from("attendance")
        .select("*, security_guards(full_name, employee_id), duty_posts(name, client_name)")
        .order("check_in_at", { ascending: false })
        .limit(500);
      if (dateFrom) q = q.gte("check_in_at", `${dateFrom}T00:00:00`);
      if (dateTo) q = q.lte("check_in_at", `${dateTo}T23:59:59.999`);
      const { data, error } = await q;
      if (error) throw error;
      return data;
    },
  });

  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")
        .eq("status", "active")
        .order("name");
      if (error) throw error;
      return data;
    },
  });

  const toggleFlag = useMutation({
    mutationFn: async ({ id, nextStatus }: { id: string; nextStatus: AttendanceStatus }) => {
      const { error } = await supabase
        .from("attendance")
        .update({ status: nextStatus })
        .eq("id", id);
      if (error) throw error;
    },
    onSuccess: (_d, v) => {
      toast.success(v.nextStatus === "flagged" ? "Marked as flagged" : "Flag removed");
      qc.invalidateQueries({ queryKey: ["attendance"] });
    },
    onError: (e: Error) => toast.error(e.message),
  });

  const checkOut = useMutation({
    mutationFn: async (id: string) => {
      const { error } = await supabase
        .from("attendance")
        .update({ status: "checked_out", check_out_at: new Date().toISOString() })
        .eq("id", id);
      if (error) throw error;
    },
    onSuccess: () => {
      toast.success("Checked out");
      qc.invalidateQueries({ queryKey: ["attendance"] });
    },
    onError: (e: Error) => toast.error(e.message),
  });

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

  const saveEdit = useMutation({
    mutationFn: async () => {
      if (!editing || !editForm) throw new Error("No attendance record selected");
      if (!editForm.guard_id) throw new Error("Select a guard");
      const checkInIso = toIsoOrNull(editForm.check_in_at);
      const checkOutIso = toIsoOrNull(editForm.check_out_at);
      if (!checkInIso) throw new Error("Check-in time is required");
      if (checkOutIso && new Date(checkOutIso).getTime() < new Date(checkInIso).getTime()) {
        throw new Error("Check-out time cannot be before check-in time");
      }

      const { error } = await supabase
        .from("attendance")
        .update({
          guard_id: editForm.guard_id,
          duty_post_id: editForm.duty_post_id || null,
          method: editForm.method,
          status: editForm.status,
          shift: editForm.shift || null,
          check_in_at: checkInIso,
          check_out_at: checkOutIso,
          check_in_lat: numberOrNull(editForm.check_in_lat),
          check_in_lng: numberOrNull(editForm.check_in_lng),
          check_out_lat: numberOrNull(editForm.check_out_lat),
          check_out_lng: numberOrNull(editForm.check_out_lng),
          location: editForm.location.trim() || null,
          notes: editForm.notes.trim() || null,
        })
        .eq("id", editing.id);
      if (error) throw error;
    },
    onSuccess: () => {
      toast.success("Attendance updated");
      qc.invalidateQueries({ queryKey: ["attendance"] });
      setEditing(null);
      setEditForm(null);
    },
    onError: (e: Error) => toast.error(e.message),
  });

  const openEdit = (row: AttendanceRow) => {
    setEditing(row);
    setEditForm({
      guard_id: row.guard_id,
      duty_post_id: row.duty_post_id ?? "",
      method: row.method,
      status: row.status,
      shift: row.shift ?? "",
      check_in_at: toDateTimeLocal(row.check_in_at),
      check_out_at: toDateTimeLocal(row.check_out_at),
      check_in_lat: row.check_in_lat?.toString() ?? "",
      check_in_lng: row.check_in_lng?.toString() ?? "",
      check_out_lat: row.check_out_lat?.toString() ?? "",
      check_out_lng: row.check_out_lng?.toString() ?? "",
      location: row.location ?? "",
      notes: row.notes ?? "",
    });
  };

  // Realtime sync
  useEffect(() => {
    const ch = supabase
      .channel("attendance_rt")
      .on("postgres_changes", { event: "*", schema: "public", table: "attendance" }, () => {
        qc.invalidateQueries({ queryKey: ["attendance"] });
      })
      .subscribe();
    return () => { supabase.removeChannel(ch); };
  }, [qc]);

  const stats = useMemo(() => {
    const rows = attendanceQ.data ?? [];
    const today = new Date().toDateString();
    const todays = rows.filter((r: { check_in_at: string }) => new Date(r.check_in_at).toDateString() === today);
    const onDuty = rows.filter((r: { status: string }) => r.status === "checked_in").length;
    const uniqueGuards = new Set(todays.map((r: { guard_id: string }) => r.guard_id)).size;
    const completed = rows.filter((r: { check_out_at: string | null }) => r.check_out_at);
    const avgMin = completed.length
      ? Math.round(
          completed.reduce((s: number, r: { check_in_at: string; check_out_at: string | null }) => {
            return s + (new Date(r.check_out_at as string).getTime() - new Date(r.check_in_at).getTime()) / 60000;
          }, 0) / completed.length
        )
      : 0;
    return { today: todays.length, onDuty, uniqueGuards, avgMin };
  }, [attendanceQ.data]);

  const filtered = useMemo(() => {
    const rows = (attendanceQ.data ?? []) as AttendanceRow[];
    const q = search.trim().toLowerCase();
    const idq = idSearch.trim().toLowerCase();
    return rows.filter((r) => {
      if (statusFilter !== "all" && r.status !== statusFilter) return false;
      if (shiftFilter !== "all" && (r.shift ?? "") !== shiftFilter) return false;
      if (dateFrom || dateTo) {
        const d = new Date(r.check_in_at);
        const pad = (n: number) => String(n).padStart(2, "0");
        const ymd = `${d.getFullYear()}-${pad(d.getMonth() + 1)}-${pad(d.getDate())}`;
        if (dateFrom && ymd < dateFrom) return false;
        if (dateTo && ymd > dateTo) return false;
      }
      if (idq) {
        const eid = (r.security_guards?.employee_id ?? "").toLowerCase();
        if (!eid.includes(idq)) return false;
      }
      if (!q) return true;
      const hay = `${r.security_guards?.full_name ?? ""} ${r.security_guards?.employee_id ?? ""} ${r.location ?? ""}`.toLowerCase();
      return hay.includes(q);
    });
  }, [attendanceQ.data, search, idSearch, statusFilter, shiftFilter, dateFrom, dateTo]);

  const fmtDur = (m: number) => (m >= 60 ? `${Math.floor(m / 60)}h ${m % 60}m` : `${m}m`);

  const exportCSV = () => {
    const rows: (string | number)[][] = [["Guard", "Employee ID", "Shift", "Method", "Location", "Check-in", "Check-out", "Lat", "Lng", "Status"]];
    for (const a of filtered) {
      rows.push([
        a.security_guards?.full_name ?? "",
        a.security_guards?.employee_id ?? "",
        a.shift ?? "",
        a.method,
        a.duty_posts?.name ?? a.location ?? "",
        new Date(a.check_in_at).toISOString(),
        a.check_out_at ? new Date(a.check_out_at).toISOString() : "",
        a.check_in_lat ?? "",
        a.check_in_lng ?? "",
        a.status,
      ]);
    }
    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 = `attendance-${todayYmd()}.csv`; a.click();
    URL.revokeObjectURL(url);
  };

  const exportImage = async () => {
    if (!tableRef.current) return;
    setExportingImg(true);
    try {
      const bg = getComputedStyle(document.body).backgroundColor || "#ffffff";
      const dataUrl = await toPng(tableRef.current, {
        cacheBust: true,
        pixelRatio: 2,
        backgroundColor: bg,
      });
      const a = document.createElement("a");
      a.href = dataUrl;
      a.download = `attendance-${todayYmd()}.png`;
      a.click();
      toast.success("Image downloaded");
    } catch (e) {
      toast.error(e instanceof Error ? e.message : "Image export failed");
    } finally {
      setExportingImg(false);
    }
  };

  const statTiles = [
    { label: "Check-ins today", value: stats.today, icon: ClipboardCheck, tone: "from-sky-500/15 to-sky-500/0 text-sky-600 dark:text-sky-400", hint: "All records" },
    { label: "Currently on duty", value: stats.onDuty, icon: Activity, tone: "from-emerald-500/15 to-emerald-500/0 text-emerald-600 dark:text-emerald-400", hint: "Live" },
    { label: "Unique guards today", value: stats.uniqueGuards, icon: Users, tone: "from-violet-500/15 to-violet-500/0 text-violet-600 dark:text-violet-400", hint: "Distinct" },
    { label: "Avg shift duration", value: stats.avgMin ? fmtDur(stats.avgMin) : "—", icon: Clock, tone: "from-amber-500/15 to-amber-500/0 text-amber-600 dark:text-amber-400", hint: "Completed only" },
  ];

  return (
    <div className="space-y-6">
      <section className="relative overflow-hidden rounded-[28px] border border-white/10 bg-gradient-primary text-primary-foreground shadow-elegant">
        <div className="absolute inset-0 bg-grid opacity-20" aria-hidden />
        <div className="absolute inset-0 bg-[radial-gradient(1000px_500px_at_15%_-10%,rgba(255,255,255,0.18),transparent_60%),radial-gradient(800px_400px_at_100%_120%,rgba(110,231,183,0.22),transparent_60%)]" aria-hidden />
        <div className="absolute -top-24 -right-20 h-72 w-72 rounded-full bg-white/15 blur-3xl animate-float-slow" aria-hidden />
        <div className="absolute -bottom-24 -left-16 h-72 w-72 rounded-full bg-emerald-300/20 blur-3xl" aria-hidden />
        <div className="relative grid gap-6 p-6 sm:p-9 lg:grid-cols-[minmax(0,1fr)_auto] lg:items-end">
          <div className="min-w-0">
            <div className="inline-flex items-center gap-2 rounded-full bg-white/10 px-3 py-1 text-[11px] uppercase tracking-[0.22em] text-primary-foreground/90 ring-1 ring-white/15 backdrop-blur">
              <span className="relative inline-flex h-2 w-2">
                <span className="absolute inset-0 rounded-full bg-emerald-300 animate-ping opacity-75" />
                <span className="relative inline-block h-2 w-2 rounded-full bg-emerald-300" />
              </span>
              Live attendance · {now.toLocaleDateString(undefined, { weekday: "long", day: "numeric", month: "short" })}
            </div>
            <h1 className="mt-4 text-4xl sm:text-5xl font-extrabold tracking-tight leading-[1.05]">
              Attendance <span className="bg-gradient-to-r from-white to-emerald-200 bg-clip-text text-transparent">Operations</span>
            </h1>
            <p className="mt-2 text-sm sm:text-[15px] text-primary-foreground/85 max-w-xl">QR &amp; GPS verified check-ins with geofence enforcement and live shift telemetry.</p>
            <div className="mt-5 flex flex-wrap gap-2 text-[11px]">
              <span className="inline-flex items-center gap-1.5 rounded-full bg-white/12 px-3 py-1 ring-1 ring-white/15 backdrop-blur"><ShieldCheck className="h-3.5 w-3.5" /> Geofence on</span>
              <span className="inline-flex items-center gap-1.5 rounded-full bg-white/12 px-3 py-1 ring-1 ring-white/15 backdrop-blur"><Crosshair className="h-3.5 w-3.5" /> GPS lock</span>
              <span className="inline-flex items-center gap-1.5 rounded-full bg-white/12 px-3 py-1 ring-1 ring-white/15 backdrop-blur"><QrCode className="h-3.5 w-3.5" /> QR ready</span>
            </div>
          </div>
          <div className="flex flex-col items-stretch gap-3 sm:flex-row lg:flex-col lg:items-end">
            <div className="rounded-2xl bg-white/12 px-5 py-3 ring-1 ring-white/15 backdrop-blur shadow-elegant">
              <div className="text-[10px] uppercase tracking-widest text-primary-foreground/80">Local time</div>
              <div className="mt-1 text-3xl font-bold leading-none tabular-nums">
                {now.toLocaleTimeString([], { hour: "2-digit", minute: "2-digit", second: "2-digit", hour12: false })}
              </div>
              <div className="mt-1 text-[11px] text-primary-foreground/80">Asia/Dhaka</div>
            </div>
            <div className="rounded-2xl bg-white/12 px-5 py-3 ring-1 ring-white/15 backdrop-blur shadow-elegant">
              <div className="text-[10px] uppercase tracking-widest text-primary-foreground/80">Auto-shift</div>
              <div className="mt-1 text-2xl font-bold leading-none">Shift {detectShiftFromNow()}</div>
              <div className="mt-1 text-[11px] text-primary-foreground/80 tabular-nums">{SHIFTS[detectShiftFromNow()].time}</div>
            </div>
          </div>
        </div>
      </section>

      <div className="grid gap-4 sm:grid-cols-2 lg:grid-cols-4">
        {statTiles.map((s) => (
          <Card key={s.label} className="group relative overflow-hidden border-border/60 rounded-2xl shadow-elegant transition duration-300 hover:-translate-y-1 hover:shadow-glow">
            <div className={`absolute inset-0 bg-gradient-to-br ${s.tone} opacity-80 pointer-events-none`} aria-hidden />
            <div className="pointer-events-none absolute -right-10 -top-10 h-32 w-32 rounded-full bg-white/40 blur-3xl opacity-0 group-hover:opacity-60 transition" aria-hidden />
            <CardContent className="relative p-5 flex items-start justify-between gap-3">
              <div className="min-w-0">
                <div className="text-[11px] uppercase tracking-[0.18em] text-muted-foreground">{s.label}</div>
                <div className="mt-2 text-[2rem] font-extrabold leading-none tracking-tight tabular-nums">{s.value}</div>
                <div className="mt-2 text-[11px] text-muted-foreground">{s.hint}</div>
              </div>
              <div className={`h-12 w-12 shrink-0 rounded-2xl bg-background/80 backdrop-blur grid place-items-center ring-1 ring-border/70 shadow-sm ${s.tone.split(" ").slice(-2).join(" ")}`}>
                <s.icon className="h-5 w-5" />
              </div>
            </CardContent>
            <div className="absolute inset-x-0 bottom-0 h-0.5 bg-gradient-to-r from-transparent via-primary/40 to-transparent" aria-hidden />
          </Card>
        ))}
      </div>

      <Card className="relative shadow-elegant border-border/60 rounded-2xl overflow-hidden">
        <div className="absolute inset-0 bg-[radial-gradient(600px_200px_at_0%_0%,oklch(0.55_0.14_255/0.10),transparent_60%),radial-gradient(500px_200px_at_100%_100%,oklch(0.62_0.14_165/0.10),transparent_60%)] pointer-events-none" aria-hidden />
        <div className="h-1 w-full bg-gradient-primary" aria-hidden />
        <CardContent className="relative flex flex-col sm:flex-row sm:items-center sm:justify-between gap-4 p-5">
          <div className="flex items-center gap-3 min-w-0">
            <div className="relative h-12 w-12 rounded-2xl bg-gradient-primary grid place-items-center text-primary-foreground shadow-elegant shrink-0">
              <ClipboardCheck className="h-5 w-5" />
              <span className="absolute -top-1 -right-1 h-3 w-3 rounded-full bg-emerald-400 ring-2 ring-card animate-pulse-dot" />
            </div>
            <div className="min-w-0">
              <div className="font-semibold text-base">New Check-in</div>
              <div className="text-sm text-muted-foreground">Record a guard's arrival with QR or GPS verification.</div>
            </div>
          </div>
          <Button
            size="lg"
            className="shadow-elegant hover:shadow-glow transition"
            onClick={() => setShowNewCheckIn((v) => !v)}
          >
            <Plus className="h-4 w-4 mr-1" /> New Check-in
          </Button>
        </CardContent>
      </Card>

      {showNewCheckIn && (
        <NewCheckInPage embedded onDone={() => setShowNewCheckIn(false)} />
      )}

      <Card className="shadow-elegant border-border/60 rounded-2xl overflow-hidden">
        <div className="relative border-b bg-gradient-to-br from-primary/10 via-primary/5 to-transparent">
          <div className="pointer-events-none absolute inset-0 opacity-40 [background:radial-gradient(circle_at_top_right,theme(colors.primary/20),transparent_60%)]" />
          <CardHeader className="relative flex flex-row items-center justify-between gap-3">
            <div className="flex items-center gap-3">
              <div className="h-11 w-11 rounded-xl bg-gradient-primary grid place-items-center shadow-md ring-1 ring-primary/20">
                <Activity className="h-5 w-5 text-primary-foreground" />
              </div>
              <div>
                <CardTitle className="tracking-tight">Recent Attendance</CardTitle>
                <CardDescription>Live check-ins for selected date range</CardDescription>
              </div>
            </div>
            <div className="flex items-center gap-2">
              <Badge variant="outline" className="hidden sm:inline-flex gap-1.5 bg-background/60 backdrop-blur">
                <Calendar className="h-3 w-3" /> {filtered.length} shown
              </Badge>
              <Button size="sm" variant="outline" onClick={exportCSV} disabled={filtered.length === 0} className="bg-background/60 backdrop-blur">
                <Download className="h-4 w-4 mr-1" /> Export
              </Button>
              <Button size="sm" variant="outline" onClick={exportImage} disabled={filtered.length === 0 || exportingImg} className="bg-background/60 backdrop-blur">
                <Download className="h-4 w-4 mr-1" /> {exportingImg ? "Rendering…" : "Image"}
              </Button>
            </div>
          </CardHeader>
        </div>
        <CardContent className="pb-3 pt-4 flex flex-col sm:flex-row flex-wrap gap-3 border-b bg-muted/20">
          <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, ID or location"
              className="pl-9"
            />
          </div>
          <div className="relative w-full sm:w-56">
            <Search className="absolute left-3 top-1/2 -translate-y-1/2 h-4 w-4 text-muted-foreground" />
            <Input
              value={idSearch}
              onChange={(e) => setIdSearch(e.target.value)}
              placeholder="Employee ID number"
              className="pl-9"
              inputMode="search"
            />
          </div>
          <Select value={statusFilter} onValueChange={setStatusFilter}>
            <SelectTrigger className="w-full sm:w-48"><SelectValue /></SelectTrigger>
            <SelectContent>
              <SelectItem value="all">All statuses</SelectItem>
              <SelectItem value="checked_in">Checked in</SelectItem>
              <SelectItem value="checked_out">Checked out</SelectItem>
              <SelectItem value="flagged">Flagged</SelectItem>
            </SelectContent>
          </Select>
          <Select value={shiftFilter} onValueChange={setShiftFilter}>
            <SelectTrigger className="w-full sm:w-44" aria-label="Filter by shift">
              <SelectValue placeholder="Shift" />
            </SelectTrigger>
            <SelectContent>
              <SelectItem value="all">All shifts</SelectItem>
              <SelectItem value="A">Shift A (6am–2pm)</SelectItem>
              <SelectItem value="B">Shift B (2pm–10pm)</SelectItem>
              <SelectItem value="C">Shift C (10pm–6am)</SelectItem>
              <SelectItem value="custom">Custom</SelectItem>
            </SelectContent>
          </Select>
          <div className="flex items-center gap-2">
            <Input
              type="date"
              value={dateFrom}
              onChange={(e) => setDateFrom(e.target.value)}
              className="w-full sm:w-40"
              aria-label="From date"
            />
            <span className="text-muted-foreground text-xs">to</span>
            <Input
              type="date"
              value={dateTo}
              onChange={(e) => setDateTo(e.target.value)}
              className="w-full sm:w-40"
              aria-label="To date"
            />
          </div>
          {(dateFrom || dateTo) && (
            <Button variant="outline" size="sm" onClick={() => { setDateFrom(""); setDateTo(""); }}>
              All dates
            </Button>
          )}
        </CardContent>
        <CardContent className="p-0">
          <div ref={tableRef} className="bg-card">
          <div className="hidden md:block w-full overflow-x-auto"><Table>
            <TableHeader className="bg-muted/60 sticky top-0 z-10 backdrop-blur">
              <TableRow className="hover:bg-transparent border-b-2">
                <TableHead className="w-16 font-semibold text-foreground/80 uppercase text-[11px] tracking-wider">ক্রমিক নং</TableHead>
                <TableHead className="font-semibold text-foreground/80 uppercase text-[11px] tracking-wider">Guard</TableHead>
                <TableHead className="font-semibold text-foreground/80 uppercase text-[11px] tracking-wider">Shift</TableHead>
                <TableHead className="font-semibold text-foreground/80 uppercase text-[11px] tracking-wider">Method</TableHead>
                <TableHead className="font-semibold text-foreground/80 uppercase text-[11px] tracking-wider">Location</TableHead>
                <TableHead className="font-semibold text-foreground/80 uppercase text-[11px] tracking-wider">Check-in</TableHead>
                <TableHead className="font-semibold text-foreground/80 uppercase text-[11px] tracking-wider">Check-out</TableHead>
                <TableHead className="font-semibold text-foreground/80 uppercase text-[11px] tracking-wider">Coords</TableHead>
                <TableHead className="font-semibold text-foreground/80 uppercase text-[11px] tracking-wider">Status</TableHead>
                <TableHead className="text-right font-semibold text-foreground/80 uppercase text-[11px] tracking-wider">Actions</TableHead>
              </TableRow>
            </TableHeader>
            <TableBody>
              {attendanceQ.isLoading && (
                <TableRow><TableCell colSpan={10} className="text-center text-muted-foreground py-8">Loading…</TableCell></TableRow>
              )}
              {!attendanceQ.isLoading && filtered.length === 0 && (
                <TableRow><TableCell colSpan={10} className="text-center text-muted-foreground py-8">No matching check-ins.</TableCell></TableRow>
              )}
              {filtered.map((a, i) => (
                <TableRow key={a.id} className="group/row border-b-border/40 hover:bg-primary/5 transition-colors odd:bg-muted/10">
                  <TableCell className="tabular-nums">
                    <span className="inline-flex h-6 min-w-6 items-center justify-center rounded-md bg-muted px-1.5 text-[11px] font-semibold text-muted-foreground">
                      {i + 1}
                    </span>
                  </TableCell>
                  <TableCell>
                    <div className="flex items-center gap-2 min-w-0">
                      <div className="h-8 w-8 shrink-0 rounded-full bg-gradient-primary grid place-items-center text-primary-foreground text-xs font-semibold">
                        {(a.security_guards?.full_name ?? "?").slice(0, 1).toUpperCase()}
                      </div>
                      <div className="min-w-0">
                        <div className="font-medium truncate">{a.security_guards?.full_name ?? "—"}</div>
                        <div className="text-muted-foreground text-xs truncate">{a.security_guards?.employee_id}</div>
                      </div>
                    </div>
                  </TableCell>
                  <TableCell>
                    {a.shift ? <Badge variant="secondary">{a.shift}</Badge> : <span className="text-muted-foreground">—</span>}
                  </TableCell>
                  <TableCell><Badge variant="outline" className="uppercase">{a.method}</Badge></TableCell>
                  <TableCell className="text-xs">
                    {a.duty_posts?.name ?? a.location ?? "—"}
                    {a.duty_posts?.client_name && (
                      <div className="text-muted-foreground">{a.duty_posts.client_name}</div>
                    )}
                  </TableCell>
                  <TableCell className="text-xs tabular-nums">{new Date(a.check_in_at).toLocaleString()}</TableCell>
                  <TableCell className="text-xs tabular-nums">{a.check_out_at ? new Date(a.check_out_at).toLocaleString() : "—"}</TableCell>
                  <TableCell className="font-mono text-xs">
                    {a.check_in_lat != null && a.check_in_lng != null
                      ? `${a.check_in_lat.toFixed(4)}, ${a.check_in_lng.toFixed(4)}`
                      : "—"}
                  </TableCell>
                  <TableCell>
                    <span
                      className={
                        "inline-flex items-center gap-1 rounded-full px-2 py-0.5 text-xs font-medium " +
                        (a.status === "checked_in"
                          ? "bg-emerald-500/10 text-emerald-600 dark:text-emerald-400"
                          : a.status === "checked_out"
                          ? "bg-muted text-muted-foreground"
                          : "bg-destructive/10 text-destructive")
                      }
                    >
                      <span className={"h-1.5 w-1.5 rounded-full " + (a.status === "checked_in" ? "bg-emerald-500 animate-pulse-dot" : "bg-current opacity-60")} />
                      {a.status.replace("_", " ")}
                    </span>
                  </TableCell>
                  <TableCell className="text-right">
                    <div className="flex justify-end gap-1">
                      <Button
                        size="sm"
                        variant="ghost"
                        onClick={() => openEdit(a)}
                        title="Edit attendance"
                      >
                        <Pencil className="h-4 w-4" />
                      </Button>
                      {!a.check_out_at && (
                        <Button
                          size="icon"
                          variant="ghost"
                          onClick={() => checkOut.mutate(a.id)}
                          disabled={checkOut.isPending && checkOut.variables === a.id}
                          title="Check out"
                          aria-label="Check out"
                          className="h-8 w-8"
                        >
                          <LogOut className="h-4 w-4 text-emerald-600" />
                        </Button>
                      )}
                      <Button
                        size="icon"
                        variant="ghost"
                        onClick={() => toggleFlag.mutate({ id: a.id, nextStatus: a.status === "flagged" ? (a.check_out_at ? "checked_out" : "checked_in") : "flagged" })}
                        disabled={toggleFlag.isPending && toggleFlag.variables?.id === a.id}
                        title={a.status === "flagged" ? "Remove flag" : "Flag this record"}
                        aria-label={a.status === "flagged" ? "Remove flag" : "Flag this record"}
                        className="h-8 w-8"
                      >
                        {a.status === "flagged"
                          ? <FlagOff className="h-4 w-4 text-muted-foreground" />
                          : <Flag className="h-4 w-4 text-destructive" />}
                      </Button>
                      <Button
                        size="icon"
                        variant="ghost"
                        onClick={() => setDeleting(a)}
                        disabled={deleteRow.isPending && deleteRow.variables === a.id}
                        title="Delete record"
                        aria-label="Delete record"
                        className="h-8 w-8"
                      >
                        <Trash2 className="h-4 w-4 text-destructive" />
                      </Button>
                    </div>
                  </TableCell>
                </TableRow>
              ))}
            </TableBody>
          </Table></div>
          {/* Mobile card list */}
          <div className="md:hidden divide-y divide-border/60">
            {attendanceQ.isLoading && (
              <div className="text-center text-muted-foreground py-8 text-sm">Loading…</div>
            )}
            {!attendanceQ.isLoading && filtered.length === 0 && (
              <div className="text-center text-muted-foreground py-8 text-sm">No matching check-ins.</div>
            )}
            {filtered.map((a, i) => (
              <div key={a.id} className="p-4 space-y-3 transition-colors hover:bg-primary/5">
                <div className="flex items-start gap-3">
                  <div className="relative grid h-11 w-11 shrink-0 place-items-center rounded-full bg-gradient-primary text-primary-foreground text-sm font-semibold shadow-md ring-2 ring-primary/20">
                    {(a.security_guards?.full_name ?? "?").slice(0, 1).toUpperCase()}
                    <span className="absolute -bottom-1 -right-1 inline-flex h-5 min-w-5 items-center justify-center rounded-full bg-background px-1 text-[10px] font-bold text-foreground ring-1 ring-border">
                      {i + 1}
                    </span>
                  </div>
                  <div className="min-w-0 flex-1">
                    <div className="font-semibold truncate">{a.security_guards?.full_name ?? "—"}</div>
                    <div className="text-xs text-muted-foreground truncate">
                      ID: {a.security_guards?.employee_id ?? "—"}
                    </div>
                  </div>
                  <span
                    className={
                      "shrink-0 inline-flex items-center gap-1 rounded-full px-2 py-0.5 text-[11px] font-medium " +
                      (a.status === "checked_in"
                        ? "bg-emerald-500/10 text-emerald-600 dark:text-emerald-400"
                        : a.status === "checked_out"
                        ? "bg-muted text-muted-foreground"
                        : "bg-destructive/10 text-destructive")
                    }
                  >
                    <span className={"h-1.5 w-1.5 rounded-full " + (a.status === "checked_in" ? "bg-emerald-500 animate-pulse-dot" : "bg-current opacity-60")} />
                    {a.status.replace("_", " ")}
                  </span>
                </div>

                <div className="flex flex-wrap gap-1.5">
                  {a.shift && <Badge variant="secondary">Shift {a.shift}</Badge>}
                  <Badge variant="outline" className="uppercase">{a.method}</Badge>
                  {a.duty_posts?.name || a.location ? (
                    <Badge variant="outline" className="max-w-[60%] truncate">
                      <MapPin className="mr-1 h-3 w-3" />
                      {a.duty_posts?.name ?? a.location}
                    </Badge>
                  ) : null}
                </div>

                <div className="grid grid-cols-2 gap-2 text-xs">
                  <div className="rounded-lg bg-muted/40 p-2">
                    <div className="text-[10px] uppercase tracking-wide text-muted-foreground">Check-in</div>
                    <div className="tabular-nums">{new Date(a.check_in_at).toLocaleString()}</div>
                  </div>
                  <div className="rounded-lg bg-muted/40 p-2">
                    <div className="text-[10px] uppercase tracking-wide text-muted-foreground">Check-out</div>
                    <div className="tabular-nums">{a.check_out_at ? new Date(a.check_out_at).toLocaleString() : "—"}</div>
                  </div>
                </div>

                {a.check_in_lat != null && a.check_in_lng != null && (
                  <div className="font-mono text-[11px] text-muted-foreground">
                    📍 {a.check_in_lat.toFixed(4)}, {a.check_in_lng.toFixed(4)}
                  </div>
                )}

                <div className="flex flex-wrap gap-2 pt-1">
                  <Button size="sm" variant="outline" className="flex-1 min-w-[80px]" onClick={() => openEdit(a)}>
                    <Pencil className="h-4 w-4 mr-1" /> Edit
                  </Button>
                  {!a.check_out_at && (
                    <Button
                      size="sm"
                      variant="outline"
                      className="flex-1 min-w-[80px]"
                      onClick={() => checkOut.mutate(a.id)}
                      disabled={checkOut.isPending && checkOut.variables === a.id}
                    >
                      <LogOut className="h-4 w-4 mr-1 text-emerald-600" /> Check-out
                    </Button>
                  )}
                  <Button
                    size="sm"
                    variant="outline"
                    onClick={() => toggleFlag.mutate({ id: a.id, nextStatus: a.status === "flagged" ? (a.check_out_at ? "checked_out" : "checked_in") : "flagged" })}
                    disabled={toggleFlag.isPending && toggleFlag.variables?.id === a.id}
                    aria-label={a.status === "flagged" ? "Remove flag" : "Flag"}
                  >
                    {a.status === "flagged"
                      ? <FlagOff className="h-4 w-4 text-muted-foreground" />
                      : <Flag className="h-4 w-4 text-destructive" />}
                  </Button>
                  <Button
                    size="sm"
                    variant="outline"
                    onClick={() => setDeleting(a)}
                    disabled={deleteRow.isPending && deleteRow.variables === a.id}
                    aria-label="Delete"
                  >
                    <Trash2 className="h-4 w-4 text-destructive" />
                  </Button>
                </div>
              </div>
            ))}
          </div>
          </div>
        </CardContent>
      </Card>

      <Dialog open={Boolean(deleting)} onOpenChange={(open) => { if (!open) setDeleting(null); }}>
        <DialogContent className="sm:max-w-md">
          <DialogHeader>
            <DialogTitle>Delete attendance record?</DialogTitle>
          </DialogHeader>
          <p className="text-sm text-muted-foreground">
            This will permanently delete {deleting?.security_guards?.full_name ?? "this guard"}'s attendance record.
          </p>
          <DialogFooter>
            <Button variant="outline" onClick={() => setDeleting(null)}>Cancel</Button>
            <Button
              variant="destructive"
              onClick={() => deleting && deleteRow.mutate(deleting.id)}
              disabled={deleteRow.isPending}
            >
              {deleteRow.isPending ? "Deleting…" : "Delete"}
            </Button>
          </DialogFooter>
        </DialogContent>
      </Dialog>

      <Dialog open={Boolean(editing && editForm)} onOpenChange={(open) => { if (!open) { setEditing(null); setEditForm(null); } }}>
        <DialogContent className="max-w-3xl">
          <DialogHeader>
            <DialogTitle>Edit attendance</DialogTitle>
          </DialogHeader>
          {editForm && (
            <div className="grid gap-4 sm:grid-cols-2">
              <div className="grid gap-2">
                <Label>Guard</Label>
                <Select value={editForm.guard_id} onValueChange={(value) => setEditForm({ ...editForm, guard_id: value })}>
                  <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={editForm.duty_post_id || "none"} onValueChange={(value) => setEditForm({ ...editForm, duty_post_id: value === "none" ? "" : value })}>
                  <SelectTrigger><SelectValue placeholder="Select post" /></SelectTrigger>
                  <SelectContent>
                    <SelectItem value="none">No duty post</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 gap-2">
                <Label>Method</Label>
                <Select value={editForm.method} onValueChange={(value) => setEditForm({ ...editForm, method: value as AttendanceMethod })}>
                  <SelectTrigger><SelectValue /></SelectTrigger>
                  <SelectContent>
                    <SelectItem value="gps">GPS</SelectItem>
                    <SelectItem value="qr">QR</SelectItem>
                    <SelectItem value="manual">Manual</SelectItem>
                  </SelectContent>
                </Select>
              </div>
              <div className="grid gap-2">
                <Label>Status</Label>
                <Select value={editForm.status} onValueChange={(value) => setEditForm({ ...editForm, status: value as AttendanceStatus })}>
                  <SelectTrigger><SelectValue /></SelectTrigger>
                  <SelectContent>
                    <SelectItem value="checked_in">Checked in</SelectItem>
                    <SelectItem value="checked_out">Checked out</SelectItem>
                    <SelectItem value="flagged">Flagged</SelectItem>
                  </SelectContent>
                </Select>
              </div>
              <div className="grid gap-2">
                <Label>Shift</Label>
                <Select value={editForm.shift || "none"} onValueChange={(value) => setEditForm({ ...editForm, shift: value === "none" ? "" : value })}>
                  <SelectTrigger><SelectValue placeholder="Select shift" /></SelectTrigger>
                  <SelectContent>
                    <SelectItem value="none">No shift</SelectItem>
                    <SelectItem value="A">Shift A</SelectItem>
                    <SelectItem value="B">Shift B</SelectItem>
                    <SelectItem value="C">Shift C</SelectItem>
                    <SelectItem value="custom">Custom</SelectItem>
                  </SelectContent>
                </Select>
              </div>
              <div className="grid gap-2">
                <Label>Location</Label>
                <Input value={editForm.location} onChange={(e) => setEditForm({ ...editForm, location: e.target.value })} />
              </div>
              <div className="grid gap-2">
                <Label>Check-in time</Label>
                <Input type="datetime-local" value={editForm.check_in_at} onChange={(e) => setEditForm({ ...editForm, check_in_at: e.target.value })} />
              </div>
              <div className="grid gap-2">
                <Label>Check-out time</Label>
                <Input type="datetime-local" value={editForm.check_out_at} onChange={(e) => setEditForm({ ...editForm, check_out_at: e.target.value })} />
              </div>
              <div className="grid gap-2">
                <Label>Check-in latitude</Label>
                <Input inputMode="decimal" value={editForm.check_in_lat} onChange={(e) => setEditForm({ ...editForm, check_in_lat: e.target.value })} />
              </div>
              <div className="grid gap-2">
                <Label>Check-in longitude</Label>
                <Input inputMode="decimal" value={editForm.check_in_lng} onChange={(e) => setEditForm({ ...editForm, check_in_lng: e.target.value })} />
              </div>
              <div className="grid gap-2">
                <Label>Check-out latitude</Label>
                <Input inputMode="decimal" value={editForm.check_out_lat} onChange={(e) => setEditForm({ ...editForm, check_out_lat: e.target.value })} />
              </div>
              <div className="grid gap-2">
                <Label>Check-out longitude</Label>
                <Input inputMode="decimal" value={editForm.check_out_lng} onChange={(e) => setEditForm({ ...editForm, check_out_lng: e.target.value })} />
              </div>
              <div className="grid gap-2 sm:col-span-2">
                <Label>Notes</Label>
                <Textarea rows={3} value={editForm.notes} onChange={(e) => setEditForm({ ...editForm, notes: e.target.value })} />
              </div>
            </div>
          )}
          <DialogFooter>
            <Button variant="outline" onClick={() => { setEditing(null); setEditForm(null); }}>Cancel</Button>
            <Button onClick={() => saveEdit.mutate()} disabled={saveEdit.isPending}>
              {saveEdit.isPending ? "Saving…" : "Save changes"}
            </Button>
          </DialogFooter>
        </DialogContent>
      </Dialog>
    </div>
  );
}