"use client"

import { useState, useEffect, useRef, useCallback, useMemo } from "react"
import { ATTENDANCE_STATUS_LABELS, type AttendanceStatus } from "../types"
import { Dropdown } from "@/components/ui/dropdown"
import { usePagination, TablePagination } from "@/components/ui/pagination"

// ─── types ───────────────────────────────────────────────────────────────────

type Employee = {
  id: string
  fullName: string
  branchId: string | null
  departmentId?: string | null
  position: string | null
}
type Branch = { id: string; name: string }
type Department = { id: string; name: string; branchId: string }

type CellKey = string
type Registry = Record<CellKey, {
  id?: string
  status: AttendanceStatus
  checkIn?: string
  checkOut?: string
  note?: string
  fromLeave?: boolean
}>

type Props = {
  employees: Employee[]
  branches: Branch[]
  departments?: Department[]
}

// ─── constants ───────────────────────────────────────────────────────────────

const STATUS_DISPLAY: Record<AttendanceStatus, { short: string; cell: string; dot: string }> = {
  present: { short: "P", cell: "bg-green-100  text-green-700", dot: "bg-green-500" },
  absent: { short: "A", cell: "bg-red-100    text-red-700", dot: "bg-red-500" },
  late: { short: "L", cell: "bg-yellow-100 text-yellow-700", dot: "bg-yellow-500" },
  half_day: { short: "H", cell: "bg-blue-100   text-blue-700", dot: "bg-blue-500" },
  on_leave: { short: "OL", cell: "bg-purple-100 text-purple-700", dot: "bg-purple-500" },
}

function pad(n: number) { return String(n).padStart(2, "0") }
function toDateStr(y: number, m: number, d: number) { return `${y}-${pad(m + 1)}-${pad(d)}` }
function getDaysInMonth(year: number, month: number) { return new Date(year, month + 1, 0).getDate() }
function getDayName(year: number, month: number, day: number) {
  return new Date(year, month, day).toLocaleDateString("en-US", { weekday: "short" })
}
function isWeekend(year: number, month: number, day: number) {
  const dow = new Date(year, month, day).getDay()
  return dow === 0 || dow === 6
}
function addDays(base: Date, n: number) { const d = new Date(base); d.setDate(d.getDate() + n); return d }

function toLocalTime(iso: string): string {
  return new Date(iso).toLocaleTimeString("en-GB", {
    hour: "2-digit",
    minute: "2-digit",
    timeZone: "Asia/Kuwait",
  })
}

// ─── component ───────────────────────────────────────────────────────────────

export default function AttendanceRegister({ employees, branches, departments = [] }: Props) {
  const today = new Date()
  const [year, setYear] = useState(today.getFullYear())
  const [month, setMonth] = useState(today.getMonth())
  // Default to "All Companies" (no branch filter)
  const [branchId, setBranchId] = useState("")
  const [deptId, setDeptId] = useState("")
  const [search, setSearch] = useState("")
  const [registry, setRegistry] = useState<Registry>({})
  const [loading, setLoading] = useState(false)

  // popup state
  const [popup, setPopup] = useState<{
    employeeId: string
    employeeName: string
    dateStr: string
    anchorRect: DOMRect
  } | null>(null)
  const [saving, setSaving] = useState(false)
  const popupRef = useRef<HTMLDivElement>(null)

  const days = getDaysInMonth(year, month)
  const dayNumbers = Array.from({ length: days }, (_, i) => i + 1)

  // ── departments for selected branch ────────────────────────────────────────
  const branchDepts = useMemo(
    () => (branchId ? departments.filter((d) => d.branchId === branchId) : departments),
    [departments, branchId]
  )

  useEffect(() => { setDeptId("") }, [branchId])

  // ── dropdown option lists ──────────────────────────────────────────────────
  const branchOptions = useMemo(() => [
    { value: "", label: "All Companies" },
    ...branches.map((b) => ({ value: b.id, label: b.name })),
  ], [branches])

  const deptOptions = useMemo(() => [
    { value: "", label: "All Departments" },
    ...branchDepts.map((d) => ({ value: d.id, label: d.name })),
  ], [branchDepts])

  // ── filtered employees ─────────────────────────────────────────────────────
  const filteredEmp = useMemo(() => {
    const q = search.trim().toLowerCase()
    return employees.filter((e) => {
      if (branchId && e.branchId !== branchId) return false
      if (deptId && e.departmentId !== deptId) return false
      if (q && !e.fullName.toLowerCase().includes(q)) return false
      return true
    })
  }, [employees, branchId, deptId, search])

  const { page, pageSize, setPage, setPageSize, totalPages, paginate, resetPage } =
    usePagination(filteredEmp, 10)

  useEffect(() => { resetPage() }, [branchId, deptId, search, month, year])

  const pagedEmp = paginate(filteredEmp)

  // ── fetch month data ────────────────────────────────────────────────────────
  const fetchMonth = useCallback(async () => {
    setLoading(true)
    try {
      const dateFrom = `${year}-${pad(month + 1)}-01`
      const dateTo = `${year}-${pad(month + 1)}-${pad(days)}`
      const params = new URLSearchParams({ dateFrom, dateTo })
      if (branchId) params.set("branchId", branchId)

      const [attRes, leaveRes] = await Promise.all([
        fetch(`/api/attendance?${params}`),
        fetch(`/api/leave-requests?dateFrom=${dateFrom}&dateTo=${dateTo}&status=approved`),
      ])

      const rows = await attRes.json() as Array<{
        id: string; employeeId: string; date: string
        checkIn: string | null; checkOut: string | null
        status: AttendanceStatus; note: string | null
      }>

      const leaveRows: Array<{ employeeId: string; startDate: string; endDate: string; status: string }> =
        leaveRes.ok ? await leaveRes.json() : []

      const map: Registry = {}
      for (const r of rows) {
        const d = new Date(r.date)
        const key = `${r.employeeId}_${toDateStr(d.getFullYear(), d.getMonth(), d.getDate())}`
        map[key] = {
          id: r.id,
          status: r.status,
          checkIn: r.checkIn ? toLocalTime(r.checkIn) : undefined,
          checkOut: r.checkOut ? toLocalTime(r.checkOut) : undefined,
          note: r.note ?? undefined,
        }
      }

      for (const lv of leaveRows) {
        if (lv.status !== "approved") continue
        const start = new Date(lv.startDate); start.setHours(0, 0, 0, 0)
        const end = new Date(lv.endDate); end.setHours(0, 0, 0, 0)
        let cur = new Date(start)
        while (cur <= end) {
          const ds = `${cur.getFullYear()}-${pad(cur.getMonth() + 1)}-${pad(cur.getDate())}`
          const key = `${lv.employeeId}_${ds}`
          if (!map[key]) map[key] = { status: "on_leave", fromLeave: true }
          cur = addDays(cur, 1)
        }
      }

      setRegistry(map)
    } finally {
      setLoading(false)
    }
  }, [year, month, branchId, days])

  useEffect(() => { fetchMonth() }, [fetchMonth])

  // close popup on outside click
  useEffect(() => {
    if (!popup) return
    function onDown(e: MouseEvent) {
      if (popupRef.current && !popupRef.current.contains(e.target as Node)) setPopup(null)
    }
    document.addEventListener("mousedown", onDown)
    return () => document.removeEventListener("mousedown", onDown)
  }, [popup])

  // ── open popup ──────────────────────────────────────────────────────────────
  function openPopup(e: React.MouseEvent, emp: Employee, dateStr: string) {
    const rect = (e.currentTarget as HTMLElement).getBoundingClientRect()
    setPopup({ employeeId: emp.id, employeeName: emp.fullName, dateStr, anchorRect: rect })
  }

  // ── save cell ───────────────────────────────────────────────────────────────
  async function saveCell(status: AttendanceStatus, checkIn?: string, checkOut?: string, note?: string) {
    if (!popup) return
    setSaving(true)
    const key = `${popup.employeeId}_${popup.dateStr}`
    const existing = registry[key]
    try {
      const body = {
        employeeId: popup.employeeId,
        branchId: branchId || undefined,
        date: popup.dateStr,
        status, checkIn, checkOut, note,
      }
      const res = existing?.id
        ? await fetch(`/api/attendance/${existing.id}`, { method: "PUT", headers: { "Content-Type": "application/json" }, body: JSON.stringify(body) })
        : await fetch("/api/attendance", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify(body) })
      const data = await res.json()
      setRegistry((prev) => ({ ...prev, [key]: { id: data.id, status, checkIn, checkOut, note } }))
      setPopup(null)
    } finally {
      setSaving(false)
    }
  }

  // ── clear cell ──────────────────────────────────────────────────────────────
  async function clearCell() {
    if (!popup) return
    const key = `${popup.employeeId}_${popup.dateStr}`
    const rec = registry[key]
    if (!rec?.id) { setPopup(null); return }
    setSaving(true)
    try {
      await fetch(`/api/attendance/${rec.id}`, { method: "DELETE" })
      setRegistry((prev) => { const n = { ...prev }; delete n[key]; return n })
      setPopup(null)
    } finally {
      setSaving(false)
    }
  }

  // ── summary (all filtered employees, not just current page) ────────────────
  const todayStr = toDateStr(today.getFullYear(), today.getMonth(), today.getDate())
  const todayCells = filteredEmp.map((e) => registry[`${e.id}_${todayStr}`]?.status)
  const summary = {
    present: todayCells.filter(s => s === "present").length,
    absent: todayCells.filter(s => s === "absent").length,
    late: todayCells.filter(s => s === "late").length,
    on_leave: todayCells.filter(s => s === "on_leave").length,
  }

  const hasFilters = !!(branchId || deptId || search)

  // ─── render ─────────────────────────────────────────────────────────────────
  return (
    <div className="space-y-4">

      {/* ── toolbar ── */}
      <div className="flex flex-wrap items-center justify-between gap-3 rounded-xl border bg-card px-4 py-3 shadow-sm">
        <div className="flex flex-wrap items-center gap-2">

          <div className="w-44">
            <Dropdown
              placeholder="All Companies"
              searchPlaceholder="Search companies…"
              options={branchOptions}
              value={branchId}
              onChange={setBranchId}
            />
          </div>

          {branchDepts.length > 0 && (
            <div className="w-44">
              <Dropdown
                placeholder="All Departments"
                searchPlaceholder="Search departments…"
                options={deptOptions}
                value={deptId}
                onChange={setDeptId}
              />
            </div>
          )}

          <div className="h-5 w-px bg-border" />

          <select
            className="h-9 rounded-lg border border-input bg-background px-3 text-sm font-medium shadow-sm focus:outline-none focus:ring-2 focus:ring-primary/20"
            value={`${year}-${pad(month + 1)}`}
            onChange={(e) => {
              const [y, m] = e.target.value.split("-").map(Number)
              setYear(y); setMonth(m - 1)
            }}
          >
            {Array.from({ length: 24 }, (_, i) => {
              const d = new Date(today.getFullYear(), today.getMonth() - 11 + i, 1)
              const y = d.getFullYear(), m = d.getMonth()
              return (
                <option key={`${y}-${m}`} value={`${y}-${pad(m + 1)}`}>
                  {d.toLocaleDateString("en-US", { month: "long", year: "numeric" })}
                </option>
              )
            })}
          </select>

          <div className="h-5 w-px bg-border" />

          <div className="relative">
            <svg
              className="pointer-events-none absolute left-2.5 top-1/2 -translate-y-1/2 text-muted-foreground"
              width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.5"
            >
              <circle cx="11" cy="11" r="8" /><path d="m21 21-4.35-4.35" />
            </svg>
            <input
              type="text"
              placeholder="Search employee…"
              value={search}
              onChange={(e) => setSearch(e.target.value)}
              className="h-9 rounded-lg border border-input bg-background pl-8 pr-3 text-sm shadow-sm focus:outline-none focus:ring-2 focus:ring-primary/20 w-44"
            />
          </div>

          {hasFilters && (
            <button
              onClick={() => { setBranchId(""); setDeptId(""); setSearch("") }}
              className="h-9 rounded-lg border border-input bg-background px-3 text-xs text-muted-foreground hover:text-foreground transition-colors"
            >
              Clear
            </button>
          )}

          {loading && (
            <span className="flex items-center gap-1.5 text-xs text-muted-foreground">
              <svg className="animate-spin" width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.5">
                <path d="M21 12a9 9 0 1 1-6.219-8.56" />
              </svg>
              Loading…
            </span>
          )}
        </div>

        <span className="text-xs text-muted-foreground">
          {filteredEmp.length} employee{filteredEmp.length !== 1 ? "s" : ""}
          {hasFilters && ` (filtered from ${employees.length})`}
        </span>
      </div>

      {/* today summary pills */}
      <div className="flex items-center gap-2 flex-wrap">
        {(["present", "absent", "late", "on_leave"] as const).map((s) => (
          <span key={s} className={`inline-flex items-center gap-1.5 rounded-full border px-2.5 py-0.5 text-xs font-medium ${STATUS_DISPLAY[s].cell}`}>
            <span className={`h-1.5 w-1.5 rounded-full ${STATUS_DISPLAY[s].dot}`} />
            {ATTENDANCE_STATUS_LABELS[s]}: {summary[s]}
          </span>
        ))}
      </div>

      {/* ── register table + pagination — unified card ── */}
      <div className="rounded-lg border bg-card overflow-auto">
        <table className="w-full border-collapse text-xs">
          <thead>
            <tr className="bg-muted/50">
              <th className="sticky left-0 z-20 bg-muted/80 backdrop-blur min-w-[180px] border-b border-r px-3 py-2.5 text-left text-sm font-semibold text-foreground">
                Employee
              </th>
              {dayNumbers.map((d) => {
                const weekend = isWeekend(year, month, d)
                const isToday = today.getDate() === d && today.getMonth() === month && today.getFullYear() === year
                return (
                  <th
                    key={d}
                    className={`border-b border-r px-0 py-1.5 text-center font-medium min-w-[36px] w-[36px] ${isToday ? "bg-primary/10 text-primary" : weekend ? "bg-muted/80 text-muted-foreground/60" : "text-muted-foreground"
                      }`}
                  >
                    <div className="text-[10px] leading-tight">{getDayName(year, month, d)}</div>
                    <div className={`text-xs font-bold leading-tight ${isToday ? "text-primary" : ""}`}>{d}</div>
                  </th>
                )
              })}
              <th className="border-b px-2 py-2.5 text-center text-xs font-semibold text-muted-foreground min-w-[120px]">
                Summary
              </th>
            </tr>
          </thead>

          <tbody>
            {pagedEmp.length === 0 ? (
              <tr>
                <td colSpan={days + 2} className="px-4 py-10 text-center text-muted-foreground">
                  {search || deptId
                    ? "No employees match your filters."
                    : "No employees found."}
                </td>
              </tr>
            ) : (
              pagedEmp.map((emp, empIdx) => {
                const empCells = dayNumbers.map((d) => registry[`${emp.id}_${toDateStr(year, month, d)}`]?.status)
                const empSummary = {
                  P: empCells.filter(s => s === "present").length,
                  A: empCells.filter(s => s === "absent").length,
                  L: empCells.filter(s => s === "late").length,
                  OL: empCells.filter(s => s === "on_leave").length,
                }

                return (
                  <tr key={emp.id} className={`group transition-colors hover:bg-muted/20 ${empIdx % 2 === 0 ? "" : "bg-muted/10"}`}>
                    <td className={`sticky left-0 z-10 border-b border-r px-3 py-2 ${empIdx % 2 === 0 ? "bg-card" : "bg-muted/10"} group-hover:bg-muted/20 backdrop-blur`}>
                      <div className="font-medium text-foreground leading-tight">{emp.fullName}</div>
                      {emp.position && (
                        <div className="text-[10px] text-muted-foreground leading-tight mt-0.5">{emp.position}</div>
                      )}
                    </td>

                    {dayNumbers.map((d) => {
                      const dateStr = toDateStr(year, month, d)
                      const key = `${emp.id}_${dateStr}`
                      const cell = registry[key]
                      const weekend = isWeekend(year, month, d)
                      const isToday = today.getDate() === d && today.getMonth() === month && today.getFullYear() === year
                      const isFuture = new Date(year, month, d) > today

                      return (
                        <td
                          key={d}
                          className={`border-b border-r p-0 text-center ${isToday ? "bg-primary/5" : weekend ? "bg-muted/30" : ""
                            } ${isFuture ? "opacity-40 cursor-not-allowed" : "cursor-pointer"}`}
                          onClick={isFuture ? undefined : (e) => openPopup(e, emp, dateStr)}
                        >
                          {cell ? (
                            <span
                              className={`flex h-8 w-full items-center justify-center text-[11px] font-bold transition-all hover:brightness-95 ${STATUS_DISPLAY[cell.status].cell} ${cell.fromLeave ? "opacity-70 italic" : ""}`}
                              style={{ border: "none" }}
                            >
                              {STATUS_DISPLAY[cell.status].short}
                            </span>
                          ) : (
                            <span className={`flex h-8 w-full items-center justify-center text-muted-foreground/25 transition-colors ${!isFuture && !weekend ? "hover:bg-muted/40 hover:text-muted-foreground/60" : ""}`}>
                              {weekend ? "" : "·"}
                            </span>
                          )}
                        </td>
                      )
                    })}

                    <td className="border-b px-2 py-1.5">
                      <div className="flex items-center justify-center gap-1 flex-wrap">
                        {empSummary.P > 0 && <span className={`rounded px-1.5 py-0.5 text-[10px] font-bold ${STATUS_DISPLAY.present.cell}`}>P:{empSummary.P}</span>}
                        {empSummary.A > 0 && <span className={`rounded px-1.5 py-0.5 text-[10px] font-bold ${STATUS_DISPLAY.absent.cell}`}>A:{empSummary.A}</span>}
                        {empSummary.L > 0 && <span className={`rounded px-1.5 py-0.5 text-[10px] font-bold ${STATUS_DISPLAY.late.cell}`}>L:{empSummary.L}</span>}
                        {empSummary.OL > 0 && <span className={`rounded px-1.5 py-0.5 text-[10px] font-bold ${STATUS_DISPLAY.on_leave.cell}`}>OL:{empSummary.OL}</span>}
                        {(empSummary.P + empSummary.A + empSummary.L + empSummary.OL) === 0 && (
                          <span className="text-[10px] text-muted-foreground/40">—</span>
                        )}
                      </div>
                    </td>
                  </tr>
                )
              })
            )}
          </tbody>
        </table>

        {/* shared pagination — sits flush as the table card footer */}
        {filteredEmp.length > 0 && (
          <TablePagination
            total={filteredEmp.length}
            page={page}
            pageSize={pageSize}
            totalPages={totalPages}
            onPageChange={setPage}
            onPageSizeChange={setPageSize}
            pageSizeOptions={[10, 20, 50]}
            className="rounded-b-lg rounded-t-none"
          />
        )}
      </div>

      {/* ── cell popup ── */}
      {popup && (
        <CellPopup
          ref={popupRef}
          popup={popup}
          existing={registry[`${popup.employeeId}_${popup.dateStr}`]}
          saving={saving}
          onSave={saveCell}
          onClear={clearCell}
          onClose={() => setPopup(null)}
        />
      )}
    </div>
  )
}

// ─── CellPopup ────────────────────────────────────────────────────────────────

import React from "react"

type PopupProps = {
  popup: { employeeName: string; dateStr: string; anchorRect: DOMRect }
  existing?: { status: AttendanceStatus; checkIn?: string; checkOut?: string; note?: string; fromLeave?: boolean }
  saving: boolean
  onSave: (status: AttendanceStatus, checkIn?: string, checkOut?: string, note?: string) => void
  onClear: () => void
  onClose: () => void
}

const CellPopup = React.forwardRef<HTMLDivElement, PopupProps>(
  ({ popup, existing, saving, onSave, onClear, onClose }, ref) => {
    const [status, setStatus] = useState<AttendanceStatus>(existing?.status ?? "present")
    const [checkIn, setCheckIn] = useState(existing?.checkIn ?? "")
    const [checkOut, setCheckOut] = useState(existing?.checkOut ?? "")
    const [note, setNote] = useState(existing?.note ?? "")

    const displayDate = new Date(popup.dateStr + "T00:00:00").toLocaleDateString("en-US", {
      weekday: "short", month: "short", day: "numeric",
    })

    const style: React.CSSProperties = {
      position: "fixed",
      top: popup.anchorRect.bottom + 6,
      left: Math.min(popup.anchorRect.left, window.innerWidth - 320),
      zIndex: 50,
      width: 300,
    }

    return (
      <div ref={ref} style={style} className="rounded-xl border bg-popover shadow-xl">
        <div className="flex items-start justify-between border-b px-4 py-3">
          <div>
            <div className="text-sm font-semibold leading-tight">{popup.employeeName}</div>
            <div className="text-xs text-muted-foreground mt-0.5">{displayDate}</div>
            {existing?.fromLeave && (
              <span className="mt-1.5 inline-flex items-center gap-1 rounded-full bg-purple-50 border border-purple-200 px-2 py-0.5 text-[10px] font-medium text-purple-600">
                <svg width="9" height="9" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.5">
                  <rect x="3" y="4" width="18" height="18" rx="2" /><line x1="16" y1="2" x2="16" y2="6" /><line x1="8" y1="2" x2="8" y2="6" /><line x1="3" y1="10" x2="21" y2="10" />
                </svg>
                Approved leave
              </span>
            )}
          </div>
          <button onClick={onClose} className="text-muted-foreground hover:text-foreground transition-colors ml-2 mt-0.5">
            <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.5" strokeLinecap="round">
              <path d="M18 6 6 18M6 6l12 12" />
            </svg>
          </button>
        </div>

        <div className="p-4 space-y-3">
          <div>
            <div className="text-xs font-medium text-muted-foreground mb-2">Status</div>
            <div className="grid grid-cols-5 gap-1">
              {(Object.keys(STATUS_DISPLAY) as AttendanceStatus[]).map((s) => (
                <button
                  key={s}
                  onClick={() => setStatus(s)}
                  className={`flex flex-col items-center gap-0.5 rounded-lg border-2 py-1.5 px-0.5 text-[10px] font-bold transition-all ${status === s
                      ? `${STATUS_DISPLAY[s].cell} border-current scale-105 shadow-sm`
                      : "border-transparent bg-muted/40 text-muted-foreground hover:bg-muted"
                    }`}
                >
                  <span className="text-xs font-black">{STATUS_DISPLAY[s].short}</span>
                  <span className="leading-tight text-center" style={{ fontSize: 9 }}>
                    {ATTENDANCE_STATUS_LABELS[s].split(" ")[0]}
                  </span>
                </button>
              ))}
            </div>
          </div>

          {(status === "present" || status === "late") && (
            <div className="grid grid-cols-2 gap-2">
              <div>
                <label className="text-xs font-medium text-muted-foreground">Check In</label>
                <input type="time" value={checkIn} onChange={(e) => setCheckIn(e.target.value)}
                  className="mt-1 flex h-8 w-full rounded-md border border-input bg-background px-2 text-xs" />
              </div>
              <div>
                <label className="text-xs font-medium text-muted-foreground">Check Out</label>
                <input type="time" value={checkOut} onChange={(e) => setCheckOut(e.target.value)}
                  className="mt-1 flex h-8 w-full rounded-md border border-input bg-background px-2 text-xs" />
              </div>
            </div>
          )}

          <div>
            <label className="text-xs font-medium text-muted-foreground">Note (optional)</label>
            <input type="text" value={note} onChange={(e) => setNote(e.target.value)}
              placeholder="Add a note…"
              className="mt-1 flex h-8 w-full rounded-md border border-input bg-background px-2 text-xs" />
          </div>

          <div className="flex gap-2 pt-1">
            <button
              onClick={() => onSave(status, checkIn || undefined, checkOut || undefined, note || undefined)}
              disabled={saving}
              className="flex-1 h-8 rounded-md bg-primary text-primary-foreground text-xs font-medium hover:bg-primary/90 disabled:opacity-60 transition-colors"
            >
              {saving ? "Saving…" : existing?.status ? "Update" : "Save"}
            </button>
            {existing?.status && (
              <button
                onClick={onClear}
                disabled={saving}
                className="h-8 px-3 rounded-md border border-destructive/40 text-destructive text-xs font-medium hover:bg-destructive/10 disabled:opacity-60 transition-colors"
              >
                Clear
              </button>
            )}
          </div>
        </div>
      </div>
    )
  }
)
CellPopup.displayName = "CellPopup"