import type { Metadata } from "next";
import { desc, eq, and, sql } from "drizzle-orm";
import { Mail, CheckCircle2, XCircle, AlertTriangle, Terminal } from "lucide-react";
import { requireAdmin } from "@/lib/auth/admin-guard";
import { db } from "@/lib/db/client";
import { emailLog } from "@/lib/db/schema";
import {
  AdminHeading,
  DataTable,
  KpiCard,
  StatusBadge,
  Toolbar,
  FilterPill,
  EmptyState,
  SearchInput,
  formatAdminDateTime,
  type Column,
} from "@/components/admin";
import type { EmailLogEntry } from "@/lib/db/schema";

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

const STATUS_FILTERS = ["all", "sent", "failed", "dev_console", "queued"] as const;
type StatusFilter = (typeof STATUS_FILTERS)[number];

function isStatusFilter(v: string | undefined): v is StatusFilter {
  return typeof v === "string" && (STATUS_FILTERS as readonly string[]).includes(v);
}

export default async function AdminEmailLogPage({
  searchParams,
}: {
  searchParams: Promise<{ status?: string; q?: string; page?: string }>;
}) {
  await requireAdmin();
  const params = await searchParams;
  const status: StatusFilter = isStatusFilter(params.status) ? params.status : "all";
  const page = Math.max(1, Number(params.page ?? "1") || 1);
  const perPage = 50;
  const query = (params.q ?? "").trim();

  const whereParts = [] as ReturnType<typeof eq>[];
  if (status !== "all") whereParts.push(eq(emailLog.status, status));
  if (query) {
    whereParts.push(sql`${emailLog.recipient} ILIKE ${"%" + query + "%"} OR ${emailLog.subject} ILIKE ${"%" + query + "%"}`);
  }
  const whereClause = whereParts.length > 0 ? and(...whereParts) : undefined;

  const [{ total }] = await db
    .select({ total: sql<number>`count(*)`.mapWith(Number) })
    .from(emailLog)
    .where(whereClause ?? sql`true`);

  const rows = await db
    .select()
    .from(emailLog)
    .where(whereClause ?? sql`true`)
    .orderBy(desc(emailLog.createdAt))
    .limit(perPage)
    .offset((page - 1) * perPage);

  const [counts] = await db
    .select({
      total: sql<number>`count(*)`.mapWith(Number),
      sent: sql<number>`count(*) filter (where ${emailLog.status} = 'sent')`.mapWith(Number),
      failed: sql<number>`count(*) filter (where ${emailLog.status} = 'failed')`.mapWith(Number),
      dev: sql<number>`count(*) filter (where ${emailLog.status} = 'dev_console')`.mapWith(Number),
    })
    .from(emailLog);

  const totalPages = Math.max(1, Math.ceil(total / perPage));

  const columns: Column<EmailLogEntry>[] = [
    {
      key: "when",
      header: "When",
      cell: (r) => formatAdminDateTime(r.createdAt),
      className: "whitespace-nowrap text-[12px] text-[var(--color-slate)]",
    },
    {
      key: "status",
      header: "Status",
      cell: (r) => {
        if (r.status === "sent")
          return <StatusBadge label="sent" tone="accent" dot />;
        if (r.status === "failed")
          return <StatusBadge label="failed" tone="warning" dot />;
        if (r.status === "dev_console")
          return <StatusBadge label="dev" dot />;
        return <StatusBadge label={r.status} dot />;
      },
      className: "whitespace-nowrap",
    },
    {
      key: "recipient",
      header: "Recipient",
      cell: (r) => r.recipient,
      className: "truncate max-w-[240px]",
    },
    {
      key: "subject",
      header: "Subject",
      cell: (r) => r.subject,
      className: "truncate max-w-[380px]",
    },
    {
      key: "template",
      header: "Template",
      cell: (r) =>
        r.templateSlug ? (
          <code className="rounded bg-[var(--color-mist)] px-1.5 py-0.5 text-[11px] font-mono text-[var(--color-blue)]">
            {r.templateSlug}
          </code>
        ) : (
          <span className="text-[12px] text-[var(--color-slate)]">—</span>
        ),
    },
    {
      key: "details",
      header: "Details",
      cell: (r) =>
        r.errorMessage ? (
          <span className="text-[12px] text-red-700">{r.errorMessage}</span>
        ) : (
          <span className="text-[12px] text-[var(--color-slate)] line-clamp-1">
            {r.bodyPreview.slice(0, 80)}
          </span>
        ),
    },
  ];

  const buildHref = (patch: Partial<{ status: StatusFilter; page: number }>) => {
    const s = patch.status ?? status;
    const p = patch.page ?? page;
    const parts: string[] = [];
    if (s !== "all") parts.push(`status=${s}`);
    if (p !== 1) parts.push(`page=${p}`);
    if (query) parts.push(`q=${encodeURIComponent(query)}`);
    return `/admin/emails${parts.length ? `?${parts.join("&")}` : ""}`;
  };

  return (
    <>
      <AdminHeading
        eyebrow="System"
        title="Email delivery log"
        lede="Every transactional email the site has sent, dev-console included. Failed deliveries show the provider error."
      />

      <div className="mb-6 grid grid-cols-2 gap-4 lg:grid-cols-4">
        <KpiCard label="Total" value={counts.total} tone="ink" Icon={Mail} />
        <KpiCard label="Sent" value={counts.sent} tone="emerald" Icon={CheckCircle2} />
        <KpiCard label="Failed" value={counts.failed} tone="red" Icon={XCircle} />
        <KpiCard label="Dev console" value={counts.dev} tone="slate" Icon={Terminal} />
      </div>

      <div className="mb-4">
        <Toolbar
          actions={
            <form method="GET" action="/admin/emails">
              {status !== "all" && <input type="hidden" name="status" value={status} />}
              <SearchInput
                defaultValue={params.q ?? ""}
                placeholder="Search by recipient or subject…"
              />
            </form>
          }
        >
          <div className="flex flex-wrap items-center gap-1.5">
            <span className="text-[10px] font-bold uppercase tracking-[0.15em] text-[var(--color-slate)]">
              Status
            </span>
            {STATUS_FILTERS.map((s) => (
              <FilterPill
                key={s}
                href={buildHref({ status: s, page: 1 })}
                label={s === "dev_console" ? "dev" : s}
                active={status === s}
              />
            ))}
          </div>
        </Toolbar>
      </div>

      {rows.length === 0 ? (
        <EmptyState
          Icon={Mail}
          title="No email activity"
          description="Once the site sends an email, it will appear here."
        />
      ) : (
        <>
          <DataTable columns={columns} rows={rows} rowKey={(r) => r.id} />
          {totalPages > 1 && (
            <div className="mt-4 flex items-center justify-between text-[13px] text-[var(--color-slate)]">
              <span>
                Page {page} of {totalPages}
              </span>
              <div className="flex gap-2">
                {page > 1 && (
                  <a
                    href={buildHref({ page: page - 1 })}
                    className="rounded-md border border-[var(--color-line)] px-3 py-1 font-semibold text-[var(--color-ink)] hover:bg-[var(--color-mist)]"
                  >
                    Previous
                  </a>
                )}
                {page < totalPages && (
                  <a
                    href={buildHref({ page: page + 1 })}
                    className="rounded-md border border-[var(--color-line)] px-3 py-1 font-semibold text-[var(--color-ink)] hover:bg-[var(--color-mist)]"
                  >
                    Next
                  </a>
                )}
              </div>
            </div>
          )}
          {counts.dev > 0 && (
            <div className="mt-4 flex items-start gap-2 rounded-md border border-amber-200 bg-amber-50 p-3 text-[12px] text-amber-900">
              <AlertTriangle className="mt-0.5 h-4 w-4 shrink-0" aria-hidden />
              <span>
                <strong>Dev mode:</strong> RESEND_API_KEY is not set — emails
                are printed to the server console instead of being delivered.
                Configure Resend in production.
              </span>
            </div>
          )}
        </>
      )}
    </>
  );
}
