// questions.jsx — Écran « À confirmer » (étape 5/6) + 3 variantes tweakables.
// Le moteur a proposé une valeur pour chaque champ ; l'utilisateur valide ou ajuste.
//
// CÂBLAGE (2026-08-07, passe « enlever le static ») : les champs viennent du
// RUN réel, point — le jeu de champs de démonstration est parti avec data.jsx.
// Deux portes y mènent : `missingFields[]` (questions) ou `reviewFields[]`
// (révision : tout est rempli, personne n'a confirmé). La confirmation
// distingue ce qui a été EXPLICITEMENT validé — c'est cette liste qui porte
// l'imputabilité et qui seule nourrit la mémoire d'entreprise.
const { useState: useStateQ } = React;

/** missingFields (GraphQL) → la forme attendue par les 3 variantes. */
function fieldsFromRun(run) {
  const WHY = {
    not_in_context: I18N.t("Cette information ne figure ni dans votre profil ni dans votre dossier."),
    low_confidence: I18N.t("L'assistant a une proposition, mais préfère votre confirmation."),
    requires_user_judgment: I18N.t("Cette réponse demande votre jugement et vous engage."),
  };
  return (run && run.missingFields ? run.missingFields : []).map((m) => ({
    id: m.fieldName,
    label: m.question || m.fieldName,
    explication: WHY[m.whyMissing] || I18N.t("À vérifier avant l'envoi de votre {demande}."),
    proposition: m.suggestedValue || "",
    valeur: m.suggestedValue || "",
    mono: ["number", "date"].includes(m.fieldType),
    choices: m.choices || null,
  }));
}

/** reviewFields (phase awaiting_review) → la même forme, avec l'origine.
 *  Le moteur a tout rempli : ce n'est plus « répondre », c'est RELIRE. */
function fieldsFromReview(run) {
  const ORIGIN = {
    context: I18N.t("Repris de votre profil d'entreprise."),
    memory: I18N.t("Réponse que vous aviez déjà validée sur un autre {formulaire}."),
    validated: I18N.t("Déjà validé par vous."),
    inferred: I18N.t("Rédigé par l'IA à partir de votre dossier. À relire."),
  };
  return (run && run.reviewFields ? run.reviewFields : []).map((f) => ({
    id: f.fieldName,
    label: f.label || f.fieldName,
    explication: ORIGIN[f.origin] || ORIGIN.inferred,
    proposition: f.value == null ? "" : String(f.value),
    valeur: f.value == null ? "" : String(f.value),
    mono: ["number", "date"].includes(f.fieldType),
    origin: f.origin,
  }));
}

function ConfirmScreen({ variant, onNext, onBack, runId }) {
  const { t } = useLang();
  const [run] = useRunPolling(runId);
  // Deux portes mènent ici : des questions (awaiting_user) ou une révision
  // finale (awaiting_review — le moteur a tout rempli, personne n'a confirmé).
  const review = !!(runId && run && run.status === "awaiting_review");
  const live = !!(runId && run);
  const fields = review ? fieldsFromReview(run) : fieldsFromRun(run);

  const [done, setDone] = useStateQ({}); // id -> true
  const [vals, setVals] = useStateQ({});
  const [sending, setSending] = useStateQ(false);
  const [err, setErr] = useStateQ(null);

  // Les valeurs se (re)posent quand la source change — un run qui arrive après
  // le premier rendu ne doit pas laisser l'écran sur les mocks.
  React.useEffect(() => {
    const o = {}; fields.forEach((f) => (o[f.id] = f.proposition || f.valeur));
    setVals(o);
  }, [live, fields.length]);

  // Aucun champ en suspens (run absent, ou moteur passé directement à done) :
  // on le dit, on ne fabrique pas des questions pour occuper l'écran.
  if (!fields.length) {
    return (
      <ScreenShell kick={t("Étape {n} sur 6", { n: 5 })} icon="flag" title={t("Rien à confirmer ici")} hideLede>
        <div className="card card-pad" style={{ textAlign: "center", padding: "44px 30px" }}>
          <p className="muted" style={{ maxWidth: 460, margin: "0 auto" }}>
            {live ? t("Le moteur n'a laissé aucune question en suspens pour ce {formulaire}.")
                  : t("Téléversez d'abord un {formulaire} à l'étape précédente : c'est lui qui lance le travail.")}
          </p>
        </div>
        <div className="wiz-nav">
          <Btn kind="ghost" icon="arrowL" onClick={onBack}>{t("Retour")}</Btn>
          {live ? <Btn kind="primary" iconAfter="arrowR" onClick={onNext}>{t("Voir le résultat")}</Btn> : <span />}
        </div>
      </ScreenShell>
    );
  }

  const nbDone = fields.filter((f) => done[f.id]).length;
  const allDone = nbDone === fields.length && fields.length > 0;

  const confirmField = (id) => setDone((d) => ({ ...d, [id]: true }));
  const setVal = (id, v) => setVals((x) => ({ ...x, [id]: v }));

  const submit = async () => {
    setSending(true); setErr(null);
    try {
      if (review) {
        // Révision : les corrections repartent comme réponses, et la liste des
        // champs cochés porte l'imputabilité. Rien n'est généré sans ce geste.
        await G4M.confirmReview({
          runId, corrections: vals,
          validated: fields.filter((f) => done[f.id]).map((f) => f.id),
        });
        onNext();
        return;
      }
      // `validated` = ce que la personne a explicitement confirmé. Les autres
      // réponses partent quand même (le formulaire doit être complet) mais
      // marquées comme non validées côté moteur.
      await G4M.provideAnswers({
        runId,
        answers: vals,
        validated: fields.filter((f) => done[f.id]).map((f) => f.id),
      });
      onNext();
    } catch (e) {
      setErr(e.message);
    } finally {
      setSending(false);
    }
  };

  const shared = { fields, done, vals, confirmField, setVal };

  return (
    <ScreenShell kick={t("Étape {n} sur 6", { n: 5 })} icon="flag"
      title={review ? t("Relisez avant de générer") : t("Confirmez les derniers détails")} hideLede>
      <div className="confirm-intro">
        <Icon name="auto" size={22} />
        <p style={{ fontSize: ".98rem", color: "var(--ink-2)", lineHeight: 1.5 }}>
          {review
            ? <>{t("Le moteur a rempli ")}<b>{t("{n} champs", { n: fields.length })}</b>{t(" sans avoir besoin de vous poser de question. Relisez-les : ce {formulaire} sera déposé en votre nom, et c'est ")}<b>{t("votre confirmation qui l'engage")}</b>{t(". Corrigez ce que vous voulez.")}</>
            : <>{t("L'assistant a ")}<b>{t("déjà proposé une réponse")}</b>{t(" pour chacun de ces {n} champs, à partir de votre fiche projet et de vos documents. Vérifiez simplement que c'est juste et corrigez au besoin.", { n: fields.length })}</>}
        </p>
      </div>

      {/* compteur de progression */}
      <div style={{ display: "flex", alignItems: "center", justifyContent: "space-between", gap: 16, marginBottom: 22 }}>
        <div style={{ flex: 1, maxWidth: 340 }}>
          <div className="prog-track"><div className="prog-fill" style={{ width: (fields.length ? nbDone / fields.length * 100 : 0) + "%" }} /></div>
        </div>
        <span style={{ display: "flex", alignItems: "center", gap: 10 }}>
          <LiveBadge meta={{ loading: false, live: !!live }} />
          <span style={{ fontWeight: 600, color: allDone ? "var(--green)" : "var(--muted)", fontSize: ".9rem" }}>
            {nbDone} / {fields.length} {t(nbDone > 1 ? "confirmés" : "confirmé")}
          </span>
        </span>
      </div>

      {err && <div className="card card-pad" style={{ borderColor: "var(--danger)", marginBottom: 16 }}>
        <b style={{ color: "var(--danger)" }}>{t("Envoi impossible :")}</b> {err}</div>}

      {variant === "conversational" && <ConfVariant {...shared} />}
      {variant === "queue" && <QueueVariant {...shared} />}
      {(variant === "grouped" || !variant) && <GroupedVariant {...shared} />}

      <div className="wiz-nav">
        <Btn kind="ghost" icon="arrowL" onClick={onBack}>{t("Retour")}</Btn>
        <Btn kind="primary" iconAfter="arrowR" onClick={submit} disabled={!allDone || sending}>
          {sending ? t("Envoi…") : allDone ? t("Terminer ma {demande}") : t("Confirmez les {n} champs restants", { n: fields.length - nbDone })}
        </Btn>
      </div>
    </ScreenShell>
  );
}

/* ---------- Variante A : formulaire groupé (tout d'un coup) ---------- */
function GroupedVariant({ fields, done, vals, confirmField, setVal }) {
  return (
    <div>
      {fields.map((f) => {
        const ok = done[f.id];
        return (
          <div className="card qcard" key={f.id} style={{ borderLeftColor: ok ? "var(--green)" : "var(--accent)" }}>
            <div className="qcard-head">
              <span className="qcard-lab">{f.label}{f.aide && <HelpNote>{f.aide}</HelpNote>}</span>
              <span className="proposed-tag"><Icon name="auto" size={14} /> {I18N.t("Proposé par l'assistant")}</span>
            </div>
            <p className="qcard-why">{f.explication}</p>
            <div className="qinput">
              <input className={(f.mono ? "mono " : "") + (ok ? "confirmed" : "")} value={vals[f.id] || ""}
                onChange={(e) => setVal(f.id, e.target.value)} aria-label={f.label} />
              {ok
                ? <Btn kind="secondary" icon="check" onClick={() => {}}>{I18N.t("Confirmé")}</Btn>
                : <Btn kind="primary" icon="check" onClick={() => confirmField(f.id)}>{I18N.t("C'est exact")}</Btn>}
            </div>
          </div>
        );
      })}
    </div>
  );
}

/* ---------- Variante B : conversationnel (une question à la fois) ---------- */
function ConfVariant({ fields, done, vals, confirmField, setVal }) {
  const [idx, setIdx] = useStateQ(0);
  const [edit, setEdit] = useStateQ(false);
  const f = fields[Math.min(idx, fields.length - 1)];
  if (!f) return null;
  const ok = done[f.id];
  const last = idx === fields.length - 1;

  const advance = () => { setEdit(false); if (!last) setIdx(idx + 1); };

  return (
    <div className="conv">
      <div className="conv-progress">{I18N.t("Question {i} sur {n}", { i: idx + 1, n: fields.length })}</div>
      <div className="conv-bubble">
        <div className="conv-from"><span className="av"><Icon name="auto" size={15} /></span> {I18N.t("Assistant Grant4me")}</div>
        <div className="conv-q">{f.label}{f.aide && <HelpNote>{f.aide}</HelpNote>}</div>
        <div className="conv-why">{f.explication}</div>
        <div className="conv-prop">
          <div className="conv-prop-lab"><Icon name="auto" size={12} style={{ verticalAlign: "-1px" }} /> {I18N.t("Ma proposition")}</div>
          {edit
            ? <div className="conv-edit"><input className={f.mono ? "mono" : ""} value={vals[f.id] || ""} autoFocus
                onChange={(e) => setVal(f.id, e.target.value)} aria-label={f.label} /></div>
            : <div className={"conv-prop-val" + (f.mono ? " mono" : "")}>{vals[f.id]}</div>}
        </div>
        <div className="conv-actions">
          {!ok && !edit && <Btn kind="primary" icon="check" onClick={() => { confirmField(f.id); advance(); }}>{I18N.t("Oui, c'est exact")}</Btn>}
          {!ok && !edit && <Btn kind="secondary" icon="edit" onClick={() => setEdit(true)}>{I18N.t("Ajuster")}</Btn>}
          {edit && <Btn kind="primary" icon="check" onClick={() => { confirmField(f.id); advance(); }}>{I18N.t("Enregistrer et continuer")}</Btn>}
          {ok && !edit && <div className="conv-done"><Icon name="check" size={18} strokeWidth={2.4} /> {I18N.t("Confirmé")}</div>}
          {ok && !last && <Btn kind="ghost" iconAfter="arrowR" onClick={() => setIdx(idx + 1)}>{I18N.t("Suivant")}</Btn>}
        </div>
      </div>
      {/* fil des réponses confirmées */}
      <div style={{ display: "flex", gap: 8, justifyContent: "center", marginTop: 6, flexWrap: "wrap" }}>
        {fields.map((ff, i) => (
          <button key={ff.id} type="button" onClick={() => { setIdx(i); setEdit(false); }}
            title={ff.label}
            style={{ width: 11, height: 11, borderRadius: "50%", border: "none", cursor: "pointer", padding: 0,
              background: done[ff.id] ? "var(--green)" : i === idx ? "var(--accent)" : "var(--line-2)",
              transform: i === idx ? "scale(1.3)" : "none" }} />
        ))}
      </div>
    </div>
  );
}

/* ---------- Variante C : file de cartes (une carte à régler à la fois) ---------- */
function QueueVariant({ fields, done, vals, confirmField, setVal }) {
  const [idx, setIdx] = useStateQ(0);
  const f = fields[Math.min(idx, fields.length - 1)];
  if (!f) return null;
  const ok = done[f.id];
  const last = idx === fields.length - 1;
  const next = () => { if (!last) setIdx(idx + 1); };

  return (
    <div className="queue-stage">
      <div className="queue-count">
        <span>{I18N.t("Carte {i} sur {n}", { i: idx + 1, n: fields.length })}</span>
        <span className="queue-dots">
          {fields.map((ff, i) => (
            <span key={ff.id} className={"queue-dot" + (done[ff.id] ? " done" : "") + (i === idx ? " cur" : "")} />
          ))}
        </span>
      </div>
      <div className="qstack">
        {!last && <div className="queue-behind" />}
        {idx < fields.length - 2 && <div className="queue-behind two" />}
        <div className="card qstack-card">
          <div className="qcard-head">
            <span className="qcard-lab">{f.label}{f.aide && <HelpNote>{f.aide}</HelpNote>}</span>
          </div>
          <p className="qcard-why">{f.explication}</p>
          <div className="conv-prop" style={{ margin: "4px 0 0" }}>
            <div className="conv-prop-lab"><Icon name="auto" size={12} style={{ verticalAlign: "-1px" }} /> {I18N.t("Proposé par l'assistant")}</div>
            <div className="qinput" style={{ marginTop: 8 }}>
              <input className={(f.mono ? "mono " : "") + (ok ? "confirmed" : "")} value={vals[f.id] || ""}
                onChange={(e) => setVal(f.id, e.target.value)} aria-label={f.label}
                style={{ background: ok ? "var(--green-bg)" : "#fff" }} />
            </div>
          </div>
          <div className="queue-nav">
            <Btn kind="secondary" icon="arrowL" onClick={() => idx > 0 && setIdx(idx - 1)} disabled={idx === 0}>{I18N.t("Précédent")}</Btn>
            {!ok
              ? <Btn kind="primary" full icon="check" onClick={() => { confirmField(f.id); next(); }}>{I18N.t(last ? "C'est exact, terminer" : "C'est exact, carte suivante")}</Btn>
              : <Btn kind="primary" full iconAfter="arrowR" onClick={next} disabled={last}>{I18N.t(last ? "Toutes confirmées" : "Carte suivante")}</Btn>}
          </div>
        </div>
      </div>
    </div>
  );
}

Object.assign(window, { ConfirmScreen });
