/* Mémoire d'erreurs — journal consultable des erreurs nommées (AUDIT §C.4).
   La donnée existait déjà (session-log) ; cette vue la rend métacognitive :
   chronologie des ratés, filtre par tag, item correct réécoutable quand il est
   résolvable. Lecture seule — la réparation se lance depuis Apprendre. */

const ERROR_MEMORY_LIMIT = 100;
const ERROR_TAG_LABEL = {
  forme: "Forme", son: "Son", batchim: "Batchim", sens: "Sens", contexte: "Contexte",
  aide: "Aide", registre: "Registre", espace: "Espacement", particule: "Particule",
  terminaison: "Terminaison", ordre: "Ordre", comprehension: "Compréhension",
};

function errorMemoryEntries() {
  const store = window.LangStore;
  const Log = window.LangSessionLog;
  if (!store || !Log) return [];
  const clean = window.LangValidate && window.LangValidate.normalizeErrorTags
    ? (tags) => window.LangValidate.normalizeErrorTags(tags)
    : (tags) => (Array.isArray(tags) ? tags : []);
  const out = [];
  Log.all(store).forEach(session => {
    (session.results || []).forEach(r => {
      if (!r || r.skipped) return;
      const tags = clean(r.errorTags);
      const failed = r.correct === false || (r.correctedAfterRetry && tags.length);
      if (!failed && !tags.length) return;
      if (r.correct === true && !r.correctedAfterRetry) return;
      out.push({
        at: r.finishedAt || session.finishedAt || 0,
        kind: r.kind || "exercice",
        tags,
        answer: typeof r.answer === "string" ? r.answer : "",
        itemId: r.itemId || "",
        corrected: !!r.correctedAfterRetry,
      });
    });
  });
  out.sort((a, b) => b.at - a.at);
  return out.slice(0, ERROR_MEMORY_LIMIT);
}

const ERROR_KIND_LABEL = {
  cards_srs: "Carte", vocab_freq: "Vocabulaire", guided_production: "Production",
  dialogue_reply: "Réplique", dictation: "Dictée", dictation_line: "Dictée",
  dialogue_comprehension: "Compréhension", error_repair: "Réparation",
  practice_vocab: "Cardio vocab", transfer_check: "Transfert",
};

function ErrorMemoryView({ onBack }) {
  const [entries] = useState(errorMemoryEntries);
  const [tagFilter, setTagFilter] = useState("");
  const [items, setItems] = useState({}); // itemId -> {kr, fr}

  useEffect(() => {
    let alive = true;
    if (!window.LangData || !entries.length) return () => { alive = false; };
    const wanted = new Set(entries.map(e => e.itemId).filter(Boolean));
    if (!wanted.size) return () => { alive = false; };
    Promise.all([
      window.LangData.loadVocabFreq ? window.LangData.loadVocabFreq().catch(() => null) : null,
      window.LangData.loadCardsP0 ? window.LangData.loadCardsP0().catch(() => null) : null,
    ]).then(([vocab, cards]) => {
      if (!alive) return;
      const map = {};
      ((vocab && vocab.items) || []).forEach(it => { if (wanted.has(it.id)) map[it.id] = { kr: it.kr, fr: it.fr || "" }; });
      ((cards && cards.cards) || []).forEach(c => { if (wanted.has(c.id)) map[c.id] = { kr: c.kr, fr: c.meaning_fr || c.fr || "" }; });
      setItems(map);
    });
    return () => { alive = false; };
  }, [entries]);

  const counts = {};
  entries.forEach(e => e.tags.forEach(t => { counts[t] = (counts[t] || 0) + 1; }));
  const topTags = Object.entries(counts).sort((a, b) => b[1] - a[1]);
  const shown = tagFilter ? entries.filter(e => e.tags.includes(tagFilter)) : entries;

  return (
    <div style={{ display: "grid", gap: "var(--gap)" }}>
      <div style={{ display: "flex", gap: 12, alignItems: "center", flexWrap: "wrap" }}>
        <Btn kind="ghost" size="sm" icon="prev" onClick={onBack}>Pilotage</Btn>
        <Eyebrow>Mémoire d'erreurs</Eyebrow>
        <span className="faint" style={{ fontSize: 12.5 }}>{entries.length} erreur{entries.length > 1 ? "s" : ""} journalisée{entries.length > 1 ? "s" : ""} (les {ERROR_MEMORY_LIMIT} plus récentes)</span>
      </div>
      {entries.length === 0 ? (
        <EmptyState icon="book" title="Aucune erreur journalisée" body="Vos prochains ratés de séance apparaîtront ici, nommés et datés — c'est la matière première de la réparation." />
      ) : (
        <>
          {topTags.length > 0 && (
            <div style={{ display: "flex", gap: 6, flexWrap: "wrap", alignItems: "center" }}>
              <span className="faint" style={{ fontSize: 12.5 }}>Par tag :</span>
              {topTags.map(([tag, n]) => (
                <button key={tag} onClick={() => setTagFilter(tagFilter === tag ? "" : tag)} className="chip" style={{
                  cursor: "pointer", fontSize: 12.5,
                  background: tagFilter === tag ? "var(--warn-tint)" : "var(--card)",
                  color: tagFilter === tag ? "var(--warn)" : "var(--ink-soft)",
                  borderColor: tagFilter === tag ? "transparent" : "var(--rule)",
                }}>{ERROR_TAG_LABEL[tag] || tag} · {n}</button>
              ))}
              {tagFilter && <button onClick={() => setTagFilter("")} className="chip" style={{ cursor: "pointer", fontSize: 12 }}>Tout voir</button>}
            </div>
          )}
          <div style={{ display: "grid", gap: 8 }}>
            {shown.map((e, i) => {
              const item = e.itemId ? items[e.itemId] : null;
              return (
                <div key={i} className="card" style={{ padding: "12px 16px", display: "flex", gap: 12, alignItems: "center", flexWrap: "wrap" }}>
                  <span className="faint" style={{ fontSize: 12, width: 78, fontFamily: "var(--mono)" }}>{e.at ? new Date(e.at).toLocaleDateString("fr-FR", { day: "2-digit", month: "2-digit" }) : "—"}</span>
                  <span className="chip" style={{ fontSize: 11 }}>{ERROR_KIND_LABEL[e.kind] || e.kind}</span>
                  <div style={{ flex: "1 1 200px", minWidth: 0 }}>
                    {item
                      ? <Speakable text={item.kr} as="span" gloss={item.fr} className="kr" style={{ fontSize: 16 }}>{item.kr}</Speakable>
                      : (e.answer ? <span className="kr faint" style={{ fontSize: 14, textDecoration: "line-through" }}>{e.answer}</span> : <span className="faint" style={{ fontSize: 12.5 }}>—</span>)}
                    {item && e.answer && e.answer !== item.kr && <span className="kr faint" style={{ fontSize: 12.5, marginLeft: 8, textDecoration: "line-through" }}>{e.answer}</span>}
                  </div>
                  <div style={{ display: "flex", gap: 5, flexWrap: "wrap" }}>
                    {e.corrected && <span className="chip" style={{ fontSize: 10.5, background: "var(--good-tint)", color: "var(--good)", borderColor: "transparent" }}>corrigé en reprise</span>}
                    {e.tags.map(t => <span key={t} className="chip" style={{ fontSize: 10.5, background: "var(--warn-tint)", color: "var(--warn)", borderColor: "transparent" }}>{ERROR_TAG_LABEL[t] || t}</span>)}
                  </div>
                </div>
              );
            })}
          </div>
        </>
      )}
    </div>
  );
}

Object.assign(window, { ErrorMemoryView });
