"use client";

import React, { useCallback, useEffect, useMemo, useState } from "react";
import { useAuth } from "@/hooks/useAuth";
import { useRouter } from "next/navigation";
import { apiFetch } from "@/lib/api";
import { useDismissingState } from "@/hooks/useDismissingState";
import { History } from "lucide-react";
import { Table, TableHeader, TableBody, TableRow, TableHead, TableCell } from "@/components/ui/table";

const ACTIONS = [
  "refund_created",
  "donation_assigned",
  "donation_unassigned",
  "registration_created_manual",
  "registration_cancelled",
  "event_created",
  "event_updated",
  "event_deleted",
  "settings_updated",
] as const;

const ACTION_LABELS: Record<string, string> = {
  refund_created: "Refund created",
  donation_assigned: "Donation assigned",
  donation_unassigned: "Donation unassigned",
  registration_created_manual: "Manual registration created",
  registration_cancelled: "Registration cancelled (staff)",
  event_created: "Event created",
  event_updated: "Event updated",
  event_deleted: "Event deactivated",
  settings_updated: "Settings updated",
};

interface AuditLogEntry {
  id: string;
  actorId: string | null;
  actorRole: string;
  action: string;
  targetType: string;
  targetId: string | null;
  metadata: Record<string, unknown> | null;
  ip: string | null;
  createdAt: string;
  actor: { id: string; name: string; email: string } | null;
}

function formatMetadata(metadata: Record<string, unknown> | null): string {
  if (!metadata) return "";
  try {
    return Object.entries(metadata)
      .filter(([, v]) => v !== null && v !== undefined && v !== "")
      .map(([k, v]) => `${k}: ${Array.isArray(v) ? v.join(", ") : String(v)}`)
      .join(" · ");
  } catch {
    return "";
  }
}

export default function AdminAuditLogPage() {
  const { user, loading, token } = useAuth();
  const router = useRouter();

  const isAdmin = useMemo(() => user?.role === "admin", [user]);

  useEffect(() => {
    if (loading) return;
    if (!user) router.replace("/login");
  }, [user, loading, router]);

  const [entries, setEntries] = useState<AuditLogEntry[]>([]);
  const [fetching, setFetching] = useState(false);
  const [error, setError] = useDismissingState<string | null>(null);
  const [page, setPage] = useState(1);
  const [total, setTotal] = useState(0);
  const pageSize = 50;
  const totalPages = Math.max(1, Math.ceil(total / pageSize));

  const [actionFilter, setActionFilter] = useState<string>("");
  const [fromFilter, setFromFilter] = useState<string>("");
  const [toFilter, setToFilter] = useState<string>("");

  const buildQuery = useCallback((p: number) => {
    const qs = new URLSearchParams({ page: String(p), limit: String(pageSize) });
    if (actionFilter) qs.set("action", actionFilter);
    if (fromFilter) qs.set("from", fromFilter);
    if (toFilter) qs.set("to", toFilter);
    return `/api/admin/audit-log?${qs.toString()}`;
  }, [actionFilter, fromFilter, toFilter]);

  const load = useCallback(async (p = 1) => {
    if (!token) return;
    setError(null);
    setFetching(true);
    try {
      const res = await apiFetch<{ rows: AuditLogEntry[]; total: number; page: number }>(buildQuery(p), { authToken: token });
      setEntries(res?.rows || []);
      setTotal(res?.total ?? 0);
      setPage(p);
    } catch (e: any) {
      setError(e?.message || "Failed to load audit log");
    } finally {
      setFetching(false);
    }
  }, [token, buildQuery]);

  useEffect(() => { if (token) load(1); }, [token, actionFilter, fromFilter, toFilter]);

  return (
    <div className="max-w-6xl mx-auto w-full p-6">
      <div className="flex items-center gap-3 mb-4">
        <div className="w-10 h-10 rounded-xl bg-brand-50 flex items-center justify-center shrink-0">
          <History className="w-5 h-5 text-brand-600" />
        </div>
        <div>
          <h1 className="text-2xl font-semibold text-gray-900">Admin Audit Log</h1>
          <p className="text-sm text-gray-500">{total} action{total !== 1 ? "s" : ""} recorded</p>
        </div>
      </div>

      {!isAdmin && (
        <div className="p-3 border rounded bg-yellow-50 text-yellow-800 text-sm mb-4">
          You need admin access to view the audit log.
        </div>
      )}

      {error && <div className="mb-3 p-3 border rounded bg-red-50 text-red-800 text-sm">{error}</div>}

      <div className="border rounded-xl p-4 bg-white shadow-sm">
        <div className="flex flex-wrap items-end gap-3 mb-4">
          <div>
            <label className="block text-xs text-gray-600 mb-1">Action</label>
            <select className="border rounded px-2 py-1.5 text-sm" value={actionFilter} onChange={e => setActionFilter(e.target.value)}>
              <option value="">All actions</option>
              {ACTIONS.map(a => <option key={a} value={a}>{ACTION_LABELS[a]}</option>)}
            </select>
          </div>
          <div>
            <label className="block text-xs text-gray-600 mb-1">From</label>
            <input type="date" className="border rounded px-2 py-1.5 text-sm" value={fromFilter} onChange={e => setFromFilter(e.target.value)} />
          </div>
          <div>
            <label className="block text-xs text-gray-600 mb-1">To</label>
            <input type="date" className="border rounded px-2 py-1.5 text-sm" value={toFilter} onChange={e => setToFilter(e.target.value)} />
          </div>
          <button className="text-sm px-2 py-1.5 rounded bg-gray-100 hover:bg-gray-200" onClick={() => load(page)} disabled={fetching}>
            {fetching ? "Refreshing…" : "Refresh"}
          </button>
        </div>

        <Table>
          <TableHeader>
            <TableRow>
              <TableHead>When</TableHead>
              <TableHead>Actor</TableHead>
              <TableHead>Action</TableHead>
              <TableHead>Target</TableHead>
              <TableHead>Details</TableHead>
            </TableRow>
          </TableHeader>
          <TableBody>
            {entries.map(e => (
              <TableRow key={e.id}>
                <TableCell className="whitespace-nowrap text-gray-600">{new Date(e.createdAt).toLocaleString()}</TableCell>
                <TableCell>
                  {e.actor ? (
                    <>
                      <div className="font-medium">{e.actor.name}</div>
                      <div className="text-xs text-gray-500">{e.actor.email}</div>
                    </>
                  ) : (
                    <span className="text-gray-400 italic">Deleted user</span>
                  )}
                  <div className="text-xs text-gray-400 capitalize">{e.actorRole}</div>
                </TableCell>
                <TableCell>{ACTION_LABELS[e.action] || e.action}</TableCell>
                <TableCell className="text-xs text-gray-600">{e.targetType}{e.targetId ? ` #${e.targetId.slice(0, 8)}` : ""}</TableCell>
                <TableCell className="text-xs text-gray-500 max-w-[280px] truncate" title={formatMetadata(e.metadata)}>{formatMetadata(e.metadata)}</TableCell>
              </TableRow>
            ))}
            {entries.length === 0 && !fetching && (
              <TableRow>
                <TableCell colSpan={5} className="text-gray-500">No matching audit entries.</TableCell>
              </TableRow>
            )}
            {fetching && (
              <TableRow>
                <TableCell colSpan={5} className="text-gray-400">Loading…</TableCell>
              </TableRow>
            )}
          </TableBody>
        </Table>

        {totalPages > 1 && (
          <div className="flex items-center justify-between mt-4 text-sm">
            <span className="text-gray-500">Page {page} of {totalPages}</span>
            <div className="flex gap-1">
              <button
                className="px-2 py-1 rounded bg-gray-100 hover:bg-gray-200 disabled:opacity-40"
                disabled={page <= 1 || fetching}
                onClick={() => load(page - 1)}
              >
                ← Prev
              </button>
              <button
                className="px-2 py-1 rounded bg-gray-100 hover:bg-gray-200 disabled:opacity-40"
                disabled={page >= totalPages || fetching}
                onClick={() => load(page + 1)}
              >
                Next →
              </button>
            </div>
          </div>
        )}
      </div>
    </div>
  );
}
