import { createFileRoute } from "@tanstack/react-router";
import { useQuery } from "@tanstack/react-query";
import { useServerFn } from "@tanstack/react-start";
import { adminListAuditLogs } from "@/lib/admin.functions";
import { formatDistanceToNow, format } from "date-fns";
import { Badge } from "@/components/ui/badge";
import { Input } from "@/components/ui/input";
import { Button } from "@/components/ui/button";
import { useState } from "react";

export const Route = createFileRoute("/admin/audit")({ component: AdminAudit });

type Filters = { search?: string; action?: string; from?: string; to?: string; limit?: number };

function AdminAudit() {
  const fetchLogs = useServerFn(adminListAuditLogs);
  const [draft, setDraft] = useState<Filters>({});
  const [filters, setFilters] = useState<Filters>({});
  const { data, isLoading, isFetching } = useQuery({
    queryKey: ["admin-audit", filters],
    queryFn: () => fetchLogs({ data: { ...filters, limit: 300 } }),
  });

  const exportCsv = () => {
    const rows = data ?? [];
    const head = ["when", "actor", "action", "entity", "entity_id", "ip_address", "user_agent", "metadata"];
    const body = rows.map((l) => [
      l.created_at,
      (l as { actor?: { email?: string } }).actor?.email ?? "",
      l.action,
      l.entity ?? "",
      l.entity_id ?? "",
      (l as { ip_address?: string }).ip_address ?? "",
      (l as { user_agent?: string }).user_agent ?? "",
      JSON.stringify(l.metadata ?? {}),
    ]);
    const csv = [head, ...body].map((r) => r.map((c) => `"${String(c).replace(/"/g, '""')}"`).join(",")).join("\n");
    const url = URL.createObjectURL(new Blob([csv], { type: "text/csv" }));
    const a = document.createElement("a");
    a.href = url;
    a.download = `billsline-audit-${Date.now()}.csv`;
    a.click();
    URL.revokeObjectURL(url);
  };

  return (
    <div className="space-y-3">
      <div className="flex flex-wrap items-end gap-2 rounded-2xl bg-card p-3 shadow-card">
        <div className="min-w-[180px] flex-1">
          <label className="text-[11px] font-medium text-muted-foreground">Search entity / ID / IP</label>
          <Input className="h-9" value={draft.search ?? ""} onChange={(e) => setDraft({ ...draft, search: e.target.value })} />
        </div>
        <div className="w-40">
          <label className="text-[11px] font-medium text-muted-foreground">Action</label>
          <Input className="h-9" placeholder="wallet." value={draft.action ?? ""} onChange={(e) => setDraft({ ...draft, action: e.target.value })} />
        </div>
        <div className="w-40">
          <label className="text-[11px] font-medium text-muted-foreground">From</label>
          <Input className="h-9" type="date" value={draft.from ?? ""} onChange={(e) => setDraft({ ...draft, from: e.target.value })} />
        </div>
        <div className="w-40">
          <label className="text-[11px] font-medium text-muted-foreground">To</label>
          <Input className="h-9" type="date" value={draft.to ?? ""} onChange={(e) => setDraft({ ...draft, to: e.target.value })} />
        </div>
        <Button size="sm" onClick={() => setFilters({ ...draft })} disabled={isFetching}>Apply</Button>
        <Button size="sm" variant="outline" onClick={() => { setDraft({}); setFilters({}); }}>Reset</Button>
        <Button size="sm" variant="secondary" onClick={exportCsv} disabled={!data?.length}>Export CSV</Button>
      </div>

      <div className="overflow-x-auto rounded-2xl bg-card shadow-card">
        <table className="w-full text-sm">
          <thead className="bg-secondary text-left text-xs uppercase">
            <tr>
              <th className="p-3">When</th>
              <th className="p-3">Actor</th>
              <th className="p-3">Action</th>
              <th className="p-3">Entity</th>
              <th className="p-3">Origin</th>
              <th className="p-3">Details</th>
            </tr>
          </thead>
          <tbody>
            {isLoading && <tr><td colSpan={6} className="p-8 text-center text-muted-foreground">Loading…</td></tr>}
            {(data ?? []).map((l) => {
              const ip = (l as { ip_address?: string | null }).ip_address;
              const ua = (l as { user_agent?: string | null }).user_agent;
              return (
                <tr key={l.id} className="border-t align-top">
                  <td className="p-3 text-xs text-muted-foreground" title={format(new Date(l.created_at), "PPpp")}>
                    {formatDistanceToNow(new Date(l.created_at), { addSuffix: true })}
                  </td>
                  <td className="p-3">{(l as { actor?: { email?: string; full_name?: string } }).actor?.full_name ?? (l as { actor?: { email?: string } }).actor?.email ?? "—"}</td>
                  <td className="p-3"><Badge variant="outline">{l.action}</Badge></td>
                  <td className="p-3 font-mono text-xs">{l.entity ?? "—"}{l.entity_id ? `:${l.entity_id.slice(0, 8)}` : ""}</td>
                  <td className="p-3 text-[11px] text-muted-foreground">
                    <div className="font-mono">{ip || "—"}</div>
                    <div className="max-w-[220px] truncate" title={ua ?? ""}>{ua || "—"}</div>
                  </td>
                  <td className="p-3"><pre className="max-w-xs overflow-hidden text-ellipsis text-[10px]">{JSON.stringify(l.metadata, null, 0)}</pre></td>
                </tr>
              );
            })}
            {!isLoading && !data?.length && <tr><td colSpan={6} className="p-8 text-center text-muted-foreground">No audit entries match these filters.</td></tr>}
          </tbody>
        </table>
      </div>
    </div>
  );
}
