import { redirect } from "next/navigation";
import { getServerSession } from "next-auth";
import { authOptions } from "@/lib/auth";
import { isAdminEmail } from "@/lib/admin";
import { emailRepo } from "@/server/repositories/email.repo";
import {
  RetryEmailButton,
  ResendEmailButton,
} from "@/features/email/components/email-row-actions";

type Tab = "failed" | "queue" | "sent";

const TABS: { key: Tab; label: string }[] = [
  { key: "failed", label: "Gagal" },
  { key: "queue", label: "Antrian" },
  { key: "sent", label: "Terkirim" },
];

interface PageProps {
  searchParams: Promise<{ tab?: string; to?: string; template?: string }>;
}

export default async function AdminEmailsPage({ searchParams }: PageProps) {
  const session = await getServerSession(authOptions);
  if (!session?.user) redirect("/login?callbackUrl=/admin/emails");
  if (!isAdminEmail(session.user.email)) {
    return (
      <div className="mx-auto max-w-2xl px-4 py-12 text-center">
        <p className="text-sm text-neutral-600">
          Halaman ini hanya untuk admin SeTrip.
        </p>
      </div>
    );
  }

  const params = await searchParams;
  const tab: Tab = TABS.some((t) => t.key === params.tab)
    ? (params.tab as Tab)
    : "failed";
  const filters = {
    to: params.to?.trim() || undefined,
    template: params.template?.trim() || undefined,
  };

  const stats = await emailRepo.stats();
  const jobs =
    tab === "sent"
      ? []
      : await emailRepo.listJobs(
          tab === "failed" ? ["FAILED"] : ["PENDING", "PROCESSING"],
          filters
        );
  const sent = tab === "sent" ? await emailRepo.listSent(filters) : [];

  return (
    <div className="mx-auto max-w-5xl px-4 py-8 sm:py-12">
      <header className="mb-6">
        <h1 className="text-2xl font-bold text-neutral-900 sm:text-3xl">
          Email Log
        </h1>
        <p className="mt-1 text-sm text-neutral-500">
          Pantau pengiriman email transaksional. Email yang gagal dikirim bisa
          di-retry manual; email terkirim bisa di-resend kalau peserta lapor
          tidak menerima.
        </p>
      </header>

      {/* Kartu ringkasan */}
      <div className="mb-6 grid gap-3 sm:grid-cols-3">
        <StatCard
          label="Antri dikirim"
          value={stats.queued}
          tone={stats.queued > 0 ? "amber" : "ok"}
          hint="Job menunggu cron / retry"
        />
        <StatCard
          label="Gagal 24 jam"
          value={stats.failed24h}
          tone={stats.failed24h > 0 ? "red" : "ok"}
          hint="Job gagal dalam sehari terakhir"
        />
        <StatCard
          label="Perlu aksi manual"
          value={stats.deadLetter}
          tone={stats.deadLetter > 0 ? "red" : "ok"}
          hint="Gagal & habis 5 attempt — cron berhenti retry"
        />
      </div>

      {/* Tabs */}
      <div className="mb-4 flex flex-wrap gap-2">
        {TABS.map((t) => (
          <a
            key={t.key}
            href={`/admin/emails?tab=${t.key}`}
            className={`rounded-full px-4 py-1.5 text-sm font-semibold transition-colors ${
              tab === t.key
                ? "bg-primary-600 text-white"
                : "bg-neutral-100 text-neutral-600 hover:bg-neutral-200"
            }`}
          >
            {t.label}
          </a>
        ))}
      </div>

      {/* Filter */}
      <form
        method="get"
        action="/admin/emails"
        className="mb-4 flex flex-wrap items-end gap-2 rounded-2xl border border-neutral-200 bg-white p-3 shadow-sm"
      >
        <input type="hidden" name="tab" value={tab} />
        <div className="min-w-[180px] flex-1">
          <label
            htmlFor="filter-to"
            className="mb-1 block text-[10px] font-semibold uppercase tracking-wide text-neutral-500"
          >
            Penerima (email)
          </label>
          <input
            id="filter-to"
            name="to"
            defaultValue={params.to ?? ""}
            placeholder="user@email.com"
            className="w-full rounded-lg border border-neutral-200 bg-neutral-50 px-2 py-1.5 text-sm text-neutral-800 focus:border-primary-400 focus:bg-white"
          />
        </div>
        <div className="min-w-[160px] flex-1">
          <label
            htmlFor="filter-template"
            className="mb-1 block text-[10px] font-semibold uppercase tracking-wide text-neutral-500"
          >
            Template
          </label>
          <input
            id="filter-template"
            name="template"
            defaultValue={params.template ?? ""}
            placeholder="mis. refund_succeeded"
            className="w-full rounded-lg border border-neutral-200 bg-neutral-50 px-2 py-1.5 text-sm text-neutral-800 focus:border-primary-400 focus:bg-white"
          />
        </div>
        <button
          type="submit"
          className="rounded-lg bg-primary-600 px-4 py-1.5 text-sm font-semibold text-white hover:bg-primary-700"
        >
          Cari
        </button>
        {(filters.to || filters.template) && (
          <a
            href={`/admin/emails?tab=${tab}`}
            className="rounded-lg border border-neutral-200 bg-white px-3 py-1.5 text-sm font-medium text-neutral-500 hover:bg-neutral-50"
          >
            Reset
          </a>
        )}
      </form>

      {tab === "sent" ? (
        <SentTable rows={sent} />
      ) : (
        <JobTable rows={jobs} tab={tab} />
      )}
    </div>
  );
}

function StatCard({
  label,
  value,
  tone,
  hint,
}: {
  label: string;
  value: number;
  tone: "ok" | "amber" | "red";
  hint: string;
}) {
  const cls =
    tone === "red"
      ? "border-red-200 bg-red-50/60"
      : tone === "amber"
        ? "border-amber-200 bg-amber-50/60"
        : "border-emerald-200 bg-emerald-50/50";
  const valueCls =
    tone === "red"
      ? "text-red-700"
      : tone === "amber"
        ? "text-amber-700"
        : "text-emerald-700";
  return (
    <div className={`rounded-2xl border p-4 shadow-sm ${cls}`}>
      <p className="text-[10px] font-semibold uppercase tracking-wide text-neutral-500">
        {label}
      </p>
      <p className={`mt-1 text-2xl font-bold ${valueCls}`}>{value}</p>
      <p className="mt-0.5 text-[11px] text-neutral-500">{hint}</p>
    </div>
  );
}

function JobTable({
  rows,
  tab,
}: {
  rows: Awaited<ReturnType<typeof emailRepo.listJobs>>;
  tab: "failed" | "queue";
}) {
  if (rows.length === 0) {
    return (
      <EmptyState
        message={
          tab === "failed"
            ? "Tidak ada email gagal — semua pengiriman lancar. 🎉"
            : "Tidak ada email yang sedang antri."
        }
      />
    );
  }
  return (
    <div className="overflow-x-auto rounded-2xl border border-neutral-200 bg-white shadow-sm">
      <table className="min-w-full divide-y divide-neutral-100 text-sm">
        <thead className="bg-neutral-50 text-[10px] font-semibold uppercase tracking-wide text-neutral-500">
          <tr>
            <th className="px-3 py-2 text-left">Penerima</th>
            <th className="px-3 py-2 text-left">Template</th>
            <th className="px-3 py-2 text-left">Status</th>
            <th className="px-3 py-2 text-left">Attempt</th>
            <th className="px-3 py-2 text-left">
              {tab === "failed" ? "Error terakhir" : "Dijadwalkan"}
            </th>
            <th className="px-3 py-2 text-left">Aksi</th>
          </tr>
        </thead>
        <tbody className="divide-y divide-neutral-100 text-xs text-neutral-700">
          {rows.map((r) => (
            <tr key={r.id}>
              <td className="px-3 py-2">{r.to}</td>
              <td className="px-3 py-2 font-mono">{r.template}</td>
              <td className="px-3 py-2">
                <EmailBadge value={r.status} />
              </td>
              <td className="px-3 py-2">
                {r.attempts}
                {r.attempts >= 5 && (
                  <span className="ml-1 text-[10px] font-semibold text-red-600">
                    (mati)
                  </span>
                )}
              </td>
              <td className="px-3 py-2 text-neutral-500">
                {tab === "failed"
                  ? r.lastError
                    ? truncate(r.lastError, 90)
                    : "—"
                  : formatDateTime(r.scheduledAt)}
              </td>
              <td className="px-3 py-2">
                <RetryEmailButton jobId={r.id} />
              </td>
            </tr>
          ))}
        </tbody>
      </table>
    </div>
  );
}

function SentTable({
  rows,
}: {
  rows: Awaited<ReturnType<typeof emailRepo.listSent>>;
}) {
  if (rows.length === 0) {
    return <EmptyState message="Belum ada email terkirim yang cocok." />;
  }
  return (
    <div className="overflow-x-auto rounded-2xl border border-neutral-200 bg-white shadow-sm">
      <table className="min-w-full divide-y divide-neutral-100 text-sm">
        <thead className="bg-neutral-50 text-[10px] font-semibold uppercase tracking-wide text-neutral-500">
          <tr>
            <th className="px-3 py-2 text-left">Penerima</th>
            <th className="px-3 py-2 text-left">Template</th>
            <th className="px-3 py-2 text-left">Subject</th>
            <th className="px-3 py-2 text-left">Terkirim</th>
            <th className="px-3 py-2 text-left">Aksi</th>
          </tr>
        </thead>
        <tbody className="divide-y divide-neutral-100 text-xs text-neutral-700">
          {rows.map((r) => (
            <tr key={r.id}>
              <td className="px-3 py-2">{r.to}</td>
              <td className="px-3 py-2 font-mono">{r.template}</td>
              <td className="px-3 py-2">{truncate(r.subject, 60)}</td>
              <td className="px-3 py-2 text-neutral-500">
                {formatDateTime(r.sentAt)}
              </td>
              <td className="px-3 py-2">
                <ResendEmailButton emailSentId={r.id} disabled={!r.html} />
              </td>
            </tr>
          ))}
        </tbody>
      </table>
    </div>
  );
}

function EmptyState({ message }: { message: string }) {
  return (
    <div className="rounded-2xl border border-dashed border-neutral-300 bg-white p-10 text-center">
      <p className="text-sm text-neutral-500">{message}</p>
    </div>
  );
}

function EmailBadge({ value }: { value: string }) {
  const cls =
    value === "SUCCESS"
      ? "bg-emerald-100 text-emerald-800"
      : value === "FAILED"
        ? "bg-red-100 text-red-800"
        : "bg-amber-100 text-amber-800";
  return (
    <span
      className={`inline-block rounded-full px-2 py-0.5 text-[10px] font-bold uppercase tracking-wide ${cls}`}
    >
      {value}
    </span>
  );
}

function formatDateTime(d: Date): string {
  return d.toLocaleString("id-ID", {
    day: "2-digit",
    month: "short",
    year: "numeric",
    hour: "2-digit",
    minute: "2-digit",
  });
}

function truncate(s: string, max: number): string {
  return s.length > max ? `${s.slice(0, max)}…` : s;
}
