'use client';

import { useState, useEffect, useMemo, useCallback } from 'react';
import { addDays, subDays } from 'date-fns';
import Image from 'next/image';
import {
  ChevronLeft,
  ChevronRight,
  Trash2,
  Plus,
  Building2,
  Settings,
  X,
  Pencil,
  Check,
  Ban,
  AlertTriangle,
  Filter,
  Download,
  Clock,
  Coffee,
  Zap,
} from 'lucide-react';
import Link from 'next/link';
import { formatTime, formatDate, toUnix, dayRange, dateKey, fromInput } from '@/lib/time';
import { calculateDayMinutes, formatHours } from '@/lib/calculations';
import { fetchApi } from '@/lib/api';

type Company = { id: number; name: string };
type Employee = { id: number; name: string; isActive: boolean; companyId: number };
type TimeEntry = {
  id: number;
  employeeId: number;
  companyId: number;
  type: 'IN' | 'OUT' | 'BREAK_IN' | 'BREAK_OUT';
  timestamp: number;
  photoBase64: string | null;
  isDeleted: boolean;
  employeeName: string;
};
type DayEntries = {
  date: string;
  entries: TimeEntry[];
  clockMinutes: number;
  breakMinutes: number;
  workedMinutes: number;
  hasErrors: boolean;
  errors: string[];
};

function Drawer({ open, onClose, children }: { open: boolean; onClose: () => void; children: React.ReactNode }) {
  if (!open) return null;
  return (
    <div className="fixed inset-0 z-50 flex items-end sm:items-center justify-center">
      <button
        type="button"
        aria-label="Close details"
        className="absolute inset-0 bg-black/50 cursor-default"
        onClick={onClose}
      />
      <div className="bg-base-100 rounded-t-2xl sm:rounded-2xl shadow-2xl p-6 w-full max-w-lg relative z-10 max-h-[88vh] overflow-y-auto">
        <button className="btn btn-sm btn-circle btn-ghost absolute right-2 top-2" onClick={onClose}>
          <X className="size-4" />
        </button>
        {children}
      </div>
    </div>
  );
}

const DATE_PRESETS = [
  { label: 'Today', getDates: () => ({ start: new Date(), end: new Date() }) },
  { label: 'Yesterday', getDates: () => ({ start: subDays(new Date(), 1), end: subDays(new Date(), 1) }) },
  { label: 'Last 7 days', getDates: () => ({ start: subDays(new Date(), 6), end: new Date() }) },
  { label: 'Last 14 days', getDates: () => ({ start: subDays(new Date(), 13), end: new Date() }) },
  { label: 'Last 30 days', getDates: () => ({ start: subDays(new Date(), 29), end: new Date() }) },
];

function dateInputValue(date: Date) {
  return formatDate(toUnix(date), 'yyyy-MM-dd');
}

function dateInputToDate(value: string, boundary: 'start' | 'end' = 'start') {
  return new Date(`${value}${boundary === 'start' ? 'T00:00:00' : 'T23:59:59'}`);
}

export default function AdminPage() {
  const [companies, setCompanies] = useState<Company[]>([]);
  const [selectedCompany, setSelectedCompany] = useState<string>('');
  const [employees, setEmployees] = useState<Employee[]>([]);
  const [allEntries, setAllEntries] = useState<TimeEntry[]>([]);
  const [startDate, setStartDate] = useState<string>(() => dateInputValue(subDays(new Date(), 13)));
  const [endDate, setEndDate] = useState<string>(() => dateInputValue(new Date()));
  const [selectedDayEntries, setSelectedDayEntries] = useState<{
    employeeName: string;
    entries: TimeEntry[];
    date: string;
    errors: string[];
  } | null>(null);
  const [sheetOpen, setSheetOpen] = useState(false);
  const [manualPunchForm, setManualPunchForm] = useState<{
    employeeId: number;
    type: string;
    timestamp: string;
    forceOverride: boolean;
  }>({ employeeId: 0, type: 'IN', timestamp: '', forceOverride: false });
  const [editingEntryIds, setEditingEntryIds] = useState<Set<number>>(new Set());
  const [editTimestamps, setEditTimestamps] = useState<Record<number, string>>({});
  const [editingOverride, setEditingOverride] = useState<Record<number, boolean>>({});
  const [showIssuesOnly, setShowIssuesOnly] = useState(false);
  const [manualPunchError, setManualPunchError] = useState<string | null>(null);

  useEffect(() => {
    const onKey = (e: KeyboardEvent) => {
      if (e.key === 'Escape') setSheetOpen(false);
    };
    window.addEventListener('keydown', onKey);
    return () => window.removeEventListener('keydown', onKey);
  }, []);

  useEffect(() => {
    fetchApi<Company[]>('/api/companies')
      .then((data) => {
        setCompanies(data);
        setSelectedCompany((current) => current || data[0]?.id.toString() || '');
      })
      .catch(console.error);
  }, []);

  useEffect(() => {
    if (!selectedCompany) return;
    fetchApi<Employee[]>(`/api/employees?companyId=${selectedCompany}`).then(setEmployees).catch(console.error);
  }, [selectedCompany]);

  const loadEntries = useCallback(async () => {
    if (!selectedCompany) return;
    const { start: startUnix } = dayRange(dateInputToDate(startDate));
    const { end: endUnix } = dayRange(dateInputToDate(endDate, 'end'));
    const contextStartUnix = startUnix - 36 * 3600;
    const contextEndUnix = endUnix + 36 * 3600;
    fetchApi<TimeEntry[]>(
      `/api/time-entries?companyId=${selectedCompany}&startDate=${contextStartUnix}&endDate=${contextEndUnix}`,
    )
      .then(setAllEntries)
      .catch(console.error);
  }, [selectedCompany, startDate, endDate]);

  useEffect(() => {
    loadEntries();
  }, [loadEntries]);

  // Keep the open drawer in sync after any mutation — grid already refreshes via
  // loadEntries() -> allEntries -> gridData, but selectedDayEntries is a snapshot
  // taken when the drawer opened. Without this the timeline/summary/errors stay
  // frozen until you close and reopen.
  useEffect(() => {
    if (!sheetOpen || !selectedDayEntries) return;
    const empId = manualPunchForm.employeeId;
    const dateStr = selectedDayEntries.date;
    const dayData = gridData[empId]?.[dateStr];
    if (!dayData) return;
    const prevIds = selectedDayEntries.entries.map((e) => e.id).join(',');
    const nextIds = dayData.entries.map((e) => e.id).join(',');
    const prevErr = selectedDayEntries.errors.join('|');
    const nextErr = (dayData.errors || []).join('|');
    if (prevIds !== nextIds || prevErr !== nextErr) {
      setSelectedDayEntries((prev) =>
        prev ? { ...prev, entries: dayData.entries, errors: dayData.errors || [] } : prev,
      );
    }
  }, [allEntries, gridData, sheetOpen, selectedDayEntries, manualPunchForm.employeeId]);

  const days = useMemo(() => {
    const start = dateInputToDate(startDate);
    const end = dateInputToDate(endDate);
    const diff = Math.max((end.getTime() - start.getTime()) / 86400000, 0);
    return Array.from({ length: diff + 1 }, (_, i) => addDays(start, i));
  }, [startDate, endDate]);

  const gridData = useMemo(() => {
    const data: Record<number, Record<string, DayEntries>> = {};
    for (const emp of employees) {
      const empData: Record<string, DayEntries> = {};
      data[emp.id] = empData;
      for (const day of days) {
        const { start, end } = dayRange(day);
        const dateStr = dateKey(toUnix(day));
        const empEntries = allEntries.filter((e) => e.employeeId === emp.id);
        const dayEntries = empEntries.filter(
          (e) => e.employeeId === emp.id && e.timestamp >= start && e.timestamp <= end,
        );
        // Use the shared library , never duplicate inline
        const result = calculateDayMinutes(empEntries, dateStr);
        empData[dateStr] = { date: dateStr, entries: dayEntries, ...result };
      }
    }
    return data;
  }, [employees, allEntries, days]);

  const employeeTotals = useMemo(() => {
    const totals: Record<
      number,
      { clockMinutes: number; breakMinutes: number; workedMinutes: number; hasActivity: boolean }
    > = {};
    for (const emp of employees) {
      let clockMinutes = 0,
        breakMinutes = 0,
        workedMinutes = 0,
        hasActivity = false;
      for (const day of days) {
        const dayData = gridData[emp.id]?.[dateKey(toUnix(day))];
        if (dayData) {
          clockMinutes += dayData.clockMinutes;
          breakMinutes += dayData.breakMinutes;
          workedMinutes += dayData.workedMinutes;
          if (dayData.entries.length > 0) hasActivity = true;
        }
      }
      totals[emp.id] = { clockMinutes, breakMinutes, workedMinutes, hasActivity };
    }
    return totals;
  }, [employees, gridData, days]);

  const issueStats = useMemo(() => {
    let totalErrors = 0;
    const employeesWithErrors = new Set<number>();
    for (const emp of employees) {
      for (const day of days) {
        if (gridData[emp.id]?.[dateKey(toUnix(day))]?.hasErrors) {
          totalErrors++;
          employeesWithErrors.add(emp.id);
        }
      }
    }
    return { totalErrors, employeeCount: employeesWithErrors.size };
  }, [employees, days, gridData]);

  const visibleEmployees = useMemo(() => {
    if (!showIssuesOnly) return employees;
    return employees.filter((emp) => days.some((day) => gridData[emp.id]?.[dateKey(toUnix(day))]?.hasErrors));
  }, [employees, days, gridData, showIssuesOnly]);

  const openDetailDrawer = (employee: Employee, dateStr: string) => {
    const dayData = gridData[employee.id]?.[dateStr];
    if (!dayData) return;
    setSelectedDayEntries({
      employeeName: employee.name,
      entries: dayData.entries,
      date: dateStr,
      errors: dayData.errors || [],
    });
    setManualPunchForm({
      employeeId: employee.id,
      type: 'IN',
      timestamp: new Date().toISOString().slice(0, 16),
      forceOverride: false,
    });
    setEditingEntryIds(new Set());
    setEditTimestamps({});
    setEditingOverride({});
    setManualPunchError(null);
    setSheetOpen(true);
  };

  const handleDeleteEntry = async (entryId: number) => {
    await fetchApi<{ entry: TimeEntry }>('/api/time-entries', {
      method: 'PATCH',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({ id: entryId, isDeleted: true }),
    });
    loadEntries();
  };

  const handleRestoreEntry = async (entryId: number) => {
    await fetchApi<{ entry: TimeEntry }>('/api/time-entries', {
      method: 'PATCH',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({ id: entryId, isDeleted: false }),
    });
    loadEntries();
  };

  const handleAddManualPunch = async () => {
    if (!manualPunchForm || !selectedCompany) return;
    setManualPunchError(null);
    const timestamp = fromInput(manualPunchForm.timestamp);
    try {
      await fetchApi<{ entry: TimeEntry }>('/api/time-entries', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({
          employeeId: manualPunchForm.employeeId,
          companyId: parseInt(selectedCompany),
          type: manualPunchForm.type,
          timestamp,
          forceOverride: manualPunchForm.forceOverride,
        }),
      });
      setManualPunchForm((prev) => ({
        ...prev,
        type: 'IN',
        timestamp: new Date().toISOString().slice(0, 16),
        forceOverride: false,
      }));
      loadEntries();
    } catch (e: unknown) {
      setManualPunchError(e instanceof Error ? e.message : 'Failed to add punch');
      throw e;
    }
  };

  const startEditingTimestamp = (entry: TimeEntry) => {
    setEditingEntryIds((prev) => {
      const n = new Set(prev);
      n.add(entry.id);
      return n;
    });
    setEditTimestamps((prev) => ({
      ...prev,
      [entry.id]: `${formatDate(entry.timestamp, 'yyyy-MM-dd')}T${formatDate(entry.timestamp, 'HH:mm')}`,
    }));
  };

  const saveTimestamp = async (entryId: number, forceOverride = false) => {
    const ts = editTimestamps[entryId];
    if (!ts) return;
    try {
      await fetchApi<{ entry: TimeEntry }>('/api/time-entries', {
        method: 'PATCH',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ id: entryId, timestamp: fromInput(ts), forceOverride }),
      });
      setEditingEntryIds((prev) => {
        const n = new Set(prev);
        n.delete(entryId);
        return n;
      });
      setEditingOverride((prev) => {
        const n = { ...prev };
        delete n[entryId];
        return n;
      });
      loadEntries();
    } catch (e: unknown) {
      alert(e instanceof Error ? e.message : 'Failed to update timestamp');
      throw e;
    }
  };

  const cancelEditing = (entryId: number) => {
    setEditingEntryIds((prev) => {
      const n = new Set(prev);
      n.delete(entryId);
      return n;
    });
    setEditingOverride((prev) => {
      const n = { ...prev };
      delete n[entryId];
      return n;
    });
  };

  const applyPreset = (preset: (typeof DATE_PRESETS)[0]) => {
    const { start, end } = preset.getDates();
    setStartDate(dateInputValue(start));
    setEndDate(dateInputValue(end));
  };

  const shiftWindow = (direction: 1 | -1) => {
    // Shift by 1 day increments, preserving the existing date span
    setStartDate(dateInputValue(addDays(dateInputToDate(startDate), direction)));
    setEndDate(dateInputValue(addDays(dateInputToDate(endDate), direction)));
  };

  if (companies.length === 0) {
    return (
      <div className="min-h-screen bg-base-200 flex items-center justify-center p-4">
        <div className="card bg-base-100 shadow-xl p-8 w-full max-w-md text-center space-y-4">
          <div className="text-5xl">📊</div>
          <h1 className="text-2xl font-semibold">Admin Dashboard</h1>
          <p className="text-base-content/60">No hotels yet.</p>
          <Link href="/admin/manage">
            <button className="btn btn-primary w-full">
              <Building2 className="size-4" /> Go to Manage
            </button>
          </Link>
        </div>
      </div>
    );
  }

  const entryDotColors: Record<string, string> = {
    IN: 'bg-success',
    OUT: 'bg-error',
    BREAK_OUT: 'bg-warning',
    BREAK_IN: 'bg-warning',
  };
  const entryLabels: Record<string, string> = {
    IN: 'Clock In',
    OUT: 'Clock Out',
    BREAK_OUT: 'Break Start',
    BREAK_IN: 'Break End',
  };
  const entryIcons: Record<string, string> = { IN: '🟢', OUT: '🔴', BREAK_OUT: '🟡', BREAK_IN: '🟡' };

  return (
    <div className="min-h-screen bg-base-200">
      {/* Header */}
      <header className="bg-base-100 border-b border-base-300 px-4 py-3 sticky top-0 z-10">
        <div className="max-w-7xl mx-auto flex items-center justify-between flex-wrap gap-3">
          <div className="flex items-center gap-3">
            <span className="text-xl">📊</span>
            <h1 className="font-semibold text-lg">Pulse Clock · Admin</h1>
          </div>
          <div className="flex items-center gap-2 flex-wrap">
            <select
              value={selectedCompany}
              onChange={(e) => e.target.value && setSelectedCompany(e.target.value)}
              className="select select-bordered select-sm w-44"
            >
              {companies.map((c) => (
                <option key={c.id} value={c.id.toString()}>
                  {c.name}
                </option>
              ))}
            </select>
            <input
              type="date"
              value={startDate}
              onChange={(e) => e.target.value && setStartDate(e.target.value)}
              className="input input-bordered input-sm w-36"
            />
            <span className="text-sm text-base-content/40">–</span>
            <input
              type="date"
              value={endDate}
              onChange={(e) => e.target.value && setEndDate(e.target.value)}
              className="input input-bordered input-sm w-36"
            />
            <div className="join">
              <button className="btn btn-outline btn-square btn-sm join-item" onClick={() => shiftWindow(-1)}>
                <ChevronLeft className="size-4" />
              </button>
              <button className="btn btn-outline btn-square btn-sm join-item" onClick={() => shiftWindow(1)}>
                <ChevronRight className="size-4" />
              </button>
            </div>
            <button className="btn btn-outline btn-sm" onClick={loadEntries}>
              Refresh
            </button>
            <button
              className={`btn btn-sm ${showIssuesOnly ? 'btn-warning' : 'btn-outline'}`}
              onClick={() => setShowIssuesOnly((v) => !v)}
            >
              <Filter className="size-4" /> {showIssuesOnly ? 'Show All' : 'Issues Only'}
            </button>
            <Link href="/admin/payroll">
              <button className="btn btn-outline btn-sm">
                <Download className="size-4" /> Payroll
              </button>
            </Link>
            <Link href="/admin/manage">
              <button className="btn btn-outline btn-sm">
                <Settings className="size-4" /> Manage
              </button>
            </Link>
          </div>
        </div>
        {/* Date presets */}
        <div className="max-w-7xl mx-auto flex gap-1 mt-2 flex-wrap">
          {DATE_PRESETS.map((p) => (
            <button key={p.label} className="btn btn-ghost btn-xs" onClick={() => applyPreset(p)}>
              {p.label}
            </button>
          ))}
        </div>
      </header>

      {/* Issue Summary Banner , prominent */}
      <div className="max-w-7xl mx-auto px-4 pt-4">
        <div
          className={`rounded-2xl p-4 flex items-center gap-4 border-2 ${
            issueStats.totalErrors === 0
              ? 'bg-success/10 border-success/30 text-success'
              : 'bg-warning/10 border-warning/40 text-warning'
          }`}
        >
          <div className={`text-4xl ${issueStats.totalErrors === 0 ? '' : 'shrink-0'}`}>
            {issueStats.totalErrors === 0 ? '✅' : <AlertTriangle className="size-8" />}
          </div>
          <div className="flex-1">
            {issueStats.totalErrors === 0 ? (
              <>
                <div className="text-xl font-semibold">All Clear</div>
                <div className="text-sm opacity-80">
                  {employees.length} employee{employees.length !== 1 ? 's' : ''} tracked · {days.length} day
                  {days.length !== 1 ? 's' : ''} · 0 issues found
                </div>
              </>
            ) : (
              <>
                <div className="text-xl font-semibold">
                  ⚠️ {issueStats.totalErrors} Issue{issueStats.totalErrors !== 1 ? 's' : ''} Found
                </div>
                <div className="text-sm opacity-80">
                  Across {issueStats.employeeCount} employee{issueStats.employeeCount !== 1 ? 's' : ''} · Click any
                  flagged cell or{' '}
                  <button
                    className="underline hover:no-underline font-semibold"
                    onClick={() => setShowIssuesOnly(true)}
                  >
                    show issues only
                  </button>
                </div>
              </>
            )}
          </div>
          {issueStats.totalErrors > 0 && (
            <button className="btn btn-warning btn-sm" onClick={() => setShowIssuesOnly(true)}>
              <Filter className="size-4" /> Show Issues
            </button>
          )}
        </div>
      </div>

      {/* Time Grid */}
      <div className="p-4 max-w-7xl mx-auto overflow-x-auto">
        <div className="min-w-[800px]">
          {/* Header row */}
          <div
            className="grid gap-px bg-base-300 rounded-t-lg overflow-hidden"
            style={{ gridTemplateColumns: `180px repeat(${days.length}, minmax(52px, 1fr)) 96px 96px 96px` }}
          >
            <div className="bg-neutral text-neutral-content p-2 text-xs font-semibold flex items-center">Employee</div>
            {days.map((day) => (
              <div
                key={dateKey(toUnix(day))}
                className={`p-2 text-xs font-semibold text-center ${['Saturday', 'Sunday'].includes(formatDate(toUnix(day), 'EEEE')) ? 'bg-neutral/60 text-neutral-content/60' : 'bg-neutral text-neutral-content'}`}
              >
                <div>{formatDate(toUnix(day), 'EEE')}</div>
                <div>{formatDate(toUnix(day), 'MM/dd')}</div>
              </div>
            ))}
            <div className="bg-neutral text-neutral-content p-2 text-xs font-semibold text-center flex items-center justify-center">
              Clock Hrs
            </div>
            <div className="bg-neutral text-neutral-content p-2 text-xs font-semibold text-center flex items-center justify-center">
              Break
            </div>
            <div className="bg-neutral text-neutral-content p-2 text-xs font-semibold text-center flex items-center justify-center">
              Net Hrs
            </div>
          </div>

          {/* Employee rows */}
          {visibleEmployees.map((emp) => {
            const totals = employeeTotals[emp.id] || {
              clockMinutes: 0,
              breakMinutes: 0,
              workedMinutes: 0,
              hasActivity: false,
            };
            const hasAnyError = days.some((day) => gridData[emp.id]?.[dateKey(toUnix(day))]?.hasErrors);
            return (
              <div
                key={emp.id}
                className="grid gap-px bg-base-300"
                style={{ gridTemplateColumns: `180px repeat(${days.length}, minmax(52px, 1fr)) 96px 96px 96px` }}
              >
                <div
                  className={`bg-base-100 p-2 text-sm font-medium flex items-center truncate ${hasAnyError ? 'text-warning' : ''}`}
                >
                  <span className="truncate">{emp.name}</span>
                  {hasAnyError && <AlertTriangle className="size-3 ml-1 shrink-0 text-warning" />}
                </div>
                {days.map((day) => {
                  const dateStr = dateKey(toUnix(day));
                  const dayData = gridData[emp.id]?.[dateStr];
                  const bMin = dayData?.breakMinutes || 0;
                  const wMin = dayData?.workedMinutes || 0;
                  const hasErr = dayData?.hasErrors || false;
                  const hasActivity =
                    (dayData?.entries?.length ?? 0) > 0 ||
                    (dayData?.clockMinutes ?? 0) > 0 ||
                    (dayData?.breakMinutes ?? 0) > 0;
                  return (
                    <button
                      key={`${emp.id}-${dateStr}`}
                      onClick={() => openDetailDrawer(emp, dateStr)}
                      className={`bg-base-100 p-1 text-[11px] text-center hover:bg-primary/5 relative transition-colors ${
                        !hasActivity ? 'text-base-content/20' : hasErr ? 'bg-red-50 text-red-700' : 'text-base-content'
                      }`}
                    >
                      {hasActivity ? (
                        <div className="flex flex-col items-center leading-tight">
                          <span className="font-semibold">{formatHours(wMin) === '-' ? '0m' : formatHours(wMin)}</span>
                          {bMin > 0 && <span className="text-[9px] opacity-60">{formatHours(bMin)} brk</span>}
                        </div>
                      ) : (
                        <span className="font-semibold">-</span>
                      )}
                      {/* Error badge */}
                      {hasErr && (
                        <span className="absolute -top-0.5 -right-0.5 size-4 bg-error text-white text-[9px] font-semibold rounded-full flex items-center justify-center shadow">
                          !
                        </span>
                      )}
                    </button>
                  );
                })}
                <div className="bg-base-100 p-2 text-xs font-semibold text-center flex items-center justify-center">
                  {totals.hasActivity && formatHours(totals.clockMinutes) === '-'
                    ? '0m'
                    : formatHours(totals.clockMinutes)}
                </div>
                <div className="bg-base-100 p-2 text-xs font-semibold text-center flex items-center justify-center text-warning">
                  {totals.hasActivity && formatHours(totals.breakMinutes) === '-'
                    ? '0m'
                    : formatHours(totals.breakMinutes)}
                </div>
                <div className="bg-base-100 p-2 text-xs font-semibold text-center flex items-center justify-center text-success">
                  {totals.hasActivity && formatHours(totals.workedMinutes) === '-'
                    ? '0m'
                    : formatHours(totals.workedMinutes)}
                </div>
              </div>
            );
          })}

          {visibleEmployees.length === 0 && (
            <div className="bg-base-100 p-12 text-center text-base-content/40">
              <div className="text-4xl mb-2">👥</div>
              <p>
                {showIssuesOnly
                  ? 'No issues found for any employee in this date range! 🎉'
                  : 'No employees found for this hotel. Add employees in the Manage page.'}
              </p>
              {showIssuesOnly && (
                <button className="btn btn-outline btn-sm mt-3" onClick={() => setShowIssuesOnly(false)}>
                  Show All Employees
                </button>
              )}
            </div>
          )}
        </div>
      </div>

      {/* Detail Drawer */}
      <Drawer open={sheetOpen} onClose={() => setSheetOpen(false)}>
        <div className="flex items-center justify-between mb-1">
          <h3 className="font-semibold text-lg">{selectedDayEntries?.employeeName}</h3>
          <span className="badge badge-neutral badge-outline text-xs">{selectedDayEntries?.date}</span>
        </div>
        <p className="text-sm text-base-content/60 mb-4">
          {selectedDayEntries?.entries.filter((e) => !e.isDeleted).length
            ? `${selectedDayEntries!.entries.filter((e) => !e.isDeleted).length} entries`
            : 'No entries'}{' '}
          for this day
        </p>

        {/* Summary strip */}
        {selectedDayEntries && (
          <div className="grid grid-cols-3 gap-2 mb-4 p-3 bg-base-200 rounded-lg text-center text-xs">
            <div>
              <div className="text-base-content/50 mb-0.5">Clock Hours</div>
              <div className="font-semibold flex items-center justify-center gap-1">
                <Clock className="size-3" />{' '}
                {formatHours(gridData[manualPunchForm.employeeId]?.[selectedDayEntries.date]?.clockMinutes || 0)}
              </div>
            </div>
            <div>
              <div className="text-base-content/50 mb-0.5">Break</div>
              <div className="font-semibold flex items-center justify-center gap-1 text-warning">
                <Coffee className="size-3" />{' '}
                {formatHours(gridData[manualPunchForm.employeeId]?.[selectedDayEntries.date]?.breakMinutes || 0)}
              </div>
            </div>
            <div>
              <div className="text-base-content/50 mb-0.5">Net Worked</div>
              <div className="font-semibold flex items-center justify-center gap-1 text-success">
                <Zap className="size-3" />{' '}
                {formatHours(gridData[manualPunchForm.employeeId]?.[selectedDayEntries.date]?.workedMinutes || 0)}
              </div>
            </div>
          </div>
        )}

        {/* Issue summary section */}
        {selectedDayEntries && selectedDayEntries.errors.length > 0 && (
          <div className="mb-4 p-3 bg-error/10 border border-error/20 rounded-lg">
            <div className="flex items-center gap-2 mb-2">
              <AlertTriangle className="size-4 text-error" />
              <span className="font-semibold text-sm text-error">Issues Found</span>
            </div>
            <ul className="space-y-1">
              {selectedDayEntries.errors.map((err) => (
                <li key={err} className="text-xs text-error/80 flex items-start gap-1.5">
                  <span className="mt-0.5">•</span>
                  <span>{err}</span>
                </li>
              ))}
            </ul>
          </div>
        )}

        {/* Audit timeline */}
        <div className="space-y-2 mb-4">
          <h4 className="text-xs font-semibold text-base-content/40 uppercase tracking-wider">Punch Timeline</h4>
          {(selectedDayEntries?.entries ?? [])
            .toSorted((a, b) => a.timestamp - b.timestamp)
            .map((entry, i, arr) => {
              const isEditing = editingEntryIds.has(entry.id);
              const activeEntries = arr.filter((e) => !e.isDeleted);
              const idx = activeEntries.indexOf(entry);
              const forceOv = editingOverride[entry.id] || false;
              return (
                <div key={entry.id} className={`flex gap-3 items-start ${entry.isDeleted ? 'opacity-40' : ''}`}>
                  {!entry.isDeleted && (
                    <div className="flex flex-col items-center">
                      <div
                        className={`size-3 rounded-full border-2 border-base-100 shadow shrink-0 ${entryDotColors[entry.type]}`}
                      />
                      {idx < activeEntries.length - 1 && idx >= 0 && (
                        <div className="w-0.5 flex-1 bg-base-200 min-h-[24px]" />
                      )}
                    </div>
                  )}
                  <div className={`flex-1 ${entry.isDeleted ? 'bg-base-200/50' : 'bg-base-200'} rounded-lg p-3`}>
                    <div className="flex items-center justify-between">
                      <div className="flex items-center gap-2">
                        <span className="text-sm">{entryIcons[entry.type]}</span>
                        <span className={`font-semibold text-sm ${entry.isDeleted ? 'line-through' : ''}`}>
                          {entryLabels[entry.type] || entry.type}
                        </span>
                        {isEditing ? (
                          <div className="flex flex-col gap-1 ml-2">
                            <div className="flex items-center gap-1">
                              <input
                                type="datetime-local"
                                value={editTimestamps[entry.id] || ''}
                                onChange={(e) => setEditTimestamps((prev) => ({ ...prev, [entry.id]: e.target.value }))}
                                className="input input-bordered input-xs w-44"
                              />
                              <button
                                className="btn btn-ghost btn-square btn-xs text-success"
                                onClick={() => saveTimestamp(entry.id, forceOv)}
                              >
                                <Check className="size-3" />
                              </button>
                              <button
                                className="btn btn-ghost btn-square btn-xs"
                                onClick={() => cancelEditing(entry.id)}
                              >
                                <X className="size-3" />
                              </button>
                            </div>
                            <label className="flex items-center gap-1 text-xs text-base-content/60 cursor-pointer select-none">
                              <input
                                type="checkbox"
                                className="checkbox checkbox-xs"
                                checked={forceOv}
                                onChange={(e) =>
                                  setEditingOverride((prev) => ({ ...prev, [entry.id]: e.target.checked }))
                                }
                              />
                              Force override
                            </label>
                          </div>
                        ) : (
                          <>
                            <span
                              className={`text-xs ${entry.isDeleted ? 'text-base-content/30' : 'text-base-content/50'} ml-1`}
                            >
                              {formatTime(entry.timestamp, 'MMM d, h:mm a')}
                            </span>
                            <button
                              className="btn btn-ghost btn-square btn-xs"
                              onClick={() => startEditingTimestamp(entry)}
                            >
                              <Pencil className="size-3 text-base-content/40" />
                            </button>
                          </>
                        )}
                      </div>
                      <div className="flex gap-1">
                        {entry.isDeleted ? (
                          <button className="btn btn-ghost btn-xs" onClick={() => handleRestoreEntry(entry.id)}>
                            <Ban className="size-4 text-base-content/40" /> Restore
                          </button>
                        ) : (
                          <button
                            className="btn btn-ghost btn-xs text-error"
                            onClick={() => handleDeleteEntry(entry.id)}
                          >
                            <Trash2 className="size-4" />
                          </button>
                        )}
                      </div>
                    </div>
                    {entry.photoBase64 && !entry.isDeleted && (
                      <Image
                        src={entry.photoBase64}
                        alt="Punch"
                        width={96}
                        height={72}
                        unoptimized
                        className="mt-2 w-24 h-18 object-cover rounded-lg border"
                      />
                    )}
                  </div>
                </div>
              );
            })}
          {!selectedDayEntries?.entries?.length && (
            <p className="text-center py-4 text-base-content/40 text-sm">No punches recorded for this day</p>
          )}
        </div>

        <div className="divider my-4" />

        {/* Manual Punch Form */}
        <div>
          <h4 className="font-semibold text-sm mb-3 flex items-center gap-2">
            <Plus className="size-4" /> Add Manual Punch
          </h4>

          {/* Error display */}
          {manualPunchError && (
            <div className="alert alert-error mb-3 text-sm py-2">
              <AlertTriangle className="size-4" /> {manualPunchError}
            </div>
          )}

          <div className="space-y-3">
            <div>
              <label className="label" htmlFor="manual-punch-type">
                <span className="label-text text-xs">Type</span>
              </label>
              <select
                className="select select-bordered w-full select-sm"
                value={manualPunchForm?.type || ''}
                id="manual-punch-type"
                onChange={(e) => setManualPunchForm((prev) => (prev ? { ...prev, type: e.target.value } : prev))}
              >
                <option value="IN">Clock In</option>
                <option value="OUT">Clock Out</option>
                <option value="BREAK_OUT">Break Start</option>
                <option value="BREAK_IN">Break End</option>
              </select>
            </div>
            <div>
              <label className="label" htmlFor="manual-punch-timestamp">
                <span className="label-text text-xs">Date &amp; Time</span>
              </label>
              <input
                type="datetime-local"
                className="input input-bordered w-full input-sm"
                id="manual-punch-timestamp"
                value={manualPunchForm?.timestamp?.slice(0, 16) || ''}
                onChange={(e) => setManualPunchForm((prev) => (prev ? { ...prev, timestamp: e.target.value } : prev))}
              />
            </div>
            <label className="flex items-center gap-2 cursor-pointer select-none">
              <input
                type="checkbox"
                className="checkbox checkbox-sm"
                checked={manualPunchForm?.forceOverride || false}
                onChange={(e) =>
                  setManualPunchForm((prev) => (prev ? { ...prev, forceOverride: e.target.checked } : prev))
                }
              />
              <span className="text-sm">Force override (skip state machine check)</span>
            </label>
            <button
              className="btn btn-primary w-full btn-sm"
              onClick={handleAddManualPunch}
              disabled={!manualPunchForm?.type || !manualPunchForm?.timestamp}
            >
              Add Punch
            </button>
          </div>
        </div>
      </Drawer>
    </div>
  );
}
