"use client";

import { useMemo, useState } from "react";
import useSWR from "swr";
import {
  CheckCircle2,
  Inbox,
  MessageSquareWarning,
  Plus,
  Printer,
  Search,
  Trash2,
  UserCog,
} from "lucide-react";
import { toast } from "sonner";
import type {
  Paginated,
  Pengaduan,
  PengaduanResponse,
  Penduduk,
  PerangkatDesa,
  StatusPengaduan,
} from "@/lib/types";
import { ApiError, apiSend, fetcher } from "@/lib/api";
import { useSession } from "@/lib/use-session";
import { PageHeader, StatCard } from "@/components/page-header";
import { KopLaporan } from "@/components/admin/kop-laporan";
import { PengaturanKehadiran } from "@/components/admin/pengaturan-kehadiran";
import { SettingsForm, type SettingField } from "@/components/admin/settings-form";
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 { formatNumber } from "@/lib/utils";
import {
  STATUS_PENGADUAN_OPTIONS,
  badgeStatusPengaduan,
  labelStatusPengaduan,
} from "@/lib/kehadiran";

function formatWaktu(value: string) {
  const date = new Date(value);
  if (Number.isNaN(date.getTime())) return "-";
  return new Intl.DateTimeFormat("id-ID", {
    dateStyle: "medium",
    timeStyle: "short",
  }).format(date);
}

type CreateForm = { pendudukId: string; perangkatId: string; judul: string; keterangan: string };
type ResponForm = { status: StatusPengaduan; tanggapan: string };

const emptyCreate: CreateForm = { pendudukId: "", perangkatId: "", judul: "", keterangan: "" };

const PENGATURAN: SettingField[] = [
  {
    kunci: "pengaduan.jumlah_aduan_pengguna",
    label: "Jumlah Aduan Pengguna",
    type: "number",
    defaultValue: "10",
    help: "Batas jumlah aduan yang dapat dikirim satu pengguna.",
  },
  {
    kunci: "pengaduan.sensor_nama_pelapor",
    label: "Sembunyikan Nama Pelapor",
    type: "checkbox",
    help: "Sensor nama pelapor pada tampilan publik.",
  },
];

export default function PengaduanPage() {
  const { user } = useSession();
  const canMutate = user?.role === "ADMIN" || user?.role === "OPERATOR";

  const { data, isLoading, mutate } = useSWR<PengaduanResponse>("/pengaduan", fetcher);
  const { data: penduduk } = useSWR<Paginated<Penduduk>>("/penduduk?limit=200", fetcher);
  const { data: perangkat } = useSWR<PerangkatDesa[]>("/perangkat", fetcher);
  const daftar = data?.data ?? [];

  const [search, setSearch] = useState("");
  const [statusFilter, setStatusFilter] = useState("");
  const [createOpen, setCreateOpen] = useState(false);
  const [createForm, setCreateForm] = useState<CreateForm>(emptyCreate);
  const [saving, setSaving] = useState(false);
  const [responTarget, setResponTarget] = useState<Pengaduan | null>(null);
  const [responForm, setResponForm] = useState<ResponForm>({
    status: "DIPROSES",
    tanggapan: "",
  });
  const [deleteTarget, setDeleteTarget] = useState<Pengaduan | null>(null);
  const [deleting, setDeleting] = useState(false);

  const filtered = useMemo(() => {
    const keyword = search.trim().toLowerCase();
    return daftar.filter((item) => {
      if (statusFilter && item.status !== statusFilter) return false;
      if (!keyword) return true;
      return [
        item.penduduk?.nama,
        item.penduduk?.nik,
        item.perangkat?.nama,
        item.keterangan,
        item.tanggapan,
      ]
        .filter(Boolean)
        .some((value) => String(value).toLowerCase().includes(keyword));
    });
  }, [daftar, search, statusFilter]);

  async function create(event: React.FormEvent<HTMLFormElement>) {
    event.preventDefault();
    setSaving(true);
    try {
      await apiSend("/pengaduan", "POST", {
        judul: createForm.judul || undefined,
        keterangan: createForm.keterangan,
        ...(createForm.pendudukId
          ? { pendudukId: Number(createForm.pendudukId) }
          : {}),
        ...(createForm.perangkatId
          ? { perangkatId: Number(createForm.perangkatId) }
          : {}),
      });
      toast.success("Pengaduan dicatat");
      setCreateOpen(false);
      setCreateForm(emptyCreate);
      await mutate();
    } catch (error) {
      toast.error(error instanceof ApiError ? error.message : "Gagal menyimpan data");
    } finally {
      setSaving(false);
    }
  }

  function openRespon(item: Pengaduan) {
    setResponTarget(item);
    setResponForm({
      status: item.status === "BARU" ? "DIPROSES" : item.status,
      tanggapan: item.tanggapan ?? "",
    });
  }

  async function saveRespon(event: React.FormEvent<HTMLFormElement>) {
    event.preventDefault();
    if (!responTarget) return;
    setSaving(true);
    try {
      await apiSend(`/pengaduan/${responTarget.id}`, "PATCH", {
        status: responForm.status,
        tanggapan: responForm.tanggapan,
      });
      toast.success("Tanggapan pengaduan disimpan");
      setResponTarget(null);
      await mutate();
    } catch (error) {
      toast.error(error instanceof ApiError ? error.message : "Gagal menyimpan data");
    } finally {
      setSaving(false);
    }
  }

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

  return (
    <div className="animate-fade-in space-y-6">
      <div className="no-print">
        <PageHeader
          title="Pengaduan"
          description="Pengaduan warga atas layanan dan kehadiran perangkat desa."
          action={
            <div className="flex flex-wrap gap-2">
              <Button variant="outline" onClick={() => window.print()}>
                <Printer className="h-4 w-4" />
                Cetak
              </Button>
              <PengaturanKehadiran />
              {canMutate && (
                <Button onClick={() => setCreateOpen(true)}>
                  <Plus className="h-4 w-4" />
                  Catat Pengaduan
                </Button>
              )}
            </div>
          }
        />
      </div>

      <KopLaporan title="Daftar Pengaduan Warga" />

      {isLoading || !data ? (
        <div className="grid gap-4 sm:grid-cols-2 xl:grid-cols-4">
          {Array.from({ length: 4 }).map((_, index) => (
            <div key={index} className="h-28 animate-pulse rounded-xl bg-muted" />
          ))}
        </div>
      ) : (
        <>
          <div className="grid gap-4 sm:grid-cols-2 xl:grid-cols-4">
            <StatCard
              title="Total pengaduan"
              value={formatNumber(data.ringkasan.total)}
              hint="Seluruh pengaduan masuk"
              icon={Inbox}
            />
            <StatCard
              title="Baru"
              value={formatNumber(data.ringkasan.baru)}
              hint="Belum ditangani"
              icon={MessageSquareWarning}
              tone="amber"
            />
            <StatCard
              title="Diproses"
              value={formatNumber(data.ringkasan.diproses)}
              hint="Sedang ditindaklanjuti"
              icon={UserCog}
              tone="sky"
            />
            <StatCard
              title="Selesai"
              value={formatNumber(data.ringkasan.selesai)}
              hint="Sudah ditanggapi"
              icon={CheckCircle2}
              tone="violet"
            />
          </div>

          <Card>
            <CardContent className="space-y-4 p-4">
              <div className="no-print flex flex-col gap-3 sm:flex-row">
                <div className="relative flex-1">
                  <Search className="pointer-events-none 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 pengadu, perangkat, atau isi pengaduan"
                    className="pl-9"
                  />
                </div>
                <Select
                  value={statusFilter}
                  onChange={(event) => setStatusFilter(event.target.value)}
                  className="sm:w-48"
                >
                  <option value="">Semua status</option>
                  {STATUS_PENGADUAN_OPTIONS.map((option) => (
                    <option key={option.value} value={option.value}>
                      {option.label}
                    </option>
                  ))}
                </Select>
              </div>

              {filtered.length ? (
                <Table>
                  <TableHeader>
                    <TableRow>
                      <TableHead className="w-14">No</TableHead>
                      {canMutate && <TableHead className="w-32">Aksi</TableHead>}
                      <TableHead>Nama</TableHead>
                      <TableHead>Judul</TableHead>
                      <TableHead>Tanggal</TableHead>
                      <TableHead>Status</TableHead>
                      <TableHead>Terlapor</TableHead>
                      <TableHead>Keterangan</TableHead>
                      <TableHead>Tanggapan</TableHead>
                    </TableRow>
                  </TableHeader>
                  <TableBody>
                    {filtered.map((item, index) => (
                      <TableRow key={item.id}>
                        <TableCell className="text-muted-foreground">{index + 1}</TableCell>
                        {canMutate && (
                          <TableCell>
                            <div className="flex gap-1">
                              <Button
                                variant="ghost"
                                size="sm"
                                onClick={() => openRespon(item)}
                              >
                                Tanggapi
                              </Button>
                              <Button
                                variant="ghost"
                                size="icon"
                                onClick={() => setDeleteTarget(item)}
                                aria-label="Hapus pengaduan"
                              >
                                <Trash2 className="h-4 w-4 text-destructive" />
                              </Button>
                            </div>
                          </TableCell>
                        )}
                        <TableCell>
                          {item.penduduk ? (
                            <>
                              <div className="font-medium">{item.penduduk.nama}</div>
                              <div className="font-mono text-[11px] text-muted-foreground">
                                {item.penduduk.nik}
                              </div>
                            </>
                          ) : (
                            <span className="text-muted-foreground">Anonim</span>
                          )}
                        </TableCell>
                        <TableCell className="max-w-[220px]">
                          <p className="line-clamp-2 text-sm">{item.judul ?? "-"}</p>
                        </TableCell>
                        <TableCell className="whitespace-nowrap text-muted-foreground">
                          {formatWaktu(item.waktu)}
                        </TableCell>
                        <TableCell>
                          <Badge variant={badgeStatusPengaduan(item.status)}>
                            {labelStatusPengaduan(item.status)}
                          </Badge>
                        </TableCell>
                        <TableCell className="text-muted-foreground">
                          {item.perangkat ? (
                            <>
                              <div>{item.perangkat.nama}</div>
                              <div className="text-[11px]">{item.perangkat.jabatan}</div>
                            </>
                          ) : (
                            "-"
                          )}
                        </TableCell>
                        <TableCell className="max-w-[260px]">
                          <p className="line-clamp-3 text-sm">{item.keterangan}</p>
                        </TableCell>
                        <TableCell className="max-w-[220px]">
                          <p className="line-clamp-3 text-sm text-muted-foreground">
                            {item.tanggapan ?? "-"}
                          </p>
                        </TableCell>
                      </TableRow>
                    ))}
                  </TableBody>
                </Table>
              ) : (
                <p className="py-10 text-center text-sm text-muted-foreground">
                  Tidak ada pengaduan yang sesuai.
                </p>
              )}
            </CardContent>
          </Card>
        </>
      )}

      <SettingsForm
        grup="pengaduan"
        title="Pengaturan Pengaduan"
        description="Batas pengaduan dan privasi pelapor."
        fields={PENGATURAN}
      />

      <Dialog open={createOpen} onOpenChange={setCreateOpen}>
        <DialogContent className="max-h-[90vh] max-w-xl overflow-y-auto">
          <DialogHeader>
            <DialogTitle>Catat Pengaduan</DialogTitle>
            <DialogDescription>
              Masukkan pengaduan warga terkait layanan atau kehadiran perangkat.
            </DialogDescription>
          </DialogHeader>
          <form onSubmit={create} className="space-y-4">
            <div className="space-y-1.5">
              <Label htmlFor="pengadu">Pelapor</Label>
              <Select
                id="pengadu"
                value={createForm.pendudukId}
                onChange={(event) =>
                  setCreateForm({ ...createForm, pendudukId: event.target.value })
                }
              >
                <option value="">Anonim / tidak diketahui</option>
                {(penduduk?.data ?? []).map((warga) => (
                  <option key={warga.id} value={warga.id}>
                    {warga.nama} — {warga.nik}
                  </option>
                ))}
              </Select>
            </div>
            <div className="space-y-1.5">
              <Label htmlFor="tertuju">Terlapor</Label>
              <Select
                id="tertuju"
                value={createForm.perangkatId}
                onChange={(event) =>
                  setCreateForm({ ...createForm, perangkatId: event.target.value })
                }
              >
                <option value="">Tidak spesifik</option>
                {(perangkat ?? []).map((item) => (
                  <option key={item.id} value={item.id}>
                    {item.nama} — {item.jabatan}
                  </option>
                ))}
              </Select>
            </div>
            <div className="space-y-1.5">
              <Label htmlFor="judul">Judul</Label>
              <Input
                id="judul"
                value={createForm.judul}
                onChange={(event) =>
                  setCreateForm({ ...createForm, judul: event.target.value })
                }
                placeholder="Ringkasan singkat pengaduan"
              />
            </div>
            <div className="space-y-1.5">
              <Label htmlFor="isi">Keterangan</Label>
              <Textarea
                id="isi"
                value={createForm.keterangan}
                onChange={(event) =>
                  setCreateForm({ ...createForm, keterangan: event.target.value })
                }
                rows={4}
                required
                placeholder="Uraikan pengaduan secara singkat dan jelas"
              />
            </div>
            <DialogFooter>
              <Button type="button" variant="outline" onClick={() => setCreateOpen(false)}>
                Batal
              </Button>
              <Button type="submit" disabled={saving}>
                {saving ? "Menyimpan..." : "Simpan"}
              </Button>
            </DialogFooter>
          </form>
        </DialogContent>
      </Dialog>

      <Dialog
        open={!!responTarget}
        onOpenChange={(open) => !open && setResponTarget(null)}
      >
        <DialogContent className="max-w-lg">
          <DialogHeader>
            <DialogTitle>Tanggapi Pengaduan</DialogTitle>
            <DialogDescription>
              {responTarget ? formatWaktu(responTarget.waktu) : ""} —{" "}
              {responTarget?.penduduk?.nama ?? "Anonim"}
            </DialogDescription>
          </DialogHeader>
          <form onSubmit={saveRespon} className="space-y-4">
            <div className="rounded-lg border bg-muted/40 p-3 text-sm">
              {responTarget?.keterangan}
            </div>
            <div className="space-y-1.5">
              <Label htmlFor="statusRespon">Status</Label>
              <Select
                id="statusRespon"
                value={responForm.status}
                onChange={(event) =>
                  setResponForm({
                    ...responForm,
                    status: event.target.value as StatusPengaduan,
                  })
                }
              >
                {STATUS_PENGADUAN_OPTIONS.map((option) => (
                  <option key={option.value} value={option.value}>
                    {option.label}
                  </option>
                ))}
              </Select>
            </div>
            <div className="space-y-1.5">
              <Label htmlFor="tanggapan">Tanggapan</Label>
              <Textarea
                id="tanggapan"
                value={responForm.tanggapan}
                onChange={(event) =>
                  setResponForm({ ...responForm, tanggapan: event.target.value })
                }
                rows={3}
                placeholder="Tindak lanjut atau jawaban atas pengaduan"
              />
            </div>
            <DialogFooter>
              <Button
                type="button"
                variant="outline"
                onClick={() => setResponTarget(null)}
              >
                Batal
              </Button>
              <Button type="submit" disabled={saving}>
                {saving ? "Menyimpan..." : "Simpan Tanggapan"}
              </Button>
            </DialogFooter>
          </form>
        </DialogContent>
      </Dialog>

      <Dialog open={!!deleteTarget} onOpenChange={(open) => !open && setDeleteTarget(null)}>
        <DialogContent className="max-w-md">
          <DialogHeader>
            <DialogTitle>Hapus pengaduan?</DialogTitle>
            <DialogDescription>
              Pengaduan dari {deleteTarget?.penduduk?.nama ?? "anonim"} akan dihapus
              permanen.
            </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>
  );
}
