"use client";

import * as React from "react";
import Link from "next/link";
import { useRouter, usePathname } from "next/navigation";
import { ChevronDown, Monitor, Smartphone, Tablet, X } from "lucide-react";
import { cn, safeJson } from "@/lib/utils";
import { Button } from "@/components/ui/button";
import { Input, SearchInput } from "@/components/ui/input";
import { FilterSelect } from "@/components/ui/data-table";
import { Avatar } from "@/components/ui/primitives";
import { Badge, StatusBadge } from "@/components/ui/badge";
import { EmptyState } from "@/components/ui/states";
import { fmtDateTime } from "@/lib/dates";
import { AUDIT_ACTIONS } from "@/lib/audit-actions";
import { describeActivity, hrefFor } from "@/components/dashboard/activity-feed";

export interface AuditRow {
  id: string;
  code: string | null;
  action: string;
  module: string;
  severity: string;
  userName: string;
  userId: string | null;
  roleKey: string;
  entityType: string | null;
  entityId: string | null;
  entityLabel: string | null;
  previousValue: string | null;
  newValue: string | null;
  reason: string | null;
  apartmentId: string | null;
  reservationId: string | null;
  customerId: string | null;
  ipAddress: string | null;
  device: string | null;
  browser: string | null;
  createdAt: string;
}

const MODULE_TONE: Record<string, "brand" | "info" | "warning" | "negative" | "neutral" | "accent" | "positive"> = { auth: "neutral", reservations: "brand", customers: "info", apartments: "accent", payments: "positive", expenses: "warning", commissions: "info", workers: "negative", settings: "negative", cleaning: "warning", tasks: "info", maintenance: "negative", documents: "neutral" };

export function AuditTable({ rows, workers, apartments, modules, entityTypes = [], actions, filters, focusId, timezone }: { rows: AuditRow[]; workers: { id: string; fullName: string }[]; apartments: { id: string; code: string }[]; modules: string[]; entityTypes?: string[]; actions: string[]; filters: Record<string, string | undefined>; focusId?: string; timezone: string }) {
  const router = useRouter();
  const pathname = usePathname();
  const [q, setQ] = React.useState(filters.q ?? "");
  const [open, setOpen] = React.useState<string | null>(focusId ?? null);
  React.useEffect(() => {
    if (focusId) document.getElementById(`evt-${focusId}`)?.scrollIntoView({ block: "center" });
  }, [focusId]);
  const set = (k: string, v: string) => {
    const sp = new URLSearchParams();
    for (const [kk, vv] of Object.entries({ ...filters, [k]: v })) if (vv) sp.set(kk, vv);
    router.replace(`${pathname}?${sp.toString()}`);
  };
  React.useEffect(() => {
    const t = setTimeout(() => {
      if ((filters.q ?? "") !== q) set("q", q);
    }, 400);
    return () => clearTimeout(t);
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [q]);
  const hasFilters = Object.entries(filters).some(([, v]) => v);
  function exportCsv() {
    const esc = (v: unknown) => {
      const s = v == null ? "" : String(v);
      return /[",\n]/.test(s) ? `"${s.replace(/"/g, '""')}"` : s;
    };
    const csv = ["reference,time,user,role,module,action,severity,entity,previous,new,reason,ip,device,browser", ...rows.map((r) => [r.code, fmtDateTime(r.createdAt, timezone), r.userName, r.roleKey, r.module, r.action, r.severity, r.entityLabel, r.previousValue, r.newValue, r.reason, r.ipAddress, r.device, r.browser].map(esc).join(","))].join("\n");
    const url = URL.createObjectURL(new Blob(["﻿" + csv], { type: "text/csv;charset=utf-8" }));
    const a = document.createElement("a");
    a.href = url;
    a.download = "audit-log.csv";
    a.click();
    URL.revokeObjectURL(url);
  }
  return (
    <div className="space-y-3">
      <div className="flex flex-wrap items-center gap-2">
        <SearchInput value={q} onChange={setQ} placeholder="Reference (RES-1028, CUS-184, EVT-…), user, reason" className="w-full sm:w-72" />
        <FilterSelect value={filters.worker ?? ""} onChange={(v) => set("worker", v)} placeholder="All users" options={workers.map((w) => ({ value: w.id, label: w.fullName }))} />
        <FilterSelect value={filters.module ?? ""} onChange={(v) => set("module", v)} placeholder="All modules" options={modules.map((m) => ({ value: m, label: m }))} />
        <FilterSelect value={filters.action ?? ""} onChange={(v) => set("action", v)} placeholder="All actions" options={actions.map((a) => ({ value: a, label: AUDIT_ACTIONS[a] ?? a }))} />
        <FilterSelect value={filters.entity ?? ""} onChange={(v) => set("entity", v)} placeholder="All entities" options={entityTypes.map((e) => ({ value: e, label: e }))} />
        <FilterSelect value={filters.severity ?? ""} onChange={(v) => set("severity", v)} placeholder="All severities" options={[{ value: "INFO", label: "Info" }, { value: "WARNING", label: "Warning" }, { value: "CRITICAL", label: "Critical" }]} />
        <FilterSelect value={filters.apartment ?? ""} onChange={(v) => set("apartment", v)} placeholder="All apartments" options={apartments.map((a) => ({ value: a.id, label: a.code }))} />
        <FilterSelect value={filters.device ?? ""} onChange={(v) => set("device", v)} placeholder="All devices" options={[{ value: "Desktop", label: "Desktop" }, { value: "Mobile", label: "Mobile" }, { value: "Tablet", label: "Tablet" }]} />
        <div className="flex items-center gap-1">
          <Input type="date" value={filters.from ?? ""} onChange={(e) => set("from", e.target.value)} className="h-9 w-[140px] text-xs" aria-label="From" />
          <span className="text-xs text-fg-subtle">→</span>
          <Input type="date" value={filters.to ?? ""} onChange={(e) => set("to", e.target.value)} className="h-9 w-[140px] text-xs" aria-label="To" />
        </div>
        {hasFilters ? (
          <Button variant="ghost" size="sm" onClick={() => router.replace(pathname)}>
            <X /> Clear
          </Button>
        ) : null}
        <Button variant="ghost" size="sm" className="ml-auto" onClick={exportCsv}>
          Export CSV
        </Button>
      </div>
      <p className="text-xs text-fg-muted">
        {rows.length} event{rows.length === 1 ? "" : "s"}
        {rows.length === 500 ? " (showing the most recent 500 — narrow the filters for more)" : ""}
      </p>
      {rows.length === 0 ? (
        <div className="surface">
          <EmptyState title="No audit events match" description="Try a wider date range or fewer filters." />
        </div>
      ) : (
        <div className="surface divide-y divide-border">
          {rows.map((r) => {
            const href = hrefFor(r as unknown as Parameters<typeof hrefFor>[0]);
            const expanded = open === r.id;
            const prev = safeJson<unknown>(r.previousValue, null);
            const next = safeJson<unknown>(r.newValue, null);
            const DeviceIcon = r.device?.startsWith("Mobile") ? Smartphone : r.device?.startsWith("Tablet") ? Tablet : Monitor;
            return (
              <div key={r.id} id={`evt-${r.id}`} className={cn(focusId === r.id && "bg-primary/5 ring-1 ring-inset ring-primary/30")}>
                <button type="button" onClick={() => setOpen(expanded ? null : r.id)} className="flex w-full items-start gap-3 px-4 py-2.5 text-left hover:bg-surface-2/60">
                  <span className="hidden w-32 shrink-0 text-2xs text-fg-subtle sm:block">{fmtDateTime(r.createdAt, timezone)}</span>
                  <Avatar name={r.userName} size="sm" />
                  <span className="min-w-0 flex-1">
                    <span className="block text-sm">
                      <span className="font-medium">{r.userName}</span> <span className="text-fg-muted">{describeActivity({ ...r, createdAt: new Date(r.createdAt) } as unknown as Parameters<typeof describeActivity>[0])}</span>
                    </span>
                    <span className="mt-0.5 flex flex-wrap items-center gap-2 text-2xs text-fg-subtle">
                      <span className="sm:hidden">{fmtDateTime(r.createdAt, timezone)}</span>
                      <Badge tone={MODULE_TONE[r.module] ?? "neutral"} size="sm">
                        {r.module}
                      </Badge>
                      <span className="rounded bg-surface-2 px-1 font-mono">{r.action}</span>
                      {r.severity !== "INFO" ? <StatusBadge status={`SEV_${r.severity}`} size="sm" /> : null}
                      {r.code ? <span className="font-mono text-fg-subtle">{r.code}</span> : null}
                      <span className="uppercase">{r.roleKey}</span>
                      {r.device ? (
                        <span className="flex items-center gap-1">
                          <DeviceIcon className="size-3" /> {r.device} · {r.browser}
                        </span>
                      ) : null}
                    </span>
                  </span>
                  <ChevronDown className={cn("mt-1 size-4 shrink-0 text-fg-subtle transition", expanded && "rotate-180")} />
                </button>
                {expanded ? (
                  <div className="grid gap-3 border-t border-border bg-surface-2/40 px-4 py-3 text-xs sm:grid-cols-2 sm:pl-[calc(8rem+2.75rem+1rem)]">
                    <div>
                      <p className="mb-1 text-2xs font-semibold uppercase tracking-wider text-fg-subtle">Previous value</p>
                      <pre className="whitespace-pre-wrap break-words rounded-md bg-surface p-2 font-mono text-2xs text-fg-muted">{prev == null ? "—" : typeof prev === "string" ? prev : JSON.stringify(prev, null, 2)}</pre>
                    </div>
                    <div>
                      <p className="mb-1 text-2xs font-semibold uppercase tracking-wider text-fg-subtle">New value</p>
                      <pre className="whitespace-pre-wrap break-words rounded-md bg-surface p-2 font-mono text-2xs text-fg">{next == null ? "—" : typeof next === "string" ? next : JSON.stringify(next, null, 2)}</pre>
                    </div>
                    <div className="sm:col-span-2 flex flex-wrap items-center gap-x-4 gap-y-1 text-fg-muted">
                      {r.reason ? <span>Reason: <i>{r.reason}</i></span> : null}
                      <span>Entity: {r.entityType ?? "—"} {r.entityId ? <span className="font-mono text-2xs">{r.entityId}</span> : null}</span>
                      <span>IP: {r.ipAddress ?? "—"}</span>
                      {href ? (
                        <Link href={href} className="font-medium text-primary hover:underline">
                          Open {r.entityType ?? "record"} →
                        </Link>
                      ) : null}
                    </div>
                  </div>
                ) : null}
              </div>
            );
          })}
        </div>
      )}
    </div>
  );
}
