"use client";

import { useEffect, useState } from "react";
import useSWR from "swr";
import {
  Eye,
  FilePenLine,
  Newspaper,
  Plus,
  Search,
  Send,
  Star,
  Tags,
  Trash2,
} from "lucide-react";
import { toast } from "sonner";
import type {
  Artikel,
  KategoriArtikel,
  Paginated,
} from "@/lib/types";
import { ApiError, apiSend, fetcher } from "@/lib/api";
import { useSession } from "@/lib/use-session";
import { PageHeader } from "@/components/page-header";
import { Pagination } from "@/components/pagination";
import { Badge } from "@/components/ui/badge";
import { Button } from "@/components/ui/button";
import { Card, CardContent } from "@/components/ui/card";
import {
  Dialog,
  DialogContent,
  DialogDescription,
  DialogFooter,
  DialogHeader,
  DialogTitle,
} from "@/components/ui/dialog";
import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";
import { Select } from "@/components/ui/select";
import {
  Table,
  TableBody,
  TableCell,
  TableHead,
  TableHeader,
  TableRow,
} from "@/components/ui/table";
import { Textarea } from "@/components/ui/textarea";
import { formatDateShort, stripHtml } from "@/lib/utils";

type ArtikelForm = {
  judul: string;
  ringkasan: string;
  isi: string;
  kategoriId: string;
  status: string;
  headline: boolean;
};

const emptyForm: ArtikelForm = {
  judul: "",
  ringkasan: "",
  isi: "",
  kategoriId: "",
  status: "DRAFT",
  headline: false,
};

export default function BeritaPage() {
  const { user } = useSession();

  const [page, setPage] = useState(1);
  const [search, setSearch] = useState("");
  const [q, setQ] = useState("");
  const [status, setStatus] = useState("");
  const [kategoriId, setKategoriId] = useState("");

  const [formOpen, setFormOpen] = useState(false);
  const [editing, setEditing] = useState<Artikel | null>(null);
  const [form, setForm] = useState<ArtikelForm>(emptyForm);
  const [saving, setSaving] = useState(false);

  const [kategoriOpen, setKategoriOpen] = useState(false);
  const [kategoriNama, setKategoriNama] = useState("");

  const [deleteTarget, setDeleteTarget] = useState<Artikel | null>(null);
  const [deleting, setDeleting] = useState(false);

  const query = new URLSearchParams({ page: String(page), limit: "10" });
  if (q) query.set("q", q);
  if (status) query.set("status", status);
  if (kategoriId) query.set("kategoriId", kategoriId);

  const { data, isLoading, mutate } = useSWR<Paginated<Artikel>>(
    `/artikel?${query.toString()}`,
    fetcher,
  );
  const { data: kategori, mutate: mutateKategori } = useSWR<KategoriArtikel[]>(
    "/artikel/kategori",
    fetcher,
  );

  const daftar = data?.data ?? [];

  useEffect(() => {
    setPage(1);
  }, [q, status, kategoriId]);

  function openCreate() {
    setEditing(null);
    setForm(emptyForm);
    setFormOpen(true);
  }

  function openEdit(artikel: Artikel) {
    setEditing(artikel);
    setForm({
      judul: artikel.judul,
      ringkasan: artikel.ringkasan ?? "",
      isi: artikel.isi,
      kategoriId: artikel.kategoriId ? String(artikel.kategoriId) : "",
      status: artikel.status,
      headline: artikel.headline,
    });
    setFormOpen(true);
  }

  async function save(event: React.FormEvent<HTMLFormElement>) {
    event.preventDefault();
    setSaving(true);
    try {
      const payload: Record<string, unknown> = {
        judul: form.judul,
        isi: form.isi,
        status: form.status,
        headline: form.headline,
      };
      if (form.ringkasan) payload.ringkasan = form.ringkasan;
      if (form.kategoriId) payload.kategoriId = Number(form.kategoriId);

      if (editing) {
        await apiSend(`/artikel/${editing.id}`, "PATCH", payload);
        toast.success("Artikel diperbarui");
      } else {
        await apiSend("/artikel", "POST", payload);
        toast.success(
          form.status === "TERBIT" ? "Artikel diterbitkan" : "Draft artikel disimpan",
        );
      }
      setFormOpen(false);
      setEditing(null);
      await mutate();
    } catch (error) {
      toast.error(error instanceof ApiError ? error.message : "Gagal menyimpan artikel");
    } finally {
      setSaving(false);
    }
  }

  async function toggleStatus(artikel: Artikel) {
    try {
      const next = artikel.status === "TERBIT" ? "DRAFT" : "TERBIT";
      await apiSend(`/artikel/${artikel.id}`, "PATCH", { status: next });
      toast.success(next === "TERBIT" ? "Artikel diterbitkan" : "Artikel dijadikan draft");
      await mutate();
    } catch (error) {
      toast.error(error instanceof ApiError ? error.message : "Gagal mengubah status");
    }
  }

  async function toggleHeadline(artikel: Artikel) {
    try {
      await apiSend(`/artikel/${artikel.id}`, "PATCH", {
        headline: !artikel.headline,
      });
      toast.success(artikel.headline ? "Headline dilepas" : "Artikel dijadikan headline");
      await mutate();
    } catch (error) {
      toast.error(error instanceof ApiError ? error.message : "Gagal mengubah headline");
    }
  }

  async function createKategori(event: React.FormEvent<HTMLFormElement>) {
    event.preventDefault();
    setSaving(true);
    try {
      await apiSend("/artikel/kategori", "POST", { nama: kategoriNama });
      toast.success("Kategori ditambahkan");
      setKategoriNama("");
      setKategoriOpen(false);
      await mutateKategori();
    } catch (error) {
      toast.error(error instanceof ApiError ? error.message : "Gagal menambah kategori");
    } finally {
      setSaving(false);
    }
  }

  async function remove() {
    if (!deleteTarget) return;
    setDeleting(true);
    try {
      await apiSend(`/artikel/${deleteTarget.id}`, "DELETE");
      toast.success("Artikel dihapus");
      setDeleteTarget(null);
      await mutate();
    } catch (error) {
      toast.error(error instanceof ApiError ? error.message : "Gagal menghapus artikel");
    } finally {
      setDeleting(false);
    }
  }

  return (
    <div className="animate-fade-in space-y-6">
      <PageHeader
        title="Berita & Publikasi"
        description={`Kelola artikel website desa. Masuk sebagai ${user?.nama ?? "pengguna"}.`}
        action={
          <div className="flex flex-wrap gap-2">
            <Button variant="outline" onClick={() => setKategoriOpen(true)}>
              <Tags className="h-4 w-4" />
              Kategori
            </Button>
            <Button onClick={openCreate}>
              <Plus className="h-4 w-4" />
              Tulis Artikel
            </Button>
          </div>
        }
      />

      <Card>
        <CardContent className="p-0">
          <div className="flex flex-col gap-3 border-b p-4 lg:flex-row lg:items-center lg:justify-between">
            <form
              onSubmit={(event) => {
                event.preventDefault();
                setQ(search.trim());
              }}
              className="relative w-full lg:max-w-sm"
            >
              <Search className="absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-muted-foreground" />
              <Input
                value={search}
                onChange={(event) => setSearch(event.target.value)}
                placeholder="Cari judul atau ringkasan…"
                className="pl-9"
              />
            </form>
            <div className="flex flex-wrap gap-2">
              <Select
                value={status}
                onChange={(event) => setStatus(event.target.value)}
                aria-label="Filter status"
                className="w-full sm:w-36"
              >
                <option value="">Semua status</option>
                <option value="TERBIT">Terbit</option>
                <option value="DRAFT">Draft</option>
              </Select>
              <Select
                value={kategoriId}
                onChange={(event) => setKategoriId(event.target.value)}
                aria-label="Filter kategori"
                className="w-full sm:w-44"
              >
                <option value="">Semua kategori</option>
                {(kategori ?? []).map((item) => (
                  <option key={item.id} value={item.id}>
                    {item.nama}
                  </option>
                ))}
              </Select>
              {(q || status || kategoriId) && (
                <Button
                  type="button"
                  variant="ghost"
                  onClick={() => {
                    setSearch("");
                    setQ("");
                    setStatus("");
                    setKategoriId("");
                  }}
                >
                  Reset
                </Button>
              )}
            </div>
          </div>

          {isLoading ? (
            <div className="space-y-2 p-4">
              {Array.from({ length: 6 }).map((_, index) => (
                <div key={index} className="h-14 animate-pulse rounded-lg bg-muted" />
              ))}
            </div>
          ) : daftar.length ? (
            <Table>
              <TableHeader>
                <TableRow>
                  <TableHead>Judul</TableHead>
                  <TableHead>Kategori</TableHead>
                  <TableHead>Status</TableHead>
                  <TableHead>Dibaca</TableHead>
                  <TableHead>Tanggal</TableHead>
                  <TableHead className="text-right">Aksi</TableHead>
                </TableRow>
              </TableHeader>
              <TableBody>
                {daftar.map((artikel) => (
                  <TableRow key={artikel.id}>
                    <TableCell>
                      <div className="flex items-center gap-2">
                        <span className="max-w-[320px] truncate font-medium">
                          {artikel.judul}
                        </span>
                        {artikel.headline && (
                          <Star className="h-3.5 w-3.5 shrink-0 fill-amber-400 text-amber-400" />
                        )}
                      </div>
                      <div className="max-w-[380px] truncate text-xs text-muted-foreground">
                        {stripHtml(artikel.ringkasan ?? artikel.isi)}
                      </div>
                    </TableCell>
                    <TableCell className="text-muted-foreground">
                      {artikel.kategori?.nama ?? "-"}
                    </TableCell>
                    <TableCell>
                      <Badge variant={artikel.status === "TERBIT" ? "success" : "warning"}>
                        {artikel.status === "TERBIT" ? "Terbit" : "Draft"}
                      </Badge>
                    </TableCell>
                    <TableCell>
                      <span className="inline-flex items-center gap-1 text-muted-foreground">
                        <Eye className="h-3.5 w-3.5" />
                        {artikel.dibaca}
                      </span>
                    </TableCell>
                    <TableCell className="text-muted-foreground">
                      {formatDateShort(artikel.publishedAt ?? artikel.createdAt)}
                    </TableCell>
                    <TableCell className="text-right">
                      <div className="flex justify-end gap-1">
                        <Button
                          variant="ghost"
                          size="icon"
                          className="h-8 w-8"
                          onClick={() => toggleHeadline(artikel)}
                          aria-label="Atur headline"
                        >
                          <Star
                            className={
                              artikel.headline
                                ? "h-4 w-4 fill-amber-400 text-amber-400"
                                : "h-4 w-4"
                            }
                          />
                        </Button>
                        <Button
                          variant="ghost"
                          size="icon"
                          className="h-8 w-8"
                          onClick={() => toggleStatus(artikel)}
                          aria-label="Ubah status terbit"
                        >
                          <Send className="h-4 w-4" />
                        </Button>
                        <Button
                          variant="ghost"
                          size="icon"
                          className="h-8 w-8"
                          onClick={() => openEdit(artikel)}
                          aria-label="Ubah artikel"
                        >
                          <FilePenLine className="h-4 w-4" />
                        </Button>
                        <Button
                          variant="ghost"
                          size="icon"
                          className="h-8 w-8 text-destructive hover:text-destructive"
                          onClick={() => setDeleteTarget(artikel)}
                          aria-label="Hapus artikel"
                        >
                          <Trash2 className="h-4 w-4" />
                        </Button>
                      </div>
                    </TableCell>
                  </TableRow>
                ))}
              </TableBody>
            </Table>
          ) : (
            <div className="py-16 text-center">
              <Newspaper className="mx-auto h-6 w-6 text-muted-foreground" />
              <p className="mt-2 font-semibold">Belum ada artikel</p>
              <p className="mt-1 text-sm text-muted-foreground">
                Tulis berita pertama untuk website desa.
              </p>
            </div>
          )}

          {data && data.data.length > 0 && (
            <Pagination
              page={data.meta.page}
              totalPages={data.meta.totalPages}
              total={data.meta.total}
              onChange={setPage}
            />
          )}
        </CardContent>
      </Card>

      <Dialog open={formOpen} onOpenChange={setFormOpen}>
        <DialogContent className="max-w-3xl">
          <DialogHeader>
            <DialogTitle>{editing ? "Ubah Artikel" : "Tulis Artikel Baru"}</DialogTitle>
            <DialogDescription>
              Artikel berstatus terbit akan tampil di website desa.
            </DialogDescription>
          </DialogHeader>
          <form onSubmit={save} className="space-y-4">
            <div className="space-y-1.5">
              <Label>
                Judul <span className="text-destructive">*</span>
              </Label>
              <Input
                required
                maxLength={200}
                value={form.judul}
                onChange={(event) =>
                  setForm((current) => ({ ...current, judul: event.target.value }))
                }
                placeholder="Judul berita yang menarik"
              />
            </div>

            <div className="grid gap-4 sm:grid-cols-2">
              <div className="space-y-1.5">
                <Label>Kategori</Label>
                <Select
                  value={form.kategoriId}
                  onChange={(event) =>
                    setForm((current) => ({ ...current, kategoriId: event.target.value }))
                  }
                >
                  <option value="">Tanpa kategori</option>
                  {(kategori ?? []).map((item) => (
                    <option key={item.id} value={item.id}>
                      {item.nama}
                    </option>
                  ))}
                </Select>
              </div>
              <div className="space-y-1.5">
                <Label>Status</Label>
                <Select
                  value={form.status}
                  onChange={(event) =>
                    setForm((current) => ({ ...current, status: event.target.value }))
                  }
                >
                  <option value="DRAFT">Draft</option>
                  <option value="TERBIT">Terbit</option>
                </Select>
              </div>
            </div>

            <div className="space-y-1.5">
              <Label>Ringkasan</Label>
              <Textarea
                rows={2}
                value={form.ringkasan}
                onChange={(event) =>
                  setForm((current) => ({ ...current, ringkasan: event.target.value }))
                }
                placeholder="Ringkasan singkat untuk kartu berita (opsional)"
              />
            </div>

            <div className="space-y-1.5">
              <Label>
                Isi artikel <span className="text-destructive">*</span>
              </Label>
              <Textarea
                required
                rows={12}
                value={form.isi}
                onChange={(event) =>
                  setForm((current) => ({ ...current, isi: event.target.value }))
                }
                placeholder="Tulis isi berita. Pisahkan paragraf dengan baris kosong."
              />
            </div>

            <label className="flex items-center gap-2 text-sm">
              <input
                type="checkbox"
                checked={form.headline}
                onChange={(event) =>
                  setForm((current) => ({ ...current, headline: event.target.checked }))
                }
                className="h-4 w-4 rounded border-input accent-emerald-600"
              />
              Jadikan headline utama di website desa
            </label>

            <DialogFooter>
              <Button type="button" variant="outline" onClick={() => setFormOpen(false)}>
                Batal
              </Button>
              <Button type="submit" disabled={saving}>
                {saving ? "Menyimpan…" : editing ? "Simpan Perubahan" : "Simpan Artikel"}
              </Button>
            </DialogFooter>
          </form>
        </DialogContent>
      </Dialog>

      <Dialog open={kategoriOpen} onOpenChange={setKategoriOpen}>
        <DialogContent className="max-w-md">
          <DialogHeader>
            <DialogTitle>Kategori Baru</DialogTitle>
            <DialogDescription>
              Kelompokkan artikel ke dalam kategori, mis. Kegiatan, Pembangunan, Pengumuman.
            </DialogDescription>
          </DialogHeader>
          <form onSubmit={createKategori} className="space-y-4">
            <div className="space-y-1.5">
              <Label>
                Nama kategori <span className="text-destructive">*</span>
              </Label>
              <Input
                required
                maxLength={100}
                value={kategoriNama}
                onChange={(event) => setKategoriNama(event.target.value)}
                placeholder="Pengumuman"
              />
            </div>
            <div className="rounded-lg bg-muted/60 p-3">
              <div className="text-xs font-semibold uppercase tracking-wide text-muted-foreground">
                Kategori tersedia
              </div>
              <div className="mt-2 flex flex-wrap gap-1.5">
                {(kategori ?? []).map((item) => (
                  <Badge key={item.id} variant="secondary">
                    {item.nama} · {item._count?.artikel ?? 0}
                  </Badge>
                ))}
                {!kategori?.length && (
                  <span className="text-xs text-muted-foreground">Belum ada kategori</span>
                )}
              </div>
            </div>
            <DialogFooter>
              <Button type="button" variant="outline" onClick={() => setKategoriOpen(false)}>
                Batal
              </Button>
              <Button type="submit" disabled={saving}>
                {saving ? "Menyimpan…" : "Tambah Kategori"}
              </Button>
            </DialogFooter>
          </form>
        </DialogContent>
      </Dialog>

      <Dialog open={!!deleteTarget} onOpenChange={(open) => !open && setDeleteTarget(null)}>
        <DialogContent className="max-w-md">
          <DialogHeader>
            <DialogTitle>Hapus artikel?</DialogTitle>
            <DialogDescription>
              Artikel <span className="font-semibold">{deleteTarget?.judul}</span> akan
              dihapus permanen dari website desa.
            </DialogDescription>
          </DialogHeader>
          <DialogFooter>
            <Button variant="outline" onClick={() => setDeleteTarget(null)}>
              Batal
            </Button>
            <Button variant="destructive" onClick={remove} disabled={deleting}>
              {deleting ? "Menghapus…" : "Hapus"}
            </Button>
          </DialogFooter>
        </DialogContent>
      </Dialog>
    </div>
  );
}
