"use client";

import { useConfirm } from "@/components/ConfirmDialog";

import { useCallback, useEffect, useState } from "react";
import Link from "next/link";
import { Search, Trash2, ChevronLeft, ChevronRight, Loader2 } from "lucide-react";
import clsx from "clsx";

type Row = {
  id: string;
  title: string;
  author: string;
  authorName?: string;
  subtitle?: string;
  createdAt?: string;
  media?: string;
  gradient?: string;
  link?: string;
  status?: string;
  amount?: number;
  stats?: Record<string, number>;
};

/**
 * The listing screen shared by every admin collection — reels, stories,
 * comments and the rest. They differ in data, not in shape, so one component
 * keeps them consistent and means a new screen is a few lines.
 */
export function AdminCollection({
  name,
  title,
  icon,
  hint,
  searchable = true,
}: {
  name: string;
  title: string;
  icon: React.ReactNode;
  hint?: string;
  searchable?: boolean;
}) {
  const confirm = useConfirm();
  const [rows, setRows] = useState<Row[]>([]);
  const [total, setTotal] = useState(0);
  const [pages, setPages] = useState(1);
  const [page, setPage] = useState(1);
  const [q, setQ] = useState("");
  const [deletable, setDeletable] = useState(false);
  const [busy, setBusy] = useState(true);
  const [note, setNote] = useState<string | null>(null);

  const load = useCallback(() => {
    setBusy(true);
    fetch(`/api/admin/collection?name=${name}&page=${page}&q=${encodeURIComponent(q)}`)
      .then((r) => (r.ok ? r.json() : null))
      .then((d) => {
        if (d?.rows) {
          setRows(d.rows);
          setTotal(d.total);
          setPages(d.pages);
          setDeletable(d.deletable);
        }
        setBusy(false);
      })
      .catch(() => setBusy(false));
  }, [name, page, q]);

  useEffect(() => {
    const t = setTimeout(load, q ? 300 : 0);
    return () => clearTimeout(t);
  }, [load, q]);

  async function remove(id: string, label: string) {
    const sure = await confirm({
      title: "Delete this?",
      body: `"${label.slice(0, 60)}" will be removed for good.`,
      confirmLabel: "Delete",
      danger: true,
    });
    if (!sure) return;
    await fetch(`/api/admin/collection?name=${name}&id=${id}`, {
      method: "DELETE",
    }).catch(() => {});
    load();
    setNote("Deleted");
    setTimeout(() => setNote(null), 2200);
  }

  const when = (iso?: string) =>
    iso
      ? new Date(iso).toLocaleDateString(undefined, {
          day: "numeric", month: "short", year: "numeric",
        })
      : "—";

  return (
    <div className="ab-page">
      <div className="ab-head">
        <h1>
          {icon} {title}
        </h1>
        <span className="ac-total">{total.toLocaleString()}</span>

        {searchable && (
          <div className="ac-search">
            <Search size={14} />
            <input
              value={q}
              onChange={(e) => {
                setQ(e.target.value);
                setPage(1);
              }}
              placeholder="Search…"
            />
          </div>
        )}
      </div>

      {hint && <p className="ab-intro">{hint}</p>}

      {busy && rows.length === 0 && (
        <p className="ps-hint">
          <Loader2 size={14} className="animate-spin inline mr-2" />
          Loading…
        </p>
      )}

      {!busy && rows.length === 0 && (
        <p className="pf-tabempty">
          {q ? `Nothing matches "${q}".` : "Nothing here yet."}
        </p>
      )}

      <div className="ac-list">
        {rows.map((row) => (
          <div key={row.id} className="ac-row">
            {(row.media || row.gradient) && (
              <span
                className={clsx("ac-thumb", row.gradient && `bg-gradient-to-br ${row.gradient}`)}
              >
                {row.media &&
                  (row.media.match(/\.(mp4|webm)/) ? (
                    <video src={row.media} muted preload="metadata" />
                  ) : (
                    // eslint-disable-next-line @next/next/no-img-element
                    <img src={row.media} alt="" />
                  ))}
              </span>
            )}

            <span className="min-w-0 flex-1">
              {row.link ? (
                <Link href={row.link}>
                  <b>{row.title}</b>
                </Link>
              ) : (
                <b>{row.title}</b>
              )}
              <em>
                {row.author !== "—" && (
                  <Link href={`/${row.author}`} className="ac-author">
                    @{row.author}
                  </Link>
                )}
                {row.subtitle && <> · {row.subtitle}</>}
              </em>
            </span>

            {row.stats &&
              Object.entries(row.stats).map(([k, v]) => (
                <span key={k} className="ac-stat" title={k}>
                  <b>{v}</b>
                  <em>{k}</em>
                </span>
              ))}

            {typeof row.amount === "number" && (
              <b className={clsx("ac-amount", row.amount >= 0 ? "up" : "down")}>
                {row.amount >= 0 ? "+" : ""}
                {row.amount}
              </b>
            )}

            {row.status && (
              <span className={clsx("am-wstatus", row.status)}>{row.status}</span>
            )}

            <span className="ac-when">{when(row.createdAt)}</span>

            {deletable && (
              <button
                onClick={() => remove(row.id, row.title)}
                className="ab-del"
                title="Delete"
              >
                <Trash2 size={13} />
              </button>
            )}
          </div>
        ))}
      </div>

      {pages > 1 && (
        <div className="ac-pager">
          <button onClick={() => setPage((p) => Math.max(1, p - 1))} disabled={page === 1}>
            <ChevronLeft size={15} />
          </button>
          <span>
            Page {page} of {pages}
          </span>
          <button
            onClick={() => setPage((p) => Math.min(pages, p + 1))}
            disabled={page === pages}
          >
            <ChevronRight size={15} />
          </button>
        </div>
      )}

      {note && <div className="ps-note">{note}</div>}
    </div>
  );
}
