"use client";

import clsx from "clsx";
import Link from "next/link";
import { useCallback, useEffect, useState } from "react";
import { FileText, Pencil, Plus, RefreshCw, Search, Trash2, X } from "lucide-react";
import { Badge, Button, ConfirmDialog, EmptyState, PageHeader, Panel, Skeleton } from "@/components/ui/kit";
import { useToast } from "@/components/ui/toast";
import { useSession } from "@/components/session";
import { TemplateBuilder } from "@/components/templates/template-builder";
import { componentsToBubble, PreviewFrame, TemplateBubble } from "@/components/templates/template-preview";
import { api } from "@/lib/api";
import { formatDateTime } from "@/lib/format";
import { useApi } from "@/lib/use-api";
import type { MessageTemplate, WhatsAppConfig } from "@/lib/types";

const STATUS_TONE: Record<string, "teal" | "amber" | "brick" | "neutral"> = { APPROVED: "teal", PENDING: "amber", IN_APPEAL: "amber", REJECTED: "brick", PAUSED: "brick", DISABLED: "brick" };
const STATUS_LABEL: Record<string, string> = { APPROVED: "Approved", PENDING: "In review", REJECTED: "Rejected", PAUSED: "Paused", DISABLED: "Disabled", IN_APPEAL: "In appeal" };
const FILTERS = [
  ["", "All"],
  ["APPROVED", "Approved"],
  ["PENDING", "In review"],
  ["REJECTED", "Rejected"],
] as const;

function TemplateDrawer({ template, config, canManage, onClose, onEdit, onDelete, onChanged }: { template: MessageTemplate; config: WhatsAppConfig | null; canManage: boolean; onClose: () => void; onEdit: () => void; onDelete: () => void; onChanged: () => void }) {
  const toast = useToast();
  const [busy, setBusy] = useState<string | null>(null);
  useEffect(() => {
    const k = (e: KeyboardEvent) => e.key === "Escape" && onClose();
    window.addEventListener("keydown", k);
    return () => window.removeEventListener("keydown", k);
  }, [onClose]);
  async function review(status: string) {
    setBusy(status);
    try {
      await api.post(`/templates/${template.id}/simulate-review`, { status, reason: status === "REJECTED" ? "INVALID_FORMAT" : undefined });
      onChanged();
    } catch (e) {
      toast("error", (e as Error).message);
    } finally {
      setBusy(null);
    }
  }
  const v = template.variables;
  return (
    <div className="fixed inset-0 z-40">
      <div className="absolute inset-0 bg-ink/30" onClick={onClose} />
      <div role="dialog" aria-modal="true" aria-label={`Template ${template.name}`} className="drawer-in absolute inset-y-0 right-0 flex w-full max-w-[460px] flex-col bg-white shadow-2xl">
        <header className="flex items-start gap-3 border-b border-line px-6 py-5">
          <div className="min-w-0 flex-1">
            <h2 className="truncate text-lg font-semibold">{template.name}</h2>
            <div className="mt-1 flex flex-wrap items-center gap-2 text-sm text-muted">
              <Badge tone={STATUS_TONE[template.status] ?? "neutral"}>{STATUS_LABEL[template.status] ?? template.status}</Badge>
              <span>{template.language}</span>
              <span className="capitalize">{template.category.toLowerCase()}</span>
            </div>
          </div>
          <button onClick={onClose} aria-label="Close" className="rounded p-1 text-muted hover:bg-paper">
            <X className="size-5" />
          </button>
        </header>
        <div className="flex-1 space-y-6 overflow-y-auto px-6 py-5">
          {template.rejected_reason && (
            <p className="rounded-md bg-brick-soft px-3 py-2 text-sm text-brick">
              Meta {template.status === "REJECTED" ? "rejected" : "flagged"} this template: <span className="font-medium">{template.rejected_reason.replace(/_/g, " ").toLowerCase()}</span>. Edit it and submit again.
            </p>
          )}
          {template.status === "PENDING" && <p className="rounded-md bg-amber-soft px-3 py-2 text-sm text-amber">Meta is reviewing this template. You can send it once it&apos;s approved.</p>}
          <PreviewFrame>
            <TemplateBubble {...componentsToBubble(template.components)} />
          </PreviewFrame>
          <dl className="grid grid-cols-[130px_1fr] gap-x-4 gap-y-2 text-sm">
            <dt className="text-muted">Variables</dt>
            <dd>{[...v.header.variables.map((x) => `header {{${x}}}`), ...v.body.map((x) => `{{${x}}}`), ...v.buttons.filter((b) => b.variable).map((b) => `“${b.text}” link`)].join(", ") || "None"}</dd>
            <dt className="text-muted">Variable style</dt>
            <dd>{template.parameter_format === "NAMED" ? "Named" : "Numbered"}</dd>
            {template.quality_score && (
              <>
                <dt className="text-muted">Quality</dt>
                <dd>{template.quality_score}</dd>
              </>
            )}
            <dt className="text-muted">Last synced</dt>
            <dd>{formatDateTime(template.last_synced_at)}</dd>
          </dl>
          {config?.mode === "simulation" && canManage && template.status !== "APPROVED" && (
            <div className="rounded-lg border border-dashed border-amber/40 bg-amber-soft/40 p-4 text-sm">
              <p className="mb-3 text-muted">Simulation mode: act as Meta&apos;s reviewer. The decision arrives through the same webhook Meta uses.</p>
              <div className="flex gap-2">
                <Button size="sm" loading={busy === "APPROVED"} onClick={() => review("APPROVED")}>
                  Approve
                </Button>
                <Button size="sm" loading={busy === "REJECTED"} onClick={() => review("REJECTED")}>
                  Reject
                </Button>
              </div>
            </div>
          )}
        </div>
        {canManage && (
          <footer className="flex gap-2 border-t border-line px-6 py-3">
            {template.editable && (
              <Button icon={<Pencil className="size-4" />} onClick={onEdit}>
                Edit
              </Button>
            )}
            <Button variant="ghost" className="hover:bg-brick-soft hover:text-brick" icon={<Trash2 className="size-4" />} onClick={onDelete}>
              Delete
            </Button>
          </footer>
        )}
      </div>
    </div>
  );
}

export default function TemplatesPage() {
  const { can } = useSession();
  const toast = useToast();
  const canManage = can("templates.manage");
  const [status, setStatus] = useState("");
  const [q, setQ] = useState("");
  const list = useApi<{ data: MessageTemplate[]; meta: { account_id?: number; waba_id: string | null; last_synced_at: string | null } }>(`/templates${status ? `?status=${status}` : ""}`);
  const configReq = useApi<{ data: WhatsAppConfig }>("/whatsapp/config");
  const [syncing, setSyncing] = useState(false);
  const [builder, setBuilder] = useState<{ template?: MessageTemplate } | null>(null);
  const [openId, setOpenId] = useState<number | null>(null);
  const [toDelete, setToDelete] = useState<MessageTemplate | null>(null);
  const [deleting, setDeleting] = useState(false);
  const closeDrawer = useCallback(() => setOpenId(null), []);

  const all = list.data?.data;
  const rows = all?.filter((t) => !q || t.name.includes(q.toLowerCase().trim()));
  const noAccount = list.data && !list.data.meta.waba_id;
  const open = all?.find((t) => t.id === openId) ?? null;

  async function sync() {
    setSyncing(true);
    try {
      const r = await api.post<{ data: { created: number; updated: number; total: number } }>("/templates/sync", { account_id: list.data?.meta.account_id });
      toast("success", `Synced ${r.data.total} templates from Meta`);
      list.reload();
    } catch (e) {
      toast("error", (e as Error).message);
    } finally {
      setSyncing(false);
    }
  }

  async function remove() {
    if (!toDelete) return;
    setDeleting(true);
    try {
      await api.delete(`/templates/${toDelete.id}`);
      toast("success", `Deleted ${toDelete.name}`);
      setToDelete(null);
      setOpenId(null);
      list.reload();
    } catch (e) {
      toast("error", (e as Error).message);
    } finally {
      setDeleting(false);
    }
  }

  return (
    <>
      <PageHeader
        title="Templates"
        description="Pre-approved messages you can send anytime: to start conversations, follow up after 24 hours, and in campaigns."
        actions={
          canManage &&
          !noAccount && (
            <>
              <Button icon={<RefreshCw className={clsx("size-4", syncing && "animate-spin")} />} onClick={sync} disabled={syncing}>
                Sync from Meta
              </Button>
              <Button variant="primary" icon={<Plus className="size-4" />} onClick={() => setBuilder({})}>
                New template
              </Button>
            </>
          )
        }
      />

      {noAccount ? (
        <Panel>
          <EmptyState
            icon={<FileText className="size-5" />}
            title="Connect WhatsApp first"
            body="Templates belong to your WhatsApp Business Account. Connect a number, then sync or create templates here."
            action={
              <Link href="/settings/whatsapp">
                <Button variant="primary">Go to WhatsApp setup</Button>
              </Link>
            }
          />
        </Panel>
      ) : (
        <Panel>
          <div className="flex flex-wrap items-center gap-3 border-b border-line p-3">
            <div role="tablist" aria-label="Status" className="flex gap-1">
              {FILTERS.map(([value, label]) => (
                <button
                  key={value}
                  role="tab"
                  aria-selected={status === value}
                  onClick={() => setStatus(value)}
                  className={clsx("rounded-md px-3 py-1.5 text-sm font-medium", status === value ? "bg-teal-soft text-teal" : "text-muted hover:bg-paper hover:text-text")}
                >
                  {label}
                </button>
              ))}
            </div>
            <label className="relative ml-auto min-w-[200px]">
              <span className="sr-only">Search templates</span>
              <Search className="pointer-events-none absolute left-3 top-1/2 size-4 -translate-y-1/2 text-muted" />
              <input value={q} onChange={(e) => setQ(e.target.value)} placeholder="Search by name" className="h-9 w-full rounded-md border border-line pl-9 pr-3 text-sm focus:border-teal focus:outline-none focus:ring-2 focus:ring-teal/15" />
            </label>
          </div>
          {!rows ? (
            <div className="space-y-3 p-4">
              {Array.from({ length: 4 }).map((_, i) => (
                <Skeleton key={i} className="h-6 w-full" />
              ))}
            </div>
          ) : rows.length === 0 ? (
            <EmptyState
              icon={<FileText className="size-5" />}
              title={all?.length || status || q ? "No templates match" : "No templates yet"}
              body={all?.length || status || q ? "Try another filter or search." : "Sync the templates you already have in WhatsApp Manager, or create a new one for Meta to review."}
              action={
                canManage && !all?.length && !status && (
                  <div className="flex gap-2">
                    <Button onClick={sync} loading={syncing}>
                      Sync from Meta
                    </Button>
                    <Button variant="primary" onClick={() => setBuilder({})}>
                      New template
                    </Button>
                  </div>
                )
              }
            />
          ) : (
            <div className="relative overflow-x-auto">
              <table className="w-full min-w-[640px] text-sm">
                <thead>
                  <tr className="border-b border-line text-left text-[13px] text-muted">
                    <th className="px-4 py-2.5 font-medium">Name</th>
                    <th className="px-4 py-2.5 font-medium">Category</th>
                    <th className="px-4 py-2.5 font-medium">Language</th>
                    <th className="px-4 py-2.5 font-medium">Status</th>
                    <th className="px-4 py-2.5 font-medium">Preview</th>
                  </tr>
                </thead>
                <tbody>
                  {rows.map((t) => (
                    <tr key={t.id} className="border-b border-line last:border-0 hover:bg-paper/70">
                      <td className="px-4 py-3">
                        <button onClick={() => setOpenId(t.id)} className="font-medium text-ink hover:text-teal hover:underline">
                          {t.name}
                        </button>
                      </td>
                      <td className="px-4 py-3 capitalize text-muted">{t.category.toLowerCase()}</td>
                      <td className="px-4 py-3 text-muted">{t.language}</td>
                      <td className="px-4 py-3">
                        <Badge tone={STATUS_TONE[t.status] ?? "neutral"}>{STATUS_LABEL[t.status] ?? t.status}</Badge>
                      </td>
                      <td className="max-w-sm truncate px-4 py-3 text-muted">{componentsToBubble(t.components).body}</td>
                    </tr>
                  ))}
                </tbody>
              </table>
            </div>
          )}
          {list.data?.meta.last_synced_at && <p className="border-t border-line px-4 py-2.5 text-xs text-muted">Last synced with Meta {formatDateTime(list.data.meta.last_synced_at)}</p>}
        </Panel>
      )}

      {open && (
        <TemplateDrawer
          key={open.id}
          template={open}
          config={configReq.data?.data ?? null}
          canManage={canManage}
          onClose={closeDrawer}
          onEdit={() => setBuilder({ template: open })}
          onDelete={() => setToDelete(open)}
          onChanged={list.reload}
        />
      )}
      {builder && (
        <TemplateBuilder
          key={builder.template?.id ?? "new"}
          template={builder.template}
          accountId={list.data?.meta.account_id}
          onClose={() => setBuilder(null)}
          onSaved={(t) => {
            setBuilder(null);
            list.reload();
            setOpenId(t.id);
          }}
        />
      )}
      <ConfirmDialog
        open={!!toDelete}
        title={`Delete ${toDelete?.name}?`}
        message={`The ${toDelete?.language} version is deleted from your WhatsApp Business Account. If it was approved, Meta won't let you reuse the name for 30 days.`}
        confirmLabel="Delete template"
        loading={deleting}
        onConfirm={remove}
        onClose={() => setToDelete(null)}
      />
    </>
  );
}
