"use client";
import { useEffect, useState, useTransition } from "react";
import { useRouter } from "next/navigation";
import { Captions, Folder, FolderOpen, Loader2, Plus, Save, Trash2 } from "lucide-react";
import { setSubtitleExtraPaths, setSubtitleCacheLimitMb } from "@/app/actions/settings";
import { useSettings } from "./SettingsProvider";

/**
 * Persistent recursive-scan folders for subtitle sidecars. The player
 * always finds same-folder sidecars; configure these only if subtitles
 * live in a separate location from videos.
 */
export function SubtitleLibraryPaths() {
  const { settings } = useSettings();
  const router = useRouter();
  const [, start] = useTransition();
  const [draftSubExtras, setDraftSubExtras] = useState<string[]>(settings.subtitleExtraPaths ?? []);
  const [newSubExtra, setNewSubExtra] = useState("");
  const [saving, setSaving] = useState(false);
  const [picking, setPicking] = useState<string | null>(null);
  const [error, setError] = useState<string | null>(null);

  useEffect(() => {
    setDraftSubExtras(settings.subtitleExtraPaths ?? []);
  }, [settings.subtitleExtraPaths]);

  async function pickFolder(startPath: string): Promise<string | null> {
    try {
      const r = await fetch("/api/pick-folder", {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({ start: startPath }),
      });
      const j = await r.json();
      if (!r.ok) throw new Error(j.error ?? `picker failed (${r.status})`);
      return typeof j.path === "string" && j.path ? j.path : null;
    } catch (e) {
      setError((e as Error).message);
      return null;
    }
  }

  const dirty =
    draftSubExtras.length !== (settings.subtitleExtraPaths ?? []).length ||
    draftSubExtras.some((v, i) => v !== (settings.subtitleExtraPaths ?? [])[i]);

  function addSubExtra() {
    const v = newSubExtra.trim();
    if (!v || draftSubExtras.includes(v)) return;
    setDraftSubExtras((cur) => [...cur, v]);
    setNewSubExtra("");
  }
  function removeSubExtra(idx: number) {
    setDraftSubExtras((cur) => cur.filter((_, i) => i !== idx));
  }
  function updateSubExtra(idx: number, value: string) {
    setDraftSubExtras((cur) => cur.map((v, i) => (i === idx ? value : v)));
  }
  async function browseExtra(idx: number) {
    setPicking(`extra-${idx}`);
    try {
      const p = await pickFolder(draftSubExtras[idx] ?? "");
      if (p) updateSubExtra(idx, p);
    } finally {
      setPicking(null);
    }
  }
  async function browseNewExtra() {
    setPicking("new");
    try {
      const p = await pickFolder(newSubExtra);
      if (p) {
        if (!draftSubExtras.includes(p)) {
          setDraftSubExtras((cur) => [...cur, p]);
          setNewSubExtra("");
        } else {
          setNewSubExtra(p);
        }
      }
    } finally {
      setPicking(null);
    }
  }
  async function save() {
    setSaving(true);
    setError(null);
    try {
      await setSubtitleExtraPaths(draftSubExtras);
      start(() => router.refresh());
    } catch (e) {
      setError((e as Error).message);
    } finally {
      setSaving(false);
    }
  }

  return (
    <div>
      <div className="text-sm font-medium mb-1 flex items-center gap-1.5">
        <Captions className="w-3.5 h-3.5 text-[var(--color-cyan)]" />
        Subtitle Library Folders
      </div>
      <div className="text-xs text-[var(--color-fg-muted)] mb-2">
        Recursively scanned for subtitle sidecars matching the playing video&apos;s stem or code (depth 3).
        The player always finds same-folder sidecars; configure these only if you keep subtitles in a separate location.
      </div>
      <div className="space-y-1.5">
        {draftSubExtras.length === 0 ? (
          <div className="text-xs text-[var(--color-fg-muted)] italic px-3 py-2 rounded-lg border border-dashed border-[var(--color-glass-border)]">
            No subtitle folders.
          </div>
        ) : (
          draftSubExtras.map((p, i) => (
            <div key={i} className="flex items-center gap-2">
              <div className="relative flex-1">
                <Folder className="absolute left-3 top-1/2 -translate-y-1/2 w-4 h-4 text-[var(--color-fg-muted)] pointer-events-none" />
                <input
                  type="text"
                  value={p}
                  onChange={(e) => updateSubExtra(i, e.target.value)}
                  className="w-full glass rounded-lg pl-9 pr-3 py-1.5 text-sm font-mono outline-none focus:border-[var(--color-cyan)]"
                />
              </div>
              <button
                type="button"
                onClick={() => browseExtra(i)}
                disabled={picking !== null}
                title="Browse for folder"
                className="p-1.5 rounded-lg glass glass-hover disabled:opacity-40"
              >
                {picking === `extra-${i}` ? <Loader2 className="w-4 h-4 animate-spin" /> : <FolderOpen className="w-4 h-4" />}
              </button>
              <button
                type="button"
                onClick={() => removeSubExtra(i)}
                title="Remove"
                className="p-1.5 rounded-lg border border-red-500/30 text-red-300 hover:bg-red-500/10"
              >
                <Trash2 className="w-4 h-4" />
              </button>
            </div>
          ))
        )}
      </div>
      <div className="flex items-center gap-2 mt-2">
        <div className="relative flex-1">
          <Folder className="absolute left-3 top-1/2 -translate-y-1/2 w-4 h-4 text-[var(--color-fg-muted)] pointer-events-none" />
          <input
            type="text"
            value={newSubExtra}
            onChange={(e) => setNewSubExtra(e.target.value)}
            onKeyDown={(e) => { if (e.key === "Enter") { e.preventDefault(); addSubExtra(); } }}
            placeholder="D:\\Subtitles"
            className="w-full glass rounded-lg pl-9 pr-3 py-1.5 text-sm font-mono outline-none focus:border-[var(--color-cyan)]"
          />
        </div>
        <button
          type="button"
          onClick={browseNewExtra}
          disabled={picking !== null}
          title="Browse for folder"
          className="inline-flex items-center gap-1.5 text-sm px-3 py-1.5 rounded-lg glass glass-hover disabled:opacity-40"
        >
          {picking === "new" ? <Loader2 className="w-4 h-4 animate-spin" /> : <FolderOpen className="w-4 h-4" />}
          Browse
        </button>
        <button
          type="button"
          onClick={addSubExtra}
          disabled={!newSubExtra.trim()}
          className="inline-flex items-center gap-1.5 text-sm px-3 py-1.5 rounded-lg glass glass-hover disabled:opacity-40"
        >
          <Plus className="w-4 h-4" /> Add
        </button>
        <button
          type="button"
          onClick={save}
          disabled={!dirty || saving}
          className="inline-flex items-center gap-1.5 text-sm px-3 py-1.5 rounded-lg bg-[var(--color-cyan)] text-black font-medium disabled:opacity-40 disabled:cursor-not-allowed"
        >
          {saving ? <Loader2 className="w-4 h-4 animate-spin" /> : <Save className="w-4 h-4" />}
          Save
        </button>
      </div>
      {error && (
        <div className="mt-2 text-xs text-red-300 bg-red-500/5 border border-red-500/25 rounded-lg px-3 py-2">
          {error}
        </div>
      )}

      <SubtitleCacheLimit />
    </div>
  );
}

function SubtitleCacheLimit() {
  const { settings } = useSettings();
  const router = useRouter();
  const [, start] = useTransition();
  const [draft, setDraft] = useState<number>(settings.subtitleCacheLimitMb ?? 100);
  const [saving, setSaving] = useState(false);
  useEffect(() => { setDraft(settings.subtitleCacheLimitMb ?? 100); }, [settings.subtitleCacheLimitMb]);
  const dirty = draft !== (settings.subtitleCacheLimitMb ?? 100);
  async function save() {
    setSaving(true);
    try {
      await setSubtitleCacheLimitMb(Math.max(0, Math.floor(draft)));
      start(() => router.refresh());
    } finally {
      setSaving(false);
    }
  }
  return (
    <div className="mt-section pt-section border-t border-[var(--color-glass-border)]">
      <div className="text-sm font-medium mb-1">Subtitle Cache Size Limit</div>
      <div className="text-xs text-[var(--color-fg-muted)] mb-2 max-w-2xl">
        Soft cap on <span className="font-mono">data/subtitle-cache/</span> (converted WebVTT files).
        When exceeded, oldest entries get evicted until size drops below 80% of the cap.{" "}
        <span className="font-mono">0</span> = unlimited.
      </div>
      <div className="flex items-center gap-2">
        <input
          type="number"
          min={0}
          value={draft}
          onChange={(e) => setDraft(Math.max(0, Number(e.target.value) || 0))}
          className="w-28 glass rounded-lg px-3 py-1.5 text-sm font-mono outline-none focus:border-[var(--color-cyan)]"
        />
        <span className="text-xs text-[var(--color-fg-dim)]">MB</span>
        <button
          type="button"
          onClick={save}
          disabled={!dirty || saving}
          className="inline-flex items-center gap-1.5 text-sm px-3 py-1.5 rounded-lg bg-[var(--color-cyan)] text-black font-medium disabled:opacity-40 disabled:cursor-not-allowed"
        >
          {saving ? <Loader2 className="w-4 h-4 animate-spin" /> : <Save className="w-4 h-4" />}
          Save
        </button>
      </div>
    </div>
  );
}
