import { useMemo, useState } from "react";
import { useTranslation } from "react-i18next";
import { useQuery, useQueryClient } from "@tanstack/react-query";
import { Check, Plus } from "lucide-react";
import { api } from "../lib/api";
import { useScrollFade } from "../lib/useScrollFade";
import Modal from "./Modal";
import { useConfirm } from "./ConfirmProvider";

// Admin-only "manage this movie's collections" dialog (Collections P2). Lists the library's EDITABLE
// collections with an in/out toggle (add/remove the movie, written back to Plex), plus a field to
// create a new collection seeded with this movie. Read-only collections (smart / IMDb-TMDb auto-lists)
// never appear here. Opened from the movie info page.
export default function PlexCollectionEditor({
  item,
  library,
  memberOf,
  onClose,
  onChanged,
}: {
  item: { id: string; title: string };
  library: string;
  memberOf: string[]; // collection ids this movie is already in
  onClose: () => void;
  onChanged: () => void;
}) {
  const { t } = useTranslation();
  const qc = useQueryClient();
  const confirm = useConfirm();
  const editableFade = useScrollFade();
  const othersFade = useScrollFade();
  const [members, setMembers] = useState<Set<string>>(() => new Set(memberOf));
  const [q, setQ] = useState("");
  const [newName, setNewName] = useState("");
  const [busy, setBusy] = useState<string | null>(null); // collection id currently mutating

  const listQ = useQuery({
    queryKey: ["plex-collections", library],
    queryFn: () => api.plexCollections(library),
  });
  const editable = useMemo(
    () => (listQ.data?.collections ?? []).filter((c) => c.can_edit),
    [listQ.data],
  );
  // Existing Plex collections you could take over (plain, non-smart, non-auto) but haven't marked yet.
  const eligible = useMemo(
    () =>
      (listQ.data?.collections ?? []).filter(
        (c) => !c.can_edit && !c.smart && c.source === "collection",
      ),
    [listQ.data],
  );
  const term = q.trim().toLowerCase();
  const shown = term ? editable.filter((c) => c.title.toLowerCase().includes(term)) : editable;

  const refresh = () => {
    qc.invalidateQueries({ queryKey: ["plex-collections"] });
    qc.invalidateQueries({ queryKey: ["plex-item", item.id] });
    qc.invalidateQueries({ queryKey: ["plex-library"] });
    onChanged();
  };

  async function toggle(id: string) {
    if (busy) return;
    setBusy(id);
    const inIt = members.has(id);
    try {
      if (inIt) await api.plexCollectionRemoveItem(id, item.id);
      else await api.plexCollectionAddItem(id, item.id);
      setMembers((prev) => {
        const next = new Set(prev);
        if (inIt) next.delete(id);
        else next.add(id);
        return next;
      });
      refresh();
    } finally {
      setBusy(null);
    }
  }

  async function markEditable(id: string) {
    if (busy) return;
    setBusy(id);
    try {
      await api.plexSetCollectionEditable(id, true);
      refresh();
    } finally {
      setBusy(null);
    }
  }

  async function createNew() {
    const title = newName.trim();
    if (!title || busy) return;
    setBusy("__new__");
    try {
      const col = await api.plexCreateCollection(library, title, item.id);
      setNewName("");
      setMembers((prev) => new Set(prev).add(col.id));
      refresh();
    } finally {
      setBusy(null);
    }
  }

  async function removeCollection(id: string, title: string) {
    if (!(await confirm({ message: t("plex.collEditor.deleteConfirm", { title }), danger: true })))
      return;
    setBusy(id);
    try {
      await api.plexDeleteCollection(id);
      setMembers((prev) => {
        const next = new Set(prev);
        next.delete(id);
        return next;
      });
      refresh();
    } finally {
      setBusy(null);
    }
  }

  return (
    <Modal title={t("plex.collEditor.title", { title: item.title })} onClose={onClose}>
      {/* Create new */}
      <div className="mb-3 flex gap-2">
        <input
          value={newName}
          onChange={(e) => setNewName(e.target.value)}
          onKeyDown={(e) => e.key === "Enter" && createNew()}
          placeholder={t("plex.collEditor.newPlaceholder")}
          className="glass-card min-w-0 flex-1 rounded-lg px-3 py-2 text-sm outline-none focus:border-accent"
        />
        <button
          onClick={createNew}
          disabled={!newName.trim() || !!busy}
          className="glass-card glass-hover inline-flex shrink-0 items-center gap-1.5 rounded-lg px-3 py-2 text-sm font-medium disabled:opacity-50"
        >
          <Plus className="h-4 w-4" />
          {t("plex.collEditor.create")}
        </button>
      </div>

      {/* Filter */}
      {editable.length > 6 && (
        <input
          value={q}
          onChange={(e) => setQ(e.target.value)}
          placeholder={t("plex.collEditor.search")}
          className="glass-card mb-2 w-full rounded-lg px-3 py-1.5 text-sm outline-none focus:border-accent"
        />
      )}

      {/* Editable collections with in/out toggle */}
      <div
        ref={editableFade.ref}
        style={editableFade.style}
        className="max-h-80 space-y-1 overflow-y-auto no-scrollbar"
      >
        {listQ.isLoading ? (
          <p className="py-4 text-center text-sm text-muted">{t("plex.loading")}</p>
        ) : shown.length === 0 ? (
          <p className="py-4 text-center text-sm text-muted">{t("plex.collEditor.none")}</p>
        ) : (
          shown.map((c) => {
            const inIt = members.has(c.id);
            return (
              <div
                key={c.id}
                className="glass-card flex items-center gap-2 rounded-lg px-2 py-1.5 text-sm"
              >
                <button
                  onClick={() => toggle(c.id)}
                  disabled={!!busy}
                  className={`inline-flex min-w-0 flex-1 items-center gap-2 text-left disabled:opacity-50 ${
                    inIt ? "text-accent" : ""
                  }`}
                >
                  <span
                    className={`grid h-5 w-5 shrink-0 place-items-center rounded border ${
                      inIt ? "border-accent bg-accent/20" : "border-border"
                    }`}
                  >
                    {inIt && <Check className="h-3.5 w-3.5" />}
                  </span>
                  <span className="truncate">{c.title}</span>
                  <span className="shrink-0 text-xs text-muted">
                    {t("plex.collEditor.count", { count: c.child_count ?? 0 })}
                  </span>
                </button>
                <button
                  onClick={() => removeCollection(c.id, c.title)}
                  disabled={!!busy}
                  className="shrink-0 rounded px-1.5 py-0.5 text-xs text-muted hover:text-red-400 disabled:opacity-50"
                >
                  {t("plex.collEditor.delete")}
                </button>
              </div>
            );
          })
        )}
      </div>

      {/* Take over an existing plain Plex collection (mark it "mine to edit"). */}
      {eligible.length > 0 && (
        <details className="mt-3">
          <summary className="cursor-pointer text-xs text-muted hover:text-fg">
            {t("plex.collEditor.others", { count: eligible.length })}
          </summary>
          <div
            ref={othersFade.ref}
            style={othersFade.style}
            className="mt-2 max-h-40 space-y-1 overflow-y-auto no-scrollbar"
          >
            {eligible.map((c) => (
              <div
                key={c.id}
                className="glass-card flex items-center gap-2 rounded-lg px-2 py-1.5 text-sm"
              >
                <span className="min-w-0 flex-1 truncate">{c.title}</span>
                <span className="shrink-0 text-xs text-muted">
                  {t("plex.collEditor.count", { count: c.child_count ?? 0 })}
                </span>
                <button
                  onClick={() => markEditable(c.id)}
                  disabled={!!busy}
                  className="glass-card glass-hover shrink-0 rounded px-2 py-0.5 text-xs disabled:opacity-50"
                >
                  {t("plex.collEditor.makeEditable")}
                </button>
              </div>
            ))}
          </div>
        </details>
      )}

      <p className="mt-3 text-xs text-muted">{t("plex.collEditor.note")}</p>
    </Modal>
  );
}
