import React, { useEffect, useState } from "react";
import { api } from "./api.js";
import { Spinner } from "./ui.jsx";

function VoiceSelect({ voices, value, onChange }) {
  return (
    <select className="input" value={value || ""} onChange={(e) => onChange(e.target.value)}>
      <option value="">— aucune —</option>
      {voices.map((v) => (
        <option key={v.id} value={v.id}>
          {v.label || v.id} ({v.gender === "male" ? "H" : v.gender === "female" ? "F" : "?"})
        </option>
      ))}
    </select>
  );
}

export default function CastEditor({ slug, busy }) {
  const [cast, setCast] = useState(null);
  const [voices, setVoices] = useState([]);
  const [saved, setSaved] = useState(false);
  const [playing, setPlaying] = useState(null);
  const [msg, setMsg] = useState(null);
  const dedupPending = React.useRef(false);

  const reload = () =>
    api.getCast(slug).then((d) => { setCast(d.cast); setVoices(d.voicebank.entries); });

  useEffect(() => { reload(); }, [slug]);
  // Recharge le casting quand un job de fond (dédup / casting chapitre) se termine.
  useEffect(() => {
    if (busy) return;
    reload().then(() => {
      if (dedupPending.current) {
        dedupPending.current = false;
        api.getCast(slug).then((d) =>
          setMsg(`✓ déduplication terminée — ${d.cast.characters.length} personnages`));
      }
    });
  }, [busy]);

  const dedup = async () => {
    setMsg(null);
    try {
      dedupPending.current = true;
      await api.castDedup(slug);
      setMsg("Déduplication lancée…");
    } catch (e) {
      dedupPending.current = false;
      setMsg("Échec : " + e + " (le serveur backend est-il à jour ? redémarre-le)");
    }
  };

  if (!cast) return <p className="text-ink-muted"><Spinner /> chargement du casting…</p>;
  if (!cast.characters.length)
    return <p className="text-ink-muted">Lancez d'abord l'<b>Analyse</b> puis le <b>Casting</b>.</p>;

  const update = (patch) => { setCast({ ...cast, ...patch }); setSaved(false); };
  const setChar = (name, voiceId) =>
    update({ characters: cast.characters.map((c) => c.name === name ? { ...c, voice_id: voiceId } : c) });

  const preview = async (voiceId) => {
    if (!voiceId) return;
    setPlaying(voiceId);
    try {
      const url = await api.previewVoice(voiceId, "Bonjour, voici un aperçu de cette voix.");
      const a = new Audio(url);
      a.onended = () => setPlaying(null);
      a.play();
    } catch { setPlaying(null); }
  };

  const save = async () => { await api.putCast(slug, cast); setSaved(true); };

  return (
    <div className="space-y-4">
      <div className="card flex items-center gap-3 p-3">
        <span className="text-sm text-ink-muted">Narrateur</span>
        <VoiceSelect voices={voices} value={cast.narrator_voice_id}
          onChange={(v) => update({ narrator_voice_id: v })} />
        <button className="btn-ghost" onClick={() => preview(cast.narrator_voice_id)}>
          {playing === cast.narrator_voice_id ? "♪" : "▶"} écouter
        </button>
        <button className="btn-ghost ml-auto" disabled={busy}
          title="Fusionne les variantes d'un même personnage (Holden / James Holden / James)"
          onClick={dedup}>
          {busy ? "…" : "Dédupliquer"}
        </button>
        <button className="btn-primary" onClick={save}>
          {saved ? "✓ enregistré" : "Enregistrer"}
        </button>
      </div>

      {msg && <p className="px-1 text-sm text-ink-muted">{msg}</p>}

      <div className="card divide-y divide-ink-edge">
        {cast.characters.map((c) => (
          <div key={c.name} className="flex items-center gap-3 px-4 py-2.5">
            <div className="flex-1 min-w-0">
              <p className="truncate font-serif text-sm">{c.name}</p>
              {c.aliases?.length > 0 && (
                <p className="truncate text-xs text-ink-muted">alias : {c.aliases.join(", ")}</p>
              )}
              {c.description && <p className="truncate text-xs text-ink-muted">{c.description}</p>}
            </div>
            <span className="chip bg-ink-edge text-ink-muted">
              {c.gender === "male" ? "homme" : c.gender === "female" ? "femme" : "?"}
            </span>
            <VoiceSelect voices={voices} value={c.voice_id}
              onChange={(v) => setChar(c.name, v)} />
            <button className="btn-ghost" onClick={() => preview(c.voice_id)}>
              {playing === c.voice_id ? "♪" : "▶"}
            </button>
          </div>
        ))}
      </div>
    </div>
  );
}
