"use client";

import { useEffect, useMemo, useState } from "react";
import Link from "next/link";
import { useParams } from "next/navigation";
import useSWR from "swr";
import {
  ArrowLeft,
  CircleAlert,
  FilePenLine,
  Printer,
  RotateCcw,
  Save,
  Sparkles,
} from "lucide-react";
import { toast } from "sonner";
import type {
  Desa,
  Paginated,
  Penduduk,
  PermohonanSuratDetail,
  SuratJenis,
} from "@/lib/types";
import { ApiError, apiSend, fetcher } from "@/lib/api";
import { useSession } from "@/lib/use-session";
import { buildSampleIsian, getSuratTemplate } from "@/lib/surat/templates";
import {
  hasTemplateOverride,
  parseTemplateOverride,
  splitParagraphs,
} from "@/lib/surat/override";
import type { SuratData } from "@/lib/surat/types";
import { SuratDocument } from "@/components/surat/surat-document";
import { SuratDataForm } from "@/components/surat/surat-data-form";
import { Badge } from "@/components/ui/badge";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";
import { Select } from "@/components/ui/select";
import { Textarea } from "@/components/ui/textarea";

export default function TemplateSuratEditorPage() {
  const params = useParams<{ jenisId: string }>();
  const jenisId = Number(params?.jenisId);

  const { user } = useSession();
  const isAdmin = user?.role === "ADMIN";

  const { data: jenisList, isLoading: jenisLoading, mutate: mutateJenis } =
    useSWR<SuratJenis[]>("/surat/jenis", fetcher);
  const { data: desa } = useSWR<Desa>("/desa", fetcher);
  const { data: pendudukList } = useSWR<Paginated<Penduduk>>(
    "/penduduk?limit=200",
    fetcher,
  );

  const jenis = (jenisList ?? []).find((item) => item.id === jenisId);
  const wargaList = pendudukList?.data ?? [];

  const [pendudukId, setPendudukId] = useState("");
  const [keperluan, setKeperluan] = useState("");
  const [data, setData] = useState<SuratData>({});

  const [judul, setJudul] = useState("");
  const [pembuka, setPembuka] = useState("");
  const [isi, setIsi] = useState("");
  const [penutup, setPenutup] = useState("");
  const [loadedJenisId, setLoadedJenisId] = useState<number | null>(null);
  const [savingTemplate, setSavingTemplate] = useState(false);
  const [resetting, setResetting] = useState(false);
  const [tanggalSurat] = useState(() => new Date());

  const { data: wargaDetail, isLoading: wargaLoading } = useSWR<Penduduk>(
    pendudukId ? `/penduduk/${pendudukId}` : null,
    fetcher,
  );

  const baseTemplate = useMemo(
    () => getSuratTemplate(jenis?.urlSurat, jenis?.nama),
    [jenis?.urlSurat, jenis?.nama],
  );

  useEffect(() => {
    if (!jenis || jenis.id === loadedJenisId) return;
    const override = parseTemplateOverride(jenis.template);
    const base = getSuratTemplate(jenis.urlSurat, jenis.nama);
    setJudul(override?.judul ?? base.judul);
    setPembuka(override?.pembuka ?? base.pembuka);
    setIsi(override?.isi ?? base.isi.join("\n\n"));
    setPenutup(override?.penutup ?? base.penutup);
    setLoadedJenisId(jenis.id);
  }, [jenis, loadedJenisId]);

  useEffect(() => {
    if (!pendudukId && wargaList.length > 0) {
      setPendudukId(String(wargaList[0].id));
    }
  }, [pendudukId, wargaList]);

  const template = useMemo(
    () => ({
      ...baseTemplate,
      judul: judul.trim() || baseTemplate.judul,
      pembuka,
      isi: splitParagraphs(isi),
      penutup,
    }),
    [baseTemplate, judul, pembuka, isi, penutup],
  );

  const missing = template.fields.filter(
    (field) => field.required && !data[field.key]?.trim(),
  );

  const warga = wargaDetail as unknown as
    | PermohonanSuratDetail["penduduk"]
    | undefined;

  const suratPreview: PermohonanSuratDetail | null =
    jenis && warga
      ? {
          id: 0,
          nomor: `${jenis.kode}/PREVIEW/${tanggalSurat.getFullYear()}`,
          jenisId: jenis.id,
          pendudukId: warga.id,
          keperluan: keperluan.trim() || "……………………………",
          pemohon: warga.nama,
          status: "SELESAI",
          catatan: null,
          terlapor: false,
          dataIsian: data,
          tanggal: tanggalSurat.toISOString(),
          noAntrean: null,
          dibuatOleh: null,
          diprosesOleh: null,
          ditandatanganiOleh: null,
          selesaiPada: null,
          jenis,
          penduduk: warga,
        }
      : null;

  async function saveTemplate() {
    if (!jenis) return;
    setSavingTemplate(true);
    try {
      await apiSend(`/surat/jenis/${jenis.id}`, "PATCH", {
        template: JSON.stringify({ judul, pembuka, isi, penutup }),
      });
      toast.success("Teks template surat disimpan");
      await mutateJenis();
    } catch (error) {
      toast.error(
        error instanceof ApiError ? error.message : "Gagal menyimpan template",
      );
    } finally {
      setSavingTemplate(false);
    }
  }

  async function resetTemplate() {
    if (!jenis) return;
    setResetting(true);
    try {
      await apiSend(`/surat/jenis/${jenis.id}`, "PATCH", { template: "" });
      setJudul(baseTemplate.judul);
      setPembuka(baseTemplate.pembuka);
      setIsi(baseTemplate.isi.join("\n\n"));
      setPenutup(baseTemplate.penutup);
      toast.success("Template dikembalikan ke teks bawaan");
      await mutateJenis();
    } catch (error) {
      toast.error(
        error instanceof ApiError ? error.message : "Gagal mengembalikan template",
      );
    } finally {
      setResetting(false);
    }
  }

  if (user && user.role !== "ADMIN" && user.role !== "OPERATOR") {
    return (
      <div className="flex min-h-screen flex-col items-center justify-center gap-3 px-6 text-center text-sm">
        <p className="text-lg font-bold">Akses ditolak</p>
        <p className="text-muted-foreground">
          Peran {user.role} tidak memiliki izin membuka template surat.
        </p>
        <Link className="text-primary underline" href="/admin">
          Kembali ke dasbor
        </Link>
      </div>
    );
  }

  if (jenisLoading) {
    return (
      <div className="flex min-h-screen items-center justify-center text-sm text-muted-foreground">
        Memuat template…
      </div>
    );
  }

  if (!jenis) {
    return (
      <div className="flex min-h-screen flex-col items-center justify-center gap-3 text-sm">
        <p className="font-semibold">Template surat tidak ditemukan</p>
        <Link className="text-primary underline" href="/admin/cetak-surat">
          Kembali ke daftar template
        </Link>
      </div>
    );
  }

  return (
    <div className="min-h-screen bg-slate-100 print:bg-white">
      <div className="no-print sticky top-0 z-30 border-b border-border bg-white/90 backdrop-blur">
        <div className="mx-auto flex max-w-[1480px] flex-wrap items-center justify-between gap-3 px-4 py-3">
          <div className="flex items-center gap-3">
            <Button variant="outline" size="sm" asChild>
              <Link href="/admin/cetak-surat">
                <ArrowLeft className="h-4 w-4" />
                Kembali
              </Link>
            </Button>
            <div>
              <div className="flex flex-wrap items-center gap-2">
                <p className="text-sm font-semibold">{template.nama}</p>
                <Badge variant="info">{template.kode}</Badge>
                <Badge variant="secondary">{template.kategori}</Badge>
                {hasTemplateOverride(jenis.template) && (
                  <Badge variant="warning">Teks disesuaikan</Badge>
                )}
              </div>
              <p className="text-[11px] text-muted-foreground">
                Template surat · {template.fields.length} isian · pratinjau A4
              </p>
            </div>
          </div>
          <div className="flex items-center gap-2">
            {isAdmin && (
              <Button
                variant="outline"
                size="sm"
                onClick={saveTemplate}
                disabled={savingTemplate}
              >
                <Save className="h-4 w-4" />
                {savingTemplate ? "Menyimpan…" : "Simpan template"}
              </Button>
            )}
            <Button
              size="sm"
              onClick={() => window.print()}
              disabled={!suratPreview}
            >
              <Printer className="h-4 w-4" />
              Cetak / PDF
            </Button>
          </div>
        </div>
      </div>

      <div className="mx-auto grid max-w-[1480px] gap-6 px-4 py-6 xl:grid-cols-[400px_minmax(0,1fr)] print:block print:max-w-none print:p-0">
        <aside className="no-print space-y-4 self-start xl:sticky xl:top-[76px]">
          <div className="rounded-xl border border-border bg-white p-4 shadow-sm">
            <div className="flex items-start gap-2">
              <span className="mt-0.5 flex h-8 w-8 shrink-0 items-center justify-center rounded-lg bg-secondary text-primary">
                <Sparkles className="h-4 w-4" />
              </span>
              <div>
                <p className="text-sm font-semibold">Pemohon & keperluan</p>
                <p className="text-xs text-muted-foreground">
                  Pilih warga untuk mengisi identitas otomatis.
                </p>
              </div>
            </div>

            <div className="mt-3 space-y-3">
              <div className="space-y-1.5">
                <Label htmlFor="pemohon-template" className="text-xs">
                  Data warga
                </Label>
                <Select
                  id="pemohon-template"
                  value={pendudukId}
                  onChange={(event) => setPendudukId(event.target.value)}
                >
                  <option value="">Pilih penduduk</option>
                  {wargaList.map((wargaItem) => (
                    <option key={wargaItem.id} value={wargaItem.id}>
                      {wargaItem.nama} · {wargaItem.nik}
                    </option>
                  ))}
                </Select>
              </div>

              <div className="space-y-1.5">
                <Label htmlFor="keperluan-template" className="text-xs">
                  Keperluan surat
                </Label>
                <Input
                  id="keperluan-template"
                  value={keperluan}
                  onChange={(event) => setKeperluan(event.target.value)}
                  placeholder="Contoh: persyaratan administrasi bank"
                />
              </div>

              <Button
                type="button"
                variant="outline"
                size="sm"
                className="w-full"
                onClick={() => setData(buildSampleIsian(baseTemplate))}
              >
                <Sparkles className="h-4 w-4" />
                Isi data contoh
              </Button>
            </div>

            {missing.length > 0 && (
              <div className="mt-3 flex items-start gap-2 rounded-lg border border-amber-200 bg-amber-50 px-3 py-2 text-[11px] leading-relaxed text-amber-900">
                <CircleAlert className="mt-0.5 h-3.5 w-3.5 shrink-0" />
                <span>
                  {missing.length} data wajib belum terisi:{" "}
                  {missing.map((field) => field.label).join(", ")}.
                </span>
              </div>
            )}
          </div>

          {isAdmin && (
            <div className="rounded-xl border border-border bg-white p-4 shadow-sm">
              <div className="flex items-start justify-between gap-2">
                <div className="flex items-start gap-2">
                  <span className="mt-0.5 flex h-8 w-8 shrink-0 items-center justify-center rounded-lg bg-amber-100 text-amber-700">
                    <FilePenLine className="h-4 w-4" />
                  </span>
                  <div>
                    <p className="text-sm font-semibold">Teks template</p>
                    <p className="text-xs text-muted-foreground">
                      Berlaku untuk semua surat jenis ini.
                    </p>
                  </div>
                </div>
                <Badge variant={hasTemplateOverride(jenis.template) ? "warning" : "secondary"}>
                  {hasTemplateOverride(jenis.template) ? "Disesuaikan" : "Bawaan"}
                </Badge>
              </div>

              <div className="mt-3 space-y-3">
                <div className="space-y-1.5">
                  <Label htmlFor="template-judul" className="text-xs">
                    Judul surat
                  </Label>
                  <Input
                    id="template-judul"
                    value={judul}
                    onChange={(event) => setJudul(event.target.value)}
                  />
                </div>
                <div className="space-y-1.5">
                  <Label htmlFor="template-pembuka" className="text-xs">
                    Pembuka
                  </Label>
                  <Textarea
                    id="template-pembuka"
                    rows={2}
                    value={pembuka}
                    onChange={(event) => setPembuka(event.target.value)}
                  />
                </div>
                <div className="space-y-1.5">
                  <Label htmlFor="template-isi" className="text-xs">
                    Isi surat
                  </Label>
                  <Textarea
                    id="template-isi"
                    rows={7}
                    value={isi}
                    onChange={(event) => setIsi(event.target.value)}
                  />
                  <p className="text-[10px] leading-relaxed text-muted-foreground">
                    Pisahkan paragraf dengan baris kosong. Token seperti{" "}
                    <code>{"{nama}"}</code>, <code>{"{nik}"}</code>,{" "}
                    <code>{"{f:key_isian}"}</code> terisi otomatis.
                  </p>
                </div>
                <div className="space-y-1.5">
                  <Label htmlFor="template-penutup" className="text-xs">
                    Penutup
                  </Label>
                  <Textarea
                    id="template-penutup"
                    rows={2}
                    value={penutup}
                    onChange={(event) => setPenutup(event.target.value)}
                  />
                </div>
                <div className="flex gap-2">
                  <Button
                    type="button"
                    size="sm"
                    className="flex-1"
                    onClick={saveTemplate}
                    disabled={savingTemplate}
                  >
                    <Save className="h-4 w-4" />
                    {savingTemplate ? "Menyimpan…" : "Simpan"}
                  </Button>
                  <Button
                    type="button"
                    size="sm"
                    variant="outline"
                    onClick={resetTemplate}
                    disabled={resetting}
                  >
                    <RotateCcw className="h-4 w-4" />
                    {resetting ? "Reset…" : "Reset"}
                  </Button>
                </div>
              </div>
            </div>
          )}

          <div className="max-h-[calc(100vh-260px)] overflow-y-auto rounded-xl border border-border bg-white p-4 shadow-sm">
            <SuratDataForm
              template={baseTemplate}
              value={data}
              onChange={setData}
              idPrefix={`template-${jenis.id}`}
            />
          </div>

          <div className="rounded-xl border border-dashed border-border bg-white/60 px-4 py-3 text-[11px] text-muted-foreground">
            {isAdmin
              ? "Perubahan teks template disimpan ke jenis surat dan dipakai saat mencetak surat warga."
              : "Hanya admin yang dapat mengubah teks template. Anda tetap dapat mengisi data dan mencetak surat."}
          </div>
        </aside>

        <main className="min-w-0 print:contents">
          {wargaLoading ? (
            <div className="flex h-64 items-center justify-center rounded-xl border border-border bg-white text-sm text-muted-foreground">
              Memuat data warga…
            </div>
          ) : suratPreview ? (
            <SuratDocument
              template={template}
              surat={suratPreview}
              desa={desa}
              data={data}
            />
          ) : (
            <div className="flex h-64 items-center justify-center rounded-xl border border-dashed border-border bg-white text-sm text-muted-foreground">
              Pilih warga untuk menampilkan pratinjau surat.
            </div>
          )}
        </main>
      </div>
    </div>
  );
}
