import Link from "next/link";
import { getAuditLog, getAuditFacets, formatRelative } from "@/lib/reports";

export const dynamic = "force-dynamic";

/**
 * Audit log viewer. Cursor-paginated, with action / entity / actor filters
 * driven by the GET query string. Server-rendered so the URL is the source
 * of truth — bookmarking a filtered view just works, and page reloads don't
 * drop state.
 *
 * The JSON `before`/`after` payloads can be long; we render them lazily
 * inside a <details> block so the table stays scannable.
 */
export default async function AuditPage({
  searchParams,
}: {
  searchParams: Promise<{
    action?: string;
    entity?: string;
    actorId?: string;
    cursor?: string;
  }>;
}) {
  const { action, entity, actorId, cursor } = await searchParams;
  const [facets, { rows, nextCursor }] = await Promise.all([
    getAuditFacets(),
    getAuditLog({
      limit: 50,
      action: action || null,
      entity: entity || null,
      actorId: actorId || null,
      cursor: cursor || null,
    }),
  ]);
  const now = new Date();

  // Build a filter-preserving URL for the "Next page" link.
  const nextHref = nextCursor
    ? `/admin/audit?${new URLSearchParams({
        ...(action ? { action } : {}),
        ...(entity ? { entity } : {}),
        ...(actorId ? { actorId } : {}),
        cursor: nextCursor,
      }).toString()}`
    : null;

  const filtersActive = !!(action || entity || actorId);

  return (
    <div className="mx-auto max-w-7xl px-4 py-8">
      <div className="flex items-start justify-between gap-6 mb-6">
        <div>
          <h1 className="text-2xl font-semibold tracking-tight">Audit log</h1>
          <p className="text-slate-500 mt-1 text-sm">
            Every write — claim, release, close, create, update, delete, login — lands here.
            Newest first.
          </p>
        </div>
      </div>

      {/* ─── Filter bar ──────────────────────────────────────────── */}
      <form method="get" className="mb-6 rounded-xl bg-white border border-slate-200 p-4">
        <div className="grid gap-3 md:grid-cols-4">
          <label className="block text-sm">
            <span className="text-slate-700">Action</span>
            <select
              name="action"
              defaultValue={action ?? ""}
              className="mt-1 w-full rounded-md border border-slate-300 px-3 py-2 text-sm bg-white"
            >
              <option value="">Any action</option>
              {facets.actions.map((a) => (
                <option key={a} value={a}>
                  {a}
                </option>
              ))}
            </select>
          </label>
          <label className="block text-sm">
            <span className="text-slate-700">Entity</span>
            <select
              name="entity"
              defaultValue={entity ?? ""}
              className="mt-1 w-full rounded-md border border-slate-300 px-3 py-2 text-sm bg-white"
            >
              <option value="">Any entity</option>
              {facets.entities.map((e) => (
                <option key={e} value={e}>
                  {e}
                </option>
              ))}
            </select>
          </label>
          <label className="block text-sm">
            <span className="text-slate-700">Actor</span>
            <select
              name="actorId"
              defaultValue={actorId ?? ""}
              className="mt-1 w-full rounded-md border border-slate-300 px-3 py-2 text-sm bg-white"
            >
              <option value="">Any user</option>
              {facets.actors.map((u) => (
                <option key={u.id} value={u.id}>
                  {u.name} ({u.role})
                </option>
              ))}
            </select>
          </label>
          <div className="flex items-end gap-2">
            <button
              type="submit"
              className="h-10 rounded-md bg-slate-900 text-white text-sm font-medium px-4"
            >
              Filter
            </button>
            {filtersActive ? (
              <Link
                href="/admin/audit"
                className="h-10 inline-flex items-center rounded-md border border-slate-300 text-sm font-medium px-4 text-slate-700 hover:bg-slate-50"
              >
                Clear
              </Link>
            ) : null}
          </div>
        </div>
      </form>

      {/* ─── Results ─────────────────────────────────────────────── */}
      <div className="rounded-xl bg-white border border-slate-200 overflow-hidden">
        {rows.length === 0 ? (
          <p className="px-4 py-10 text-center text-slate-500 text-sm">
            No events match. Clear filters or widen your search.
          </p>
        ) : (
          <table className="w-full text-sm">
            <thead className="bg-slate-50 text-left text-slate-600 border-b border-slate-200">
              <tr>
                <th className="px-4 py-2 font-medium w-[140px]">When</th>
                <th className="px-4 py-2 font-medium w-[150px]">Actor</th>
                <th className="px-4 py-2 font-medium w-[150px]">Action</th>
                <th className="px-4 py-2 font-medium w-[220px]">Entity</th>
                <th className="px-4 py-2 font-medium">Payload</th>
                <th className="px-4 py-2 font-medium w-[100px]">IP</th>
              </tr>
            </thead>
            <tbody>
              {rows.map((row) => (
                <tr key={row.id} className="border-b border-slate-100 last:border-0 align-top">
                  <td className="px-4 py-2 text-slate-600 whitespace-nowrap">
                    <div>{formatRelative(row.at, now)}</div>
                    <div className="text-xs text-slate-400">{row.at.toLocaleString()}</div>
                  </td>
                  <td className="px-4 py-2">
                    {row.actor ? (
                      <>
                        <div className="text-slate-900">{row.actor.name}</div>
                        <div className="text-xs text-slate-500">{row.actor.role}</div>
                      </>
                    ) : (
                      <span className="text-slate-400 italic">system</span>
                    )}
                  </td>
                  <td className="px-4 py-2">
                    <span className="inline-flex rounded-full bg-slate-100 text-slate-700 text-xs px-2 py-0.5 font-mono">
                      {row.action}
                    </span>
                  </td>
                  <td className="px-4 py-2 font-mono text-xs text-slate-700 break-all">
                    {row.entity}
                    {row.entityId ? <span className="text-slate-500">/{row.entityId}</span> : null}
                  </td>
                  <td className="px-4 py-2">
                    {row.before || row.after ? (
                      <details>
                        <summary className="cursor-pointer text-xs text-blue-600">
                          {row.after ? "after" : "before"}
                          {row.before && row.after ? " / before" : ""}
                        </summary>
                        <div className="mt-2 space-y-2">
                          {row.after ? (
                            <JsonBlock label="after" value={row.after} />
                          ) : null}
                          {row.before ? (
                            <JsonBlock label="before" value={row.before} />
                          ) : null}
                        </div>
                      </details>
                    ) : (
                      <span className="text-slate-400 text-xs">—</span>
                    )}
                  </td>
                  <td className="px-4 py-2 text-xs text-slate-500 font-mono">
                    {row.ipAddress ?? "—"}
                  </td>
                </tr>
              ))}
            </tbody>
          </table>
        )}
      </div>

      {/* ─── Pagination ──────────────────────────────────────────── */}
      <div className="mt-4 flex items-center justify-between text-sm text-slate-600">
        <div>{rows.length} row{rows.length === 1 ? "" : "s"} on this page</div>
        {nextHref ? (
          <Link
            href={nextHref}
            className="inline-flex items-center rounded-md border border-slate-300 bg-white px-3 py-1.5 text-sm hover:bg-slate-50"
          >
            Older →
          </Link>
        ) : (
          <span className="text-slate-400">End of log</span>
        )}
      </div>
    </div>
  );
}

/**
 * Pretty-prints a JSON audit payload. Falls back to the raw string if the
 * row happens to contain non-JSON (older rows, or writes that logged a
 * free-form message).
 */
function JsonBlock({ label, value }: { label: string; value: string }) {
  let pretty = value;
  try {
    pretty = JSON.stringify(JSON.parse(value), null, 2);
  } catch {
    // leave as-is
  }
  return (
    <div>
      <div className="text-[10px] uppercase tracking-wide text-slate-500">{label}</div>
      <pre className="mt-1 text-xs bg-slate-50 border border-slate-200 rounded-md p-2 overflow-x-auto">
        {pretty}
      </pre>
    </div>
  );
}
