/* Runner - bloc dictogloss (PEDAGOGIE P18) : écouter un mini-passage connu
   (2 lignes, 2 écoutes max), puis le reconstruire DE MÉMOIRE — pas de réécoute
   pendant l'écriture. Comparaison ligne à ligne avec contraste et tags ; libre
   (srs none), le résultat journalise réussite/écarts. */

const DICTOGLOSS_PASS_SIMILARITY = 0.85;

function dictoglossPlayAll(lines, onEnd) {
  if (!window.LangAudio || !lines.length) { if (onEnd) onEnd(); return; }
  let i = 0;
  const playNext = () => {
    if (i >= lines.length) { if (onEnd) onEnd(); return; }
    const line = lines[i];
    i += 1;
    window.LangAudio.speak(line.kr, {
      url: line.audio && line.audio.url,
      ref: line.audio && line.audio.ref,
      onEnd: () => setTimeout(playNext, 450),
    });
  };
  playNext();
}

function RunnerDictoglossBlock({ exercise, glossFor, onDone }) {
  const p = exercise.prompt || {};
  const lines = Array.isArray(p.lines) ? p.lines : [];
  const maxListens = Number.isFinite(p.listens) ? p.listens : 2;
  const [listens, setListens] = useState(0);
  const [playing, setPlaying] = useState(false);
  const [writing, setWriting] = useState(false);
  const [answers, setAnswers] = useState(() => lines.map(() => ""));
  const [checked, setChecked] = useState(null); // [{cmp, contrast}]
  useEffect(() => { setListens(0); setPlaying(false); setWriting(false); setAnswers(lines.map(() => "")); setChecked(null); }, [exercise.id]);

  const listen = () => {
    if (playing || listens >= maxListens || writing) return;
    setPlaying(true);
    setListens(n => n + 1);
    dictoglossPlayAll(lines, () => setPlaying(false));
  };

  const setAnswer = (index, value) => {
    setAnswers(prev => prev.map((a, k) => (k === index ? value : a)));
    setChecked(null);
  };

  const check = () => {
    const V = window.LangValidate;
    const results = lines.map((line, k) => {
      const cmp = V.compare(line.kr, answers[k] || "", { ignorePunct: true });
      const contrast = cmp.correct ? null : V.contrast(line.kr, answers[k] || "", { ignorePunct: true });
      return { cmp, contrast };
    });
    setChecked(results);
    if (window.LangSounds) {
      const okAll = results.every(r => r.cmp.correct || r.cmp.similarity >= DICTOGLOSS_PASS_SIMILARITY);
      (okAll ? window.LangSounds.correct : window.LangSounds.wrong)();
    }
  };

  const finish = () => {
    if (!checked) return;
    const okAll = checked.every(r => r.cmp.correct || r.cmp.similarity >= DICTOGLOSS_PASS_SIMILARITY);
    const tags = [];
    checked.forEach(r => { if (!r.cmp.correct) (r.cmp.tags || []).forEach(t => { if (tags.indexOf(t) < 0) tags.push(t); }); });
    onDone({ correct: okAll, answer: answers.join(" / "), errorTags: okAll ? [] : tags, feedbackShown: true });
  };

  const canWrite = listens > 0;
  const filled = answers.every(a => String(a || "").trim());

  return (
    <div style={{ display: "grid", gap: 16 }}>
      <div className="card" style={{ padding: 24, display: "grid", gap: 14 }}>
        <Eyebrow>Dictogloss — reconstruire de mémoire{p.title ? ` · ${polishRunnerText(p.title)}` : ""}</Eyebrow>
        <div style={{ display: "flex", alignItems: "center", gap: 10, flexWrap: "wrap" }}>
          <span className="chip">1 · écouter le passage</span>
          <Btn kind={listens === 0 ? "primary" : "secondary"} size="sm" icon="speaker" disabled={playing || writing || listens >= maxListens} onClick={listen}>
            {playing ? "Écoute en cours…" : `Écouter (${listens}/${maxListens})`}
          </Btn>
          <span className="faint" style={{ fontSize: 12.5 }}>{lines.length} lignes · pas de réécoute pendant l'écriture.</span>
        </div>
        {canWrite && !writing && !checked && (
          <Btn kind="primary" size="sm" icon="pen" onClick={() => setWriting(true)} style={{ justifySelf: "start" }}>2 · Reconstruire maintenant</Btn>
        )}
        {writing && (
          <div className="fade-up" style={{ display: "grid", gap: 10 }}>
            <div style={{ display: "flex", alignItems: "center", gap: 8, flexWrap: "wrap" }}>
              <span className="chip">2 · écrire de mémoire</span>
              <span className="faint" style={{ fontSize: 12.5 }}>Le sens exact compte plus que la perfection — écris ce que tu as retenu, ligne par ligne.</span>
            </div>
            {lines.map((line, k) => (
              <div key={line.id || k} style={{ display: "grid", gap: 4 }}>
                <span className="faint" style={{ fontSize: 12 }}>Ligne {k + 1}{line.fr ? ` · ${line.fr}` : ""}</span>
                <input value={answers[k]} onChange={ev => setAnswer(k, ev.target.value)} className="kr" lang="ko"
                  autoCapitalize="off" autoCorrect="off" spellCheck={false} placeholder="…"
                  disabled={!!checked}
                  style={{ padding: "10px 12px", borderRadius: "var(--radius-sm)", border: "1px solid var(--rule)", background: checked ? (checked[k].cmp.correct || checked[k].cmp.similarity >= DICTOGLOSS_PASS_SIMILARITY ? "var(--good-tint)" : "var(--warn-tint)") : "var(--card-2)", color: "var(--ink)", fontSize: 18 }} />
              </div>
            ))}
            {checked && (
              <div className="fade-up" style={{ display: "grid", gap: 10, padding: "12px 14px", borderRadius: "var(--radius-sm)", background: "var(--card-2)", border: "1px solid var(--rule)" }}>
                <span className="eyebrow">Modèle — compare ligne à ligne</span>
                {lines.map((line, k) => (
                  <div key={k} style={{ display: "grid", gap: 5 }}>
                    <Speakable text={line.kr} as="span" gloss={line.fr} className="kr" style={{ fontSize: 17 }}>{line.kr}</Speakable>
                    {!checked[k].cmp.correct && checked[k].contrast && <ContrastFeedback contrast={checked[k].contrast} />}
                    {checked[k].cmp.correct && <span className="faint" style={{ fontSize: 12 }}>Exact.</span>}
                  </div>
                ))}
              </div>
            )}
          </div>
        )}
      </div>
      <div style={{ display: "flex", justifyContent: "flex-end", gap: 8 }}>
        {writing && !checked && <Btn kind="primary" icon="check" disabled={!filled} onClick={check}>Comparer au modèle</Btn>}
        {checked && <Btn kind="primary" icon="chevronR" onClick={finish}>Continuer</Btn>}
      </div>
    </div>
  );
}

Object.assign(window, { RunnerDictoglossBlock });
