"use client";

import { useMemo, useState } from "react";
import { Card, CardContent } from "@/components/ui/card";
import { Badge } from "@/components/ui/badge";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import { Kpi, KpiStrip } from "@/components/ui/kpi";
import { EmptyState } from "@/components/ui/empty-state";
import { Tabs, TabsList, TabsTrigger, TabsContent } from "@/components/ui/tabs";
import { useAlertConfirm } from "@/components/ui/alert-dialog";
import { useLocalStorage } from "@/lib/hooks/use-local-storage";
import {
  accruePto,
  computeRequestHours,
  newRequestId,
  resolveRule,
  type PtoRequest,
  type PtoRule,
  type PtoStatus,
} from "@/lib/hr/pto";
import { ALL_ORGANIZATIONS } from "@/lib/sag/entities";
import type { Employee } from "@/lib/sag/employees-seed";
import { formatDate } from "@/lib/utils";

// ──────────────────────────────────────────────────────────────────────────
// LocalStorage keys
// ──────────────────────────────────────────────────────────────────────────

const KEY_EMPLOYEES = "sag.hr.employees";
const KEY_RULES = "sag.hr.pto_rules"; // PtoRule[] — overrides on top of DEFAULT_PTO_RULES
const KEY_REQUESTS = "sag.hr.pto_requests"; // PtoRequest[]

// TODO: wire to authenticated user once /app/auth is live.
const APPROVER_NAME = "Glenn";

type TabId = "balances" | "requests" | "policies";

const TABS: { id: TabId; label: string; icon: string }[] = [
  { id: "balances", label: "Balances", icon: "🌴" },
  { id: "requests", label: "Requests", icon: "📨" },
  { id: "policies", label: "Policies", icon: "📜" },
];

function todayIso(): string {
  return new Date().toISOString().slice(0, 10);
}

// ──────────────────────────────────────────────────────────────────────────
// Main component
// ──────────────────────────────────────────────────────────────────────────

export function PtoTracker() {
  const [employees] = useLocalStorage<Employee[]>(KEY_EMPLOYEES, []);
  const [ruleOverrides, setRuleOverrides] = useLocalStorage<PtoRule[]>(
    KEY_RULES,
    []
  );
  const [requests, setRequests] = useLocalStorage<PtoRequest[]>(KEY_REQUESTS, []);
  const [tab, setTab] = useState<TabId>("balances");
  const [requestingFor, setRequestingFor] = useState<string | null>(null);
  const { confirm: confirmAlert, AlertConfirmPortal } = useAlertConfirm();

  const asOf = todayIso();

  const ruleByEntity = useMemo(() => {
    const m = new Map<string, PtoRule>();
    for (const org of ALL_ORGANIZATIONS) {
      m.set(org.slug, resolveRule(org.slug, ruleOverrides));
    }
    return m;
  }, [ruleOverrides]);

  const employeeAccruals = useMemo(() => {
    return employees.map((e) => {
      const rule =
        ruleByEntity.get(e.organizationSlug) ??
        resolveRule(e.organizationSlug, ruleOverrides);
      const accrual = accruePto(e, rule, asOf, requests);
      return { employee: e, rule, ...accrual };
    });
  }, [employees, ruleByEntity, ruleOverrides, requests, asOf]);

  const pendingCount = useMemo(
    () => requests.filter((r) => r.status === "pending").length,
    [requests]
  );

  const stats = useMemo(() => {
    let totalEarned = 0;
    let totalUsed = 0;
    let totalPending = 0;
    for (const r of employeeAccruals) {
      totalEarned += r.earned;
      totalUsed += r.used;
      totalPending += r.pending;
    }
    return {
      employees: employees.length,
      earned: totalEarned,
      used: totalUsed,
      pending: totalPending,
    };
  }, [employeeAccruals, employees.length]);

  function submitRequest(req: PtoRequest) {
    setRequests((prev) => [req, ...prev]);
    setRequestingFor(null);
  }

  function decide(id: string, status: Extract<PtoStatus, "approved" | "denied">) {
    const verb = status === "approved" ? "Approve" : "Deny";
    const note = window.prompt(
      `${verb} request — add a note (optional):`,
      ""
    );
    // null = the user pressed Cancel on the prompt.
    if (note === null) return;
    setRequests((prev) =>
      prev.map((r) =>
        r.id === id
          ? {
              ...r,
              status,
              decidedAt: new Date().toISOString(),
              decidedBy: APPROVER_NAME,
              decisionNote: note.trim() || undefined,
            }
          : r
      )
    );
  }

  async function cancelRequest(id: string) {
    const ok = await confirmAlert({
      title: "Cancel this PTO request?",
      description: "It will be marked cancelled.",
      actionLabel: "Cancel request",
      destructive: true,
    });
    if (!ok) return;
    setRequests((prev) =>
      prev.map((r) =>
        r.id === id
          ? {
              ...r,
              status: "cancelled",
              decidedAt: new Date().toISOString(),
              decidedBy: APPROVER_NAME,
            }
          : r
      )
    );
  }

  async function deleteRequest(id: string) {
    const ok = await confirmAlert({
      title: "Delete this request permanently?",
      description: "This permanently removes the record. Cannot be undone.",
      actionLabel: "Delete",
      destructive: true,
    });
    if (!ok) return;
    setRequests((prev) => prev.filter((r) => r.id !== id));
  }

  function saveRule(rule: PtoRule) {
    setRuleOverrides((prev) => {
      const others = prev.filter((r) => r.entitySlug !== rule.entitySlug);
      return [...others, rule];
    });
  }

  function resetRule(entitySlug: string) {
    setRuleOverrides((prev) => prev.filter((r) => r.entitySlug !== entitySlug));
  }

  return (
    <>
    <div className="space-y-6">
      {/* ─── Header + KPI strip ───────────────────────────────────────── */}
      <section className="flex items-start justify-between gap-3 flex-wrap">
        <div className="min-w-0">
          <h2 className="text-xl font-semibold">PTO across the portfolio</h2>
          <p className="text-sm text-muted-foreground">
            {pendingCount === 0
              ? "No pending requests."
              : `${pendingCount} pending request${pendingCount === 1 ? "" : "s"} awaiting decision.`}
          </p>
        </div>
        {pendingCount > 0 && (
          <Badge variant="warning">
            {pendingCount} pending
          </Badge>
        )}
      </section>

      <KpiStrip cols={4}>
        <Kpi label="Employees" value={String(stats.employees)} />
        <Kpi label="Total accrued (hrs)" value={fmtHours(stats.earned)} />
        <Kpi label="Used (hrs)" value={fmtHours(stats.used)} />
        <Kpi
          label="Pending (hrs)"
          value={fmtHours(stats.pending)}
          tone={stats.pending > 0 ? "amber" : "neutral"}
        />
      </KpiStrip>

      {/* ─── Tabs ─────────────────────────────────────────────────────── */}
      <Tabs value={tab} onValueChange={(v) => setTab(v as TabId)}>
        <TabsList className="flex-wrap">
          {TABS.map((t) => (
            <TabsTrigger key={t.id} value={t.id}>
              <span className="inline-flex items-center gap-1.5">
                <span>{t.icon}</span>
                {t.label}
                {t.id === "requests" && pendingCount > 0 && (
                  <span className="ml-1 inline-flex items-center justify-center min-w-[1.25rem] h-5 px-1 text-[10px] font-semibold rounded-full bg-yellow-200 text-yellow-900 dark:bg-yellow-900/50 dark:text-yellow-100">
                    {pendingCount}
                  </span>
                )}
              </span>
            </TabsTrigger>
          ))}
        </TabsList>

        <TabsContent value="balances">
          <BalancesTab
            rows={employeeAccruals}
            requestingFor={requestingFor}
            onStartRequest={(id) => setRequestingFor(id)}
            onCancelRequest={() => setRequestingFor(null)}
            onSubmitRequest={submitRequest}
          />
        </TabsContent>

        <TabsContent value="requests">
          <RequestsTab
            requests={requests}
            employees={employees}
            onApprove={(id) => decide(id, "approved")}
            onDeny={(id) => decide(id, "denied")}
            onCancel={cancelRequest}
            onDelete={deleteRequest}
          />
        </TabsContent>

        <TabsContent value="policies">
          <PoliciesTab
            ruleOverrides={ruleOverrides}
            employees={employees}
            onSaveRule={saveRule}
            onResetRule={resetRule}
          />
        </TabsContent>
      </Tabs>

      <p className="text-xs text-muted-foreground">
        Data saved locally in this browser under{" "}
        <code className="font-mono">{KEY_REQUESTS}</code> /{" "}
        <code className="font-mono">{KEY_RULES}</code>. Once Supabase is wired
        for HR, this will sync per-entity for managers and HR.
      </p>
    </div>
    <AlertConfirmPortal />
    </>
  );
}

// ──────────────────────────────────────────────────────────────────────────
// Balances tab
// ──────────────────────────────────────────────────────────────────────────

type BalanceRow = {
  employee: Employee;
  rule: PtoRule;
  earned: number;
  used: number;
  balance: number;
  pending: number;
};

function BalancesTab({
  rows,
  requestingFor,
  onStartRequest,
  onCancelRequest,
  onSubmitRequest,
}: {
  rows: BalanceRow[];
  requestingFor: string | null;
  onStartRequest: (employeeId: string) => void;
  onCancelRequest: () => void;
  onSubmitRequest: (req: PtoRequest) => void;
}) {
  if (rows.length === 0) {
    return (
      <EmptyState
        icon="🌴"
        title="No employees yet"
        description="Add employees in the HR directory to start tracking PTO balances."
      />
    );
  }

  return (
    <div className="rounded-md border bg-card overflow-x-auto">
      <table className="w-full text-sm min-w-[720px]">
        <thead className="section-label border-b">
          <tr>
            <th className="px-3 py-2 text-left">Name</th>
            <th className="px-3 py-2 text-left">Entity</th>
            <th className="px-3 py-2 text-left">Start date</th>
            <th className="px-3 py-2 text-right">Earned</th>
            <th className="px-3 py-2 text-right">Used</th>
            <th className="px-3 py-2 text-right">Pending</th>
            <th className="px-3 py-2 text-right">Balance</th>
            <th className="px-3 py-2 text-right">Action</th>
          </tr>
        </thead>
        <tbody>
          {rows.map((r) => {
            const org = ALL_ORGANIZATIONS.find(
              (o) => o.slug === r.employee.organizationSlug
            );
            const isRequesting = requestingFor === r.employee.id;
            return (
              <Row
                key={r.employee.id}
                row={r}
                orgEmoji={org?.emoji ?? "🏢"}
                orgName={org?.name ?? r.employee.organizationSlug}
                isRequesting={isRequesting}
                onStartRequest={() => onStartRequest(r.employee.id)}
                onCancelRequest={onCancelRequest}
                onSubmitRequest={onSubmitRequest}
              />
            );
          })}
        </tbody>
      </table>
    </div>
  );
}

function Row({
  row,
  orgEmoji,
  orgName,
  isRequesting,
  onStartRequest,
  onCancelRequest,
  onSubmitRequest,
}: {
  row: BalanceRow;
  orgEmoji: string;
  orgName: string;
  isRequesting: boolean;
  onStartRequest: () => void;
  onCancelRequest: () => void;
  onSubmitRequest: (req: PtoRequest) => void;
}) {
  const e = row.employee;
  return (
    <>
      <tr className="border-b last:border-0">
        <td className="px-3 py-2 font-medium">{e.fullName}</td>
        <td className="px-3 py-2">
          <span className="inline-flex items-center gap-1 text-xs text-muted-foreground">
            {orgEmoji} {orgName}
          </span>
        </td>
        <td className="px-3 py-2 font-mono text-xs text-muted-foreground">
          {e.startDate ? formatDate(e.startDate) : "—"}
        </td>
        <td className="px-3 py-2 text-right tabular-nums">{fmtHours(row.earned)}</td>
        <td className="px-3 py-2 text-right tabular-nums">{fmtHours(row.used)}</td>
        <td className="px-3 py-2 text-right tabular-nums">
          {row.pending > 0 ? (
            <span className="text-yellow-700 dark:text-yellow-400">
              {fmtHours(row.pending)}
            </span>
          ) : (
            fmtHours(row.pending)
          )}
        </td>
        <td className="px-3 py-2 text-right tabular-nums font-semibold">
          {fmtHours(row.balance)}
        </td>
        <td className="px-3 py-2 text-right">
          <Button
            size="sm"
            variant={isRequesting ? "outline" : "brand"}
            onClick={isRequesting ? onCancelRequest : onStartRequest}
          >
            {isRequesting ? "Cancel" : "Request PTO"}
          </Button>
        </td>
      </tr>
      {isRequesting && (
        <tr>
          <td colSpan={8} className="px-3 py-3 bg-muted/30">
            <RequestForm
              employee={e}
              balance={row.balance}
              onCancel={onCancelRequest}
              onSubmit={onSubmitRequest}
            />
          </td>
        </tr>
      )}
    </>
  );
}

// ──────────────────────────────────────────────────────────────────────────
// Inline request form
// ──────────────────────────────────────────────────────────────────────────

function RequestForm({
  employee,
  balance,
  onCancel,
  onSubmit,
}: {
  employee: Employee;
  balance: number;
  onCancel: () => void;
  onSubmit: (req: PtoRequest) => void;
}) {
  const [startDate, setStartDate] = useState("");
  const [endDate, setEndDate] = useState("");
  const [hoursOverride, setHoursOverride] = useState<string>("");
  const [reason, setReason] = useState("");
  const [autoHours, setAutoHours] = useState(true);

  const computedHours = useMemo(
    () => computeRequestHours(startDate, endDate),
    [startDate, endDate]
  );
  const effectiveHours = autoHours
    ? computedHours
    : Number.isFinite(parseFloat(hoursOverride))
      ? parseFloat(hoursOverride)
      : 0;

  const overBalance = effectiveHours > balance;

  function submit(ev: React.FormEvent) {
    ev.preventDefault();
    if (!startDate || !endDate || effectiveHours <= 0) return;
    onSubmit({
      id: newRequestId(),
      employeeId: employee.id,
      startDate,
      endDate,
      hoursRequested: effectiveHours,
      reason: reason.trim(),
      status: "pending",
      submittedAt: new Date().toISOString(),
    });
    setStartDate("");
    setEndDate("");
    setHoursOverride("");
    setReason("");
  }

  return (
    <form onSubmit={submit} className="grid gap-3 md:grid-cols-4">
      <Field label="Start date">
        <Input
          type="date"
          value={startDate}
          onChange={(ev) => setStartDate(ev.target.value)}
          required
        />
      </Field>
      <Field label="End date">
        <Input
          type="date"
          value={endDate}
          onChange={(ev) => setEndDate(ev.target.value)}
          required
        />
      </Field>
      <Field label="Hours (8/weekday auto)">
        <div className="flex items-center gap-2">
          <Input
            type="number"
            step="0.5"
            min="0"
            value={autoHours ? String(computedHours || "") : hoursOverride}
            onChange={(ev) => {
              setAutoHours(false);
              setHoursOverride(ev.target.value);
            }}
            placeholder="0"
          />
          {!autoHours && (
            <button
              type="button"
              className="text-[10px] underline text-muted-foreground"
              onClick={() => {
                setAutoHours(true);
                setHoursOverride("");
              }}
            >
              auto
            </button>
          )}
        </div>
      </Field>
      <Field label="Reason">
        <Input
          value={reason}
          onChange={(ev) => setReason(ev.target.value)}
          placeholder="Vacation, sick, personal..."
        />
      </Field>
      <div className="md:col-span-4 flex items-center justify-between gap-2 flex-wrap">
        <div className="text-xs text-muted-foreground">
          {effectiveHours > 0 && (
            <>
              Requesting <span className="font-semibold text-foreground">{fmtHours(effectiveHours)} hrs</span>
              {" "}· balance {fmtHours(balance)} hrs
              {overBalance && (
                <span className="ml-2 text-destructive">
                  (exceeds balance — will need approval)
                </span>
              )}
            </>
          )}
        </div>
        <div className="flex items-center gap-2 ml-auto">
          <Button variant="ghost" size="sm" type="button" onClick={onCancel}>
            Cancel
          </Button>
          <Button
            variant="brand"
            size="sm"
            type="submit"
            disabled={!startDate || !endDate || effectiveHours <= 0}
          >
            Submit request
          </Button>
        </div>
      </div>
    </form>
  );
}

// ──────────────────────────────────────────────────────────────────────────
// Requests tab
// ──────────────────────────────────────────────────────────────────────────

const STATUS_TONE: Record<PtoStatus, "outline" | "warning" | "success" | "destructive"> = {
  pending: "warning",
  approved: "success",
  denied: "destructive",
  cancelled: "outline",
};

const STATUS_LABEL: Record<PtoStatus, string> = {
  pending: "Pending",
  approved: "Approved",
  denied: "Denied",
  cancelled: "Cancelled",
};

function RequestsTab({
  requests,
  employees,
  onApprove,
  onDeny,
  onCancel,
  onDelete,
}: {
  requests: PtoRequest[];
  employees: Employee[];
  onApprove: (id: string) => void;
  onDeny: (id: string) => void;
  onCancel: (id: string) => void;
  onDelete: (id: string) => void;
}) {
  const sorted = useMemo(
    () =>
      [...requests].sort((a, b) => b.submittedAt.localeCompare(a.submittedAt)),
    [requests]
  );

  if (sorted.length === 0) {
    return (
      <EmptyState
        icon="📨"
        title="No PTO requests yet"
        description="Submit one from the Balances tab to start the workflow."
      />
    );
  }

  return (
    <div className="rounded-md border bg-card overflow-x-auto">
      <table className="w-full text-sm min-w-[720px]">
        <thead className="section-label border-b">
          <tr>
            <th className="px-3 py-2 text-left">Submitted</th>
            <th className="px-3 py-2 text-left">Employee</th>
            <th className="px-3 py-2 text-left">Window</th>
            <th className="px-3 py-2 text-right">Hours</th>
            <th className="px-3 py-2 text-left">Reason</th>
            <th className="px-3 py-2 text-left">Status</th>
            <th className="px-3 py-2 text-left">Decision</th>
            <th className="px-3 py-2 text-right">Actions</th>
          </tr>
        </thead>
        <tbody>
          {sorted.map((r) => {
            const emp = employees.find((e) => e.id === r.employeeId);
            const org = emp
              ? ALL_ORGANIZATIONS.find((o) => o.slug === emp.organizationSlug)
              : undefined;
            return (
              <tr
                key={r.id}
                className={`border-b last:border-0 ${
                  r.status === "pending" ? "bg-yellow-50/40 dark:bg-yellow-950/10" : ""
                }`}
              >
                <td className="px-3 py-2 font-mono text-xs text-muted-foreground">
                  {formatDate(r.submittedAt)}
                </td>
                <td className="px-3 py-2">
                  <div className="text-sm font-medium">
                    {emp?.fullName ?? "—"}
                  </div>
                  {org && (
                    <div className="text-[11px] text-muted-foreground inline-flex items-center gap-1">
                      {org.emoji} {org.name}
                    </div>
                  )}
                </td>
                <td className="px-3 py-2 font-mono text-xs">
                  {formatDate(r.startDate)} → {formatDate(r.endDate)}
                </td>
                <td className="px-3 py-2 text-right tabular-nums font-medium">
                  {fmtHours(r.hoursRequested)}
                </td>
                <td className="px-3 py-2 text-xs text-muted-foreground max-w-[180px] truncate">
                  {r.reason || "—"}
                </td>
                <td className="px-3 py-2">
                  <Badge variant={STATUS_TONE[r.status]}>
                    {STATUS_LABEL[r.status]}
                  </Badge>
                </td>
                <td className="px-3 py-2 text-xs text-muted-foreground">
                  {r.decidedAt ? (
                    <div>
                      <div>
                        {r.decidedBy ?? "—"} ·{" "}
                        <span className="font-mono">{formatDate(r.decidedAt)}</span>
                      </div>
                      {r.decisionNote && (
                        <div className="italic text-[11px] mt-0.5">
                          &ldquo;{r.decisionNote}&rdquo;
                        </div>
                      )}
                    </div>
                  ) : (
                    "—"
                  )}
                </td>
                <td className="px-3 py-2 text-right">
                  <div className="inline-flex items-center gap-1 flex-wrap justify-end">
                    {r.status === "pending" && (
                      <>
                        <Button
                          size="sm"
                          variant="brand"
                          onClick={() => onApprove(r.id)}
                        >
                          Approve
                        </Button>
                        <Button
                          size="sm"
                          variant="outline"
                          onClick={() => onDeny(r.id)}
                        >
                          Deny
                        </Button>
                        <Button
                          size="sm"
                          variant="ghost"
                          onClick={() => onCancel(r.id)}
                        >
                          Cancel
                        </Button>
                      </>
                    )}
                    {r.status !== "pending" && (
                      <Button
                        size="sm"
                        variant="ghost"
                        onClick={() => onDelete(r.id)}
                      >
                        ×
                      </Button>
                    )}
                  </div>
                </td>
              </tr>
            );
          })}
        </tbody>
      </table>
    </div>
  );
}

// ──────────────────────────────────────────────────────────────────────────
// Policies tab
// ──────────────────────────────────────────────────────────────────────────

function PoliciesTab({
  ruleOverrides,
  employees,
  onSaveRule,
  onResetRule,
}: {
  ruleOverrides: PtoRule[];
  employees: Employee[];
  onSaveRule: (rule: PtoRule) => void;
  onResetRule: (entitySlug: string) => void;
}) {
  const [showAll, setShowAll] = useState(false);

  const entitiesWithEmployees = useMemo(() => {
    const set = new Set<string>();
    for (const e of employees) set.add(e.organizationSlug);
    return set;
  }, [employees]);

  const visibleOrgs = useMemo(() => {
    if (showAll) return ALL_ORGANIZATIONS;
    return ALL_ORGANIZATIONS.filter((o) => entitiesWithEmployees.has(o.slug));
  }, [showAll, entitiesWithEmployees]);

  return (
    <div className="space-y-3">
      <Card>
        <CardContent className="p-4 flex items-center flex-wrap gap-2">
          <div className="text-xs text-muted-foreground">
            Showing {showAll ? "all entities" : "entities with employees"} ·{" "}
            <button
              type="button"
              className="underline hover:text-foreground"
              onClick={() => setShowAll((v) => !v)}
            >
              {showAll ? "Hide empty" : "Show all entities"}
            </button>
          </div>
          <span className="text-xs text-muted-foreground ml-auto">
            {visibleOrgs.length} entit{visibleOrgs.length === 1 ? "y" : "ies"}
          </span>
        </CardContent>
      </Card>

      {visibleOrgs.length === 0 ? (
        <EmptyState
          icon="📜"
          title="No entities with employees"
          description={`Toggle "Show all entities" above to edit policies for entities that don't have employees yet.`}
        />
      ) : (
        <div className="rounded-md border bg-card overflow-x-auto">
          <table className="w-full text-sm min-w-[720px]">
            <thead className="section-label border-b">
              <tr>
                <th className="px-3 py-2 text-left">Entity</th>
                <th className="px-3 py-2 text-right">Hrs / year</th>
                <th className="px-3 py-2 text-right">Rollover cap</th>
                <th className="px-3 py-2 text-right">Waiting (days)</th>
                <th className="px-3 py-2 text-left">Policy</th>
                <th className="px-3 py-2 text-left">Source</th>
                <th className="px-3 py-2 text-right">Actions</th>
              </tr>
            </thead>
            <tbody>
              {visibleOrgs.map((org) => {
                const isOverride = ruleOverrides.some(
                  (r) => r.entitySlug === org.slug
                );
                const rule = resolveRule(org.slug, ruleOverrides);
                const empCount = employees.filter(
                  (e) => e.organizationSlug === org.slug
                ).length;
                return (
                  <PolicyRow
                    key={org.slug}
                    orgEmoji={org.emoji ?? "🏢"}
                    orgName={org.name}
                    employeeCount={empCount}
                    rule={rule}
                    isOverride={isOverride}
                    onSave={onSaveRule}
                    onReset={() => onResetRule(org.slug)}
                  />
                );
              })}
            </tbody>
          </table>
        </div>
      )}
    </div>
  );
}

function PolicyRow({
  orgEmoji,
  orgName,
  employeeCount,
  rule,
  isOverride,
  onSave,
  onReset,
}: {
  orgEmoji: string;
  orgName: string;
  employeeCount: number;
  rule: PtoRule;
  isOverride: boolean;
  onSave: (rule: PtoRule) => void;
  onReset: () => void;
}) {
  const [editing, setEditing] = useState(false);
  const [hoursPerYear, setHoursPerYear] = useState(String(rule.hoursPerYear));
  const [rollover, setRollover] = useState(String(rule.rolloverCapHours));
  const [waiting, setWaiting] = useState(String(rule.waitingPeriodDays));
  const [policy, setPolicy] = useState(rule.policy);

  function startEdit() {
    setHoursPerYear(String(rule.hoursPerYear));
    setRollover(String(rule.rolloverCapHours));
    setWaiting(String(rule.waitingPeriodDays));
    setPolicy(rule.policy);
    setEditing(true);
  }

  function save() {
    const hpy = parseFloat(hoursPerYear);
    const ro = parseFloat(rollover);
    const wp = parseFloat(waiting);
    if (
      !Number.isFinite(hpy) ||
      !Number.isFinite(ro) ||
      !Number.isFinite(wp) ||
      hpy < 0 ||
      ro < 0 ||
      wp < 0
    ) {
      window.alert("Hours, rollover, and waiting must be non-negative numbers.");
      return;
    }
    onSave({
      entitySlug: rule.entitySlug,
      hoursPerYear: hpy,
      rolloverCapHours: ro,
      waitingPeriodDays: wp,
      policy: policy.trim() || rule.policy,
    });
    setEditing(false);
  }

  if (editing) {
    return (
      <tr className="border-b last:border-0 bg-muted/30">
        <td className="px-3 py-2">
          <div className="inline-flex items-center gap-1">
            {orgEmoji} {orgName}
          </div>
          {employeeCount > 0 && (
            <div className="text-[10px] text-muted-foreground tabular-nums">
              {employeeCount} employee{employeeCount === 1 ? "" : "s"}
            </div>
          )}
        </td>
        <td className="px-3 py-2">
          <Input
            type="number"
            step="1"
            min="0"
            value={hoursPerYear}
            onChange={(e) => setHoursPerYear(e.target.value)}
            className="h-8 text-right"
          />
        </td>
        <td className="px-3 py-2">
          <Input
            type="number"
            step="1"
            min="0"
            value={rollover}
            onChange={(e) => setRollover(e.target.value)}
            className="h-8 text-right"
          />
        </td>
        <td className="px-3 py-2">
          <Input
            type="number"
            step="1"
            min="0"
            value={waiting}
            onChange={(e) => setWaiting(e.target.value)}
            className="h-8 text-right"
          />
        </td>
        <td className="px-3 py-2" colSpan={2}>
          <Input
            value={policy}
            onChange={(e) => setPolicy(e.target.value)}
            className="h-8"
            placeholder="Policy description"
          />
        </td>
        <td className="px-3 py-2 text-right">
          <div className="inline-flex items-center gap-1">
            <Button size="sm" variant="brand" onClick={save}>
              Save
            </Button>
            <Button size="sm" variant="ghost" onClick={() => setEditing(false)}>
              Cancel
            </Button>
          </div>
        </td>
      </tr>
    );
  }

  return (
    <tr className="border-b last:border-0">
      <td className="px-3 py-2">
        <div className="inline-flex items-center gap-1">
          {orgEmoji} {orgName}
        </div>
        {employeeCount > 0 && (
          <div className="text-[10px] text-muted-foreground tabular-nums">
            {employeeCount} employee{employeeCount === 1 ? "" : "s"}
          </div>
        )}
      </td>
      <td className="px-3 py-2 text-right tabular-nums">{rule.hoursPerYear}</td>
      <td className="px-3 py-2 text-right tabular-nums">{rule.rolloverCapHours}</td>
      <td className="px-3 py-2 text-right tabular-nums">{rule.waitingPeriodDays}</td>
      <td className="px-3 py-2 text-xs text-muted-foreground max-w-[280px]">
        {rule.policy}
      </td>
      <td className="px-3 py-2">
        {isOverride ? (
          <Badge variant="info">Override</Badge>
        ) : (
          <Badge variant="outline">Default</Badge>
        )}
      </td>
      <td className="px-3 py-2 text-right">
        <div className="inline-flex items-center gap-1">
          <Button size="sm" variant="outline" onClick={startEdit}>
            Edit
          </Button>
          {isOverride && (
            <Button size="sm" variant="ghost" onClick={onReset}>
              Reset
            </Button>
          )}
        </div>
      </td>
    </tr>
  );
}

// ──────────────────────────────────────────────────────────────────────────
// Shared primitives
// ──────────────────────────────────────────────────────────────────────────

function Field({
  label,
  children,
  className,
}: {
  label: string;
  children: React.ReactNode;
  className?: string;
}) {
  return (
    <div className={className}>
      <label className="text-xs text-muted-foreground">{label}</label>
      <div className="mt-1">{children}</div>
    </div>
  );
}


function fmtHours(n: number): string {
  return n.toFixed(1);
}
