import type { Metadata } from "next";
import Link from "next/link";
import { desc, eq, sql as drSql } from "drizzle-orm";
import { History, User as UserIcon, ArrowRight } from "lucide-react";
import { db } from "@/lib/db/client";
import { adminAudit, users } from "@/lib/db/schema";
import {
  AdminHeading,
  DataTable,
  EmptyState,
  Toolbar,
  FilterPill,
  SearchInput,
  KpiCard,
  formatAdminDateTime,
  formatAdminRelative,
  type Column,
} from "@/components/admin";

export const metadata: Metadata = { title: "Audit log" };
export const dynamic = "force-dynamic";

type AuditRow = {
  id: string;
  action: string;
  targetId: string | null;
  metadata: unknown;
  createdAt: Date;
  adminName: string | null;
  adminId: string | null;
};

const PAGE_SIZE = 50;

function humaniseAction(action: string): string {
  return action
    .replace(/_/g, " ")
    .replace(/^./, (c) => c.toUpperCase());
}

export default async function AdminAuditPage({
  searchParams,
}: {
  searchParams: Promise<{ action?: string; q?: string; page?: string }>;
}) {
  const params = await searchParams;
  const actionFilter = (params.action ?? "").trim();
  const query = (params.q ?? "").trim().toLowerCase();
  const page = Math.max(1, Number(params.page ?? "1") || 1);
  const offset = (page - 1) * PAGE_SIZE;

  const [actionCountsRaw, totalRow, rowsRaw] = await Promise.all([
    db
      .select({
        action: adminAudit.action,
        count: drSql<number>`count(*)::int`,
      })
      .from(adminAudit)
      .groupBy(adminAudit.action)
      .orderBy(desc(drSql`count(*)`)),
    db
      .select({ count: drSql<number>`count(*)::int` })
      .from(adminAudit),
    db
      .select({
        id: adminAudit.id,
        action: adminAudit.action,
        targetId: adminAudit.targetId,
        metadata: adminAudit.metadata,
        createdAt: adminAudit.createdAt,
        adminName: users.name,
        adminId: adminAudit.adminUserId,
      })
      .from(adminAudit)
      .leftJoin(users, eq(users.id, adminAudit.adminUserId))
      .orderBy(desc(adminAudit.createdAt))
      .limit(PAGE_SIZE + 1)
      .offset(offset),
  ]);

  const total = Number(totalRow[0]?.count ?? 0);
  const allRows = rowsRaw as AuditRow[];

  let filtered = allRows;
  if (actionFilter) {
    filtered = filtered.filter((r) => r.action === actionFilter);
  }
  if (query) {
    filtered = filtered.filter((r) =>
      [r.action, r.adminName ?? "", r.targetId ?? ""]
        .join(" ")
        .toLowerCase()
        .includes(query),
    );
  }

  // Peek one more row than PAGE_SIZE to know if there's a next page.
  const hasNext = filtered.length > PAGE_SIZE;
  const pageRows = filtered.slice(0, PAGE_SIZE);

  const topActions = actionCountsRaw.slice(0, 6);
  const uniqueAdminsCount = new Set(
    allRows.map((r) => r.adminId).filter(Boolean),
  ).size;

  const buildHref = (patch: {
    action?: string;
    q?: string;
    page?: number;
  }) => {
    const nextAction = patch.action !== undefined ? patch.action : actionFilter;
    const nextQuery = patch.q !== undefined ? patch.q : query;
    const nextPage = patch.page !== undefined ? patch.page : page;
    const parts: string[] = [];
    if (nextAction) parts.push(`action=${encodeURIComponent(nextAction)}`);
    if (nextQuery) parts.push(`q=${encodeURIComponent(nextQuery)}`);
    if (nextPage > 1) parts.push(`page=${nextPage}`);
    return `/admin/audit${parts.length ? `?${parts.join("&")}` : ""}`;
  };

  const columns: Column<AuditRow>[] = [
    {
      key: "action",
      header: "Action",
      cell: (r) => (
        <Link
          href={`/admin/audit/${r.id}`}
          className="-mx-1 block min-w-0 rounded-md px-1 transition-colors hover:bg-[var(--color-mist)]/40"
        >
          <div className="truncate font-semibold text-[var(--color-ink)]">
            {humaniseAction(r.action)}
          </div>
          <div className="truncate text-[12px] text-[var(--color-slate)]">
            <code className="font-mono text-[11px]">{r.action}</code>
          </div>
        </Link>
      ),
    },
    {
      key: "admin",
      header: "Admin",
      cell: (r) => (
        <div className="flex items-center gap-2 text-[13px]">
          <span className="flex h-6 w-6 items-center justify-center rounded-full bg-[var(--color-mist)] text-[11px] font-bold text-[var(--color-blue)]">
            {r.adminName ? r.adminName.charAt(0).toUpperCase() : <UserIcon className="h-3 w-3" aria-hidden />}
          </span>
          <span className="truncate text-[var(--color-ink)]">
            {r.adminName ?? "System"}
          </span>
        </div>
      ),
    },
    {
      key: "target",
      header: "Target",
      cell: (r) => (
        <span className="font-mono text-[11px] text-[var(--color-slate)]">
          {r.targetId ? r.targetId.slice(0, 8) + "…" : "—"}
        </span>
      ),
    },
    {
      key: "when",
      header: "When",
      cell: (r) => (
        <div className="min-w-0">
          <div className="truncate text-[13px] text-[var(--color-ink)]">
            {formatAdminRelative(r.createdAt)}
          </div>
          <div className="truncate text-[11px] text-[var(--color-slate)]">
            {formatAdminDateTime(r.createdAt)}
          </div>
        </div>
      ),
    },
    {
      key: "metadata",
      header: "Details",
      cell: (r) => {
        if (!r.metadata) return <span className="text-[var(--color-slate)]">—</span>;
        try {
          const s = JSON.stringify(r.metadata);
          return (
            <span
              className="line-clamp-2 max-w-[280px] break-all font-mono text-[11px] text-[var(--color-slate)]"
              title={s}
            >
              {s}
            </span>
          );
        } catch {
          return <span className="text-[var(--color-slate)]">—</span>;
        }
      },
    },
  ];

  return (
    <>
      <AdminHeading
        eyebrow="Overview"
        title="Audit log"
        lede="Every admin action is recorded with actor, target, and a timestamp. Useful for compliance, incident review, and spotting unusual patterns."
      />

      <div className="mb-6 grid grid-cols-2 gap-4 lg:grid-cols-4">
        <KpiCard label="Total events" value={total} Icon={History} tone="ink" />
        <KpiCard
          label="On this page"
          value={pageRows.length}
          tone="blue"
          hint={`Page ${page}`}
        />
        <KpiCard
          label="Distinct actions"
          value={actionCountsRaw.length}
          tone="emerald"
        />
        <KpiCard
          label="Unique admins"
          value={uniqueAdminsCount}
          tone="slate"
        />
      </div>

      <div className="mb-4">
        <Toolbar
          actions={
            <form method="GET" action="/admin/audit">
              {actionFilter && (
                <input type="hidden" name="action" value={actionFilter} />
              )}
              <SearchInput
                defaultValue={params.q ?? ""}
                placeholder="Search by action, admin, or target id…"
              />
            </form>
          }
        >
          <FilterPill
            href={buildHref({ action: "", page: 1 })}
            label="All actions"
            count={total}
            active={!actionFilter}
          />
          {topActions.map((a) => (
            <FilterPill
              key={a.action}
              href={buildHref({ action: a.action, page: 1 })}
              label={humaniseAction(a.action)}
              count={Number(a.count)}
              active={actionFilter === a.action}
            />
          ))}
        </Toolbar>
      </div>

      {pageRows.length === 0 ? (
        <EmptyState
          Icon={History}
          title="No matching events"
          description="Try clearing the filter or broadening the search term."
        />
      ) : (
        <DataTable columns={columns} rows={pageRows} rowKey={(r) => r.id} />
      )}

      {(page > 1 || hasNext) && (
        <nav
          aria-label="Pagination"
          className="mt-6 flex items-center justify-between gap-3"
        >
          <Link
            href={buildHref({ page: Math.max(1, page - 1) })}
            aria-disabled={page <= 1}
            className={
              page <= 1
                ? "pointer-events-none inline-flex items-center gap-1 rounded-lg border border-[var(--color-line)] bg-white px-4 py-2 text-[13px] font-semibold text-[var(--color-slate)] opacity-50"
                : "inline-flex items-center gap-1 rounded-lg border border-[var(--color-line)] bg-white px-4 py-2 text-[13px] font-semibold text-[var(--color-ink)] hover:border-[var(--color-blue)] hover:text-[var(--color-blue)]"
            }
          >
            <ArrowRight className="h-3.5 w-3.5 rotate-180" aria-hidden /> Previous
          </Link>
          <span className="text-[12px] text-[var(--color-slate)]">Page {page}</span>
          <Link
            href={buildHref({ page: page + 1 })}
            aria-disabled={!hasNext}
            className={
              !hasNext
                ? "pointer-events-none inline-flex items-center gap-1 rounded-lg border border-[var(--color-line)] bg-white px-4 py-2 text-[13px] font-semibold text-[var(--color-slate)] opacity-50"
                : "inline-flex items-center gap-1 rounded-lg border border-[var(--color-line)] bg-white px-4 py-2 text-[13px] font-semibold text-[var(--color-ink)] hover:border-[var(--color-blue)] hover:text-[var(--color-blue)]"
            }
          >
            Next <ArrowRight className="h-3.5 w-3.5" aria-hidden />
          </Link>
        </nav>
      )}
    </>
  );
}
