// labs.jsx — Lab archetypes: CALC Beneish, DBG ROIC, CASE-X branching, Forensic Report Studio

const { useState: useStateL, useMemo: useMemoL } = React;

/* ─── S3 · CALC · Beneish M-score (M02.E05) ─────────────── */
function S3CalcBeneish() {
  const { beneishDefaults, beneishCoeffs, beneishCompanies } = window.FinazData;
  const [mode, setMode] = useStateL("formula"); // formula | intuicion
  const [company, setCompany] = useStateL(2); // index
  const [vals, setVals] = useStateL({ ...beneishDefaults });

  React.useEffect(() => {
    setVals({ ...beneishCompanies[company].values });
  }, [company]);

  const order = ["DSRI", "GMI", "AQI", "SGI", "DEPI", "SGAI", "TATA", "LVGI"];
  const intuicion = {
    DSRI: "Cobro más lento",
    GMI:  "Margen baja",
    AQI:  "Activos menos claros",
    SGI:  "Ventas crecen rápido",
    DEPI: "Amortizo menos",
    SGAI: "Gasto SGA cambia",
    TATA: "Accruals altos",
    LVGI: "Más apalancada",
  };
  const contribs = order.map(v => vals[v] * beneishCoeffs[v]);
  const score = -4.84 + contribs.reduce((s, v) => s + v, 0);

  const verdict = score > -2.22 ? "amber" : "green";

  return (
    <div className="screen">
      <Topbar crumbs={["M02", "E05", "S3 · CALC · Beneish M-score"]} mastery={32} />
      <ReglaFinaz step={3} />

      <div style={{ flex: 1, display: 'grid', gridTemplateColumns: '1fr 280px', minHeight: 0 }}>
        <div className="scroll-y" style={{ padding: '24px 32px' }}>
          <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'flex-end', marginBottom: 16 }}>
            <div>
              <div className="kicker" style={{ marginBottom: 6 }}>Lab CALC · Beneish M-score · 8 variables, 0 sentencias</div>
              <h2 style={{ fontSize: 18, fontWeight: 550 }}>
                Beneish no es bola de cristal. Es un perro rastreador: si ladra, abrimos la puerta correcta.
              </h2>
            </div>
            <div style={{ display: 'flex', alignItems: 'center', gap: 8 }}>
              <span className="kicker">Compañía</span>
              <select
                value={company}
                onChange={e => setCompany(parseInt(e.target.value))}
                style={{ font: 'inherit', fontSize: 12, padding: '5px 10px', border: '0.5px solid var(--rule-strong)', borderRadius: 'var(--radius-sm)', background: 'var(--bg-card)', color: 'var(--ink)' }}
              >
                {beneishCompanies.map((c, i) => <option key={i} value={i}>{c.name}</option>)}
              </select>
              <div style={{ display: 'flex', background: 'var(--bg-elev-1)', borderRadius: 'var(--radius-sm)', padding: 2, border: '0.5px solid var(--rule)' }}>
                <button onClick={() => setMode("formula")}
                  style={{ font: 'inherit', fontSize: 11, padding: '5px 10px', borderRadius: 'var(--radius-xs)', border: 0, cursor: 'pointer',
                    background: mode === "formula" ? 'var(--bg)' : 'transparent',
                    boxShadow: mode === "formula" ? 'var(--shadow-1)' : 'none',
                    color: 'var(--ink)' }}>
                  Modo fórmula
                </button>
                <button onClick={() => setMode("intuicion")}
                  style={{ font: 'inherit', fontSize: 11, padding: '5px 10px', borderRadius: 'var(--radius-xs)', border: 0, cursor: 'pointer',
                    background: mode === "intuicion" ? 'var(--bg)' : 'transparent',
                    boxShadow: mode === "intuicion" ? 'var(--shadow-1)' : 'none',
                    color: 'var(--ink)' }}>
                  Modo intuición
                </button>
              </div>
            </div>
          </div>

          {/* Big formula (only formula mode) */}
          {mode === "formula" && (
            <div className="card" style={{ marginBottom: 14, padding: 18 }}>
              <div className="kicker" style={{ marginBottom: 8 }}>Fórmula <InfoI termId="beneish"></InfoI></div>
              <div className="mono" style={{ fontSize: 13, lineHeight: 1.9, color: 'var(--ink)', overflowX: 'auto' }}>
                <span style={{ color: 'var(--ink-quiet)' }}>M =</span> −4,84
                {order.map((v, i) => {
                  const c = beneishCoeffs[v];
                  const sign = c >= 0 ? " + " : " − ";
                  return (
                    <React.Fragment key={v}>
                      <span style={{ color: 'var(--ink-quiet)' }}>{sign}</span>
                      <span>{Math.abs(c)}</span><span style={{ color: 'var(--ink-quiet)' }}>·</span>
                      <InfoI termId="beneish"><span style={{ color: 'var(--accent-deep)', fontWeight: 600 }}>{v}</span></InfoI>
                    </React.Fragment>
                  );
                })}
              </div>
            </div>
          )}

          {/* Variables table + contribution chart */}
          <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 14 }}>
            <div className="card" style={{ padding: 0, overflow: 'hidden' }}>
              <div style={{ padding: '10px 14px', borderBottom: '0.5px solid var(--rule)', background: 'var(--bg-elev-1)', display: 'flex', justifyContent: 'space-between' }}>
                <span style={{ fontSize: 12, fontWeight: 600 }}>Variables · {beneishCompanies[company].name}</span>
                <span className="mono" style={{ fontSize: 10.5, color: 'var(--ink-quiet)' }}>dataset_beneish_50_companies.csv</span>
              </div>
              <table className="tbl">
                <thead>
                  <tr>
                    <th>Variable</th>
                    <th>{mode === "intuicion" ? "Significado" : "Coef."}</th>
                    <th style={{ textAlign: 'right' }}>Valor</th>
                    <th style={{ textAlign: 'right' }}>Contribuye</th>
                  </tr>
                </thead>
                <tbody>
                  {order.map(v => {
                    const cont = vals[v] * beneishCoeffs[v];
                    return (
                      <tr key={v}>
                        <td>
                          <span style={{ display: 'inline-flex', alignItems: 'center', gap: 6 }}>
                            <span className="mono strong" style={{ fontSize: 11.5 }}>{v}</span>
                            <InfoI termId="beneish"/>
                          </span>
                        </td>
                        <td style={{ fontSize: 11.5, color: 'var(--ink-muted)' }}>
                          {mode === "intuicion" ? intuicion[v] : <span className="mono">{beneishCoeffs[v] > 0 ? '+' : '−'}{Math.abs(beneishCoeffs[v])}</span>}
                        </td>
                        <td className="num">
                          <input
                            type="number" step="0.01" value={vals[v]}
                            onChange={e => setVals(o => ({ ...o, [v]: parseFloat(e.target.value) || 0 }))}
                            style={{ width: 70, font: 'inherit', fontFamily: 'var(--type-mono)', fontSize: 12,
                              padding: '3px 6px', border: '0.5px solid var(--rule)', borderRadius: 3,
                              background: 'var(--bg)', color: 'var(--ink)', textAlign: 'right', outline: 'none' }}
                          />
                        </td>
                        <td className="num" style={{ color: cont > 0 ? 'var(--red)' : 'var(--green)' }}>
                          {cont > 0 ? '+' : ''}{cont.toFixed(3)}
                        </td>
                      </tr>
                    );
                  })}
                </tbody>
              </table>
            </div>

            <div className="card" style={{ padding: 18 }}>
              <div className="kicker" style={{ marginBottom: 8 }}>Contribución por variable</div>
              <div style={{ display: 'flex', flexDirection: 'column', gap: 6 }}>
                {order.map(v => {
                  const c = vals[v] * beneishCoeffs[v];
                  const max = Math.max(...order.map(o => Math.abs(vals[o] * beneishCoeffs[o])));
                  const w = Math.abs(c) / max * 50;
                  return (
                    <div key={v} style={{ display: 'grid', gridTemplateColumns: '40px 1fr 50px', gap: 6, alignItems: 'center', fontSize: 11 }}>
                      <span className="mono strong">{v}</span>
                      <div style={{ position: 'relative', height: 14, background: 'var(--bg-elev-1)', borderRadius: 2 }}>
                        <div style={{ position: 'absolute', top: 0, bottom: 0, left: '50%', width: 0.5, background: 'var(--rule-strong)' }}/>
                        <div style={{
                          position: 'absolute', top: 1, bottom: 1,
                          left: c < 0 ? `${50 - w}%` : '50%',
                          width: `${w}%`,
                          background: c > 0 ? 'var(--red)' : 'var(--green)',
                          opacity: 0.85, borderRadius: 1,
                        }}/>
                      </div>
                      <span className="mono num tabular" style={{ color: c > 0 ? 'var(--red)' : 'var(--green)' }}>
                        {c > 0 ? '+' : ''}{c.toFixed(2)}
                      </span>
                    </div>
                  );
                })}
              </div>
            </div>
          </div>

          {/* Big M-score result */}
          <div className="card" style={{ marginTop: 14, padding: 22, display: 'grid', gridTemplateColumns: '1fr 320px', gap: 28, alignItems: 'center' }}>
            <div>
              <div className="kicker" style={{ marginBottom: 8 }}>M-score</div>
              <div style={{ display: 'flex', alignItems: 'baseline', gap: 18 }}>
                <div className="bignum" style={{ color: score > -2.22 ? 'var(--amber)' : 'var(--green)' }}>
                  {score >= 0 ? '+' : ''}{score.toFixed(2)}
                </div>
                <div>
                  <div className="mono" style={{ fontSize: 12, color: 'var(--ink-muted)' }}>umbral −2,22</div>
                  <div style={{ marginTop: 4 }}>
                    {score > -2.22
                      ? <span className="chip chip-amber"><span className="sem-dot" style={{ background: 'var(--amber)' }}/> Sobre umbral · priorizar</span>
                      : <span className="chip chip-green"><span className="sem-dot" style={{ background: 'var(--green)' }}/> Bajo umbral · no priorizar</span>}
                  </div>
                </div>
              </div>
              <div style={{ marginTop: 14, fontSize: 12, color: 'var(--ink-muted)', maxWidth: 480, lineHeight: 1.5, fontStyle: 'italic' }}>
                Score por encima del umbral <strong style={{ color: 'var(--ink)' }}>no prueba manipulación</strong>; indica que esta
                compañía merece una investigación más profunda antes que sus 49 hermanas del dataset.
              </div>
            </div>
            <div style={{ display: 'flex', flexDirection: 'column', gap: 8 }}>
              <button className="btn btn-primary"><Icon.arrowR /> Llevar este hallazgo al memo (S4)</button>
              <button className="btn">Comparar con percentil sectorial</button>
            </div>
          </div>
        </div>

        <TutorPanel
          actions={["explain_formula", "show_hint", "ask_socratic_question", "open_inline_glossary"]}
          message="DSRI alto sin GMI deteriorada suele ser cobro lento sin pérdida de margen. Pregunta antes: ¿mix de clientes, canal nuevo o cutoff?"
        />
      </div>

      <Disclaimer />
    </div>
  );
}

/* ─── S3 · DBG · ROIC ajustado (M03.E06) ───────────────── */
function S3DbgRoic() {
  const { roicReported } = window.FinazData;
  const [flagged, setFlagged] = useStateL({});
  const [addedAdj, setAddedAdj] = useStateL({ "I+D-numerador": true, "I+D-denominador": false });
  const [reveal, setReveal] = useStateL(false);

  const nopatBase = 555;
  const nopatAdj = nopatBase + (addedAdj["I+D-numerador"] ? 310 - 95 : 0);
  const capBase = 2650;
  const capAdj = capBase + (addedAdj["I+D-denominador"] ? 310 + 280 : 0);
  const roicReportedVal = (nopatBase / capBase) * 100;
  const roicAdjVal = (nopatAdj / capAdj) * 100;
  const asymmetric = addedAdj["I+D-numerador"] && !addedAdj["I+D-denominador"];

  const toggleFlag = (label) => setFlagged(f => ({ ...f, [label]: !f[label] }));

  return (
    <div className="screen">
      <Topbar crumbs={["M03", "E06", "S3 · DBG · ROIC ajustado"]} mastery={28} />
      <ReglaFinaz step={3} />

      <div style={{ flex: 1, display: 'grid', gridTemplateColumns: '1fr 280px', minHeight: 0 }}>
        <div className="scroll-y" style={{ padding: '24px 32px' }}>
          <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'flex-end', marginBottom: 14 }}>
            <div>
              <div className="kicker" style={{ marginBottom: 6 }}>Lab DBG · Debugger de estados</div>
              <h2 style={{ fontSize: 18, fontWeight: 550, maxWidth: 620 }}>
                Un ajuste de ROIC mal aplicado: encuentra la incoherencia antes de firmarlo.
              </h2>
            </div>
            <div style={{ display: 'flex', gap: 6 }}>
              <button className="btn btn-quiet btn-sm">Reset</button>
              <button className="btn btn-sm" onClick={() => setReveal(r => !r)}>{reveal ? "Ocultar pista" : "Pista (resta puntos)"}</button>
            </div>
          </div>

          <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 14 }}>
            {/* Statements */}
            <div className="card" style={{ padding: 0, overflow: 'hidden' }}>
              <div style={{ padding: '10px 14px', borderBottom: '0.5px solid var(--rule)', background: 'var(--bg-elev-1)', display: 'flex', justifyContent: 'space-between', alignItems: 'baseline' }}>
                <span style={{ fontSize: 12, fontWeight: 600 }}>Estado reportado · Helios</span>
                <span className="mono" style={{ fontSize: 10.5, color: 'var(--ink-quiet)' }}>EUR M · FY24</span>
              </div>
              <div style={{ padding: 14 }}>
                <div className="kicker" style={{ marginBottom: 6 }}>P&L</div>
                <table className="tbl" style={{ marginBottom: 14 }}>
                  <tbody>
                    {roicReported.pnl.map(r => (
                      <tr key={r.label} style={{ background: flagged[r.label] ? 'var(--amber-soft)' : 'transparent', cursor: 'pointer' }}
                          onClick={() => toggleFlag(r.label)}>
                        <td style={{ fontWeight: r.strong ? 600 : 400 }}>
                          {flagged[r.label] && <span style={{ color: 'var(--amber)', marginRight: 4 }}>⚑</span>}
                          {r.label}
                          {r.note && <span style={{ color: 'var(--ink-quiet)', marginLeft: 6, fontSize: 10.5, fontStyle: 'italic' }}>{r.note}</span>}
                        </td>
                        <td className="num" style={{ fontWeight: r.strong ? 600 : 400 }}>
                          {r.val.toLocaleString('es-ES')}
                        </td>
                      </tr>
                    ))}
                  </tbody>
                </table>
                <div className="kicker" style={{ marginBottom: 6 }}>Balance</div>
                <table className="tbl">
                  <tbody>
                    {roicReported.bs.map(r => (
                      <tr key={r.label} style={{ background: flagged[r.label] ? 'var(--amber-soft)' : 'transparent', cursor: 'pointer' }}
                          onClick={() => toggleFlag(r.label)}>
                        <td style={{ fontWeight: r.strong ? 600 : 400 }}>
                          {flagged[r.label] && <span style={{ color: 'var(--amber)', marginRight: 4 }}>⚑</span>}
                          {r.label}
                        </td>
                        <td className="num" style={{ fontWeight: r.strong ? 600 : 400 }}>
                          {r.val.toLocaleString('es-ES')}
                        </td>
                      </tr>
                    ))}
                  </tbody>
                </table>
              </div>
            </div>

            {/* Adjustments diff */}
            <div className="card" style={{ padding: 0, overflow: 'hidden' }}>
              <div style={{ padding: '10px 14px', borderBottom: '0.5px solid var(--rule)', background: 'var(--bg-elev-1)' }}>
                <span style={{ fontSize: 12, fontWeight: 600 }}>Ajustes aplicados · diff</span>
              </div>
              <div style={{ padding: 14, display: 'flex', flexDirection: 'column', gap: 6 }}>
                <div className="kicker" style={{ marginBottom: 4 }}>NOPAT</div>
                <DiffRow type="add" active={addedAdj["I+D-numerador"]} label="Capitalizar I+D del año (NOPAT)" val="+310" onClick={() => setAddedAdj(a => ({ ...a, "I+D-numerador": !a["I+D-numerador"] }))} />
                <DiffRow type="sub" active={addedAdj["I+D-numerador"]} label="− Amortización I+D capitalizado (NOPAT)" val="−95" onClick={() => setAddedAdj(a => ({ ...a, "I+D-numerador": !a["I+D-numerador"] }))} />
                <div className="kicker" style={{ marginTop: 10, marginBottom: 4 }}>Capital invertido</div>
                <DiffRow type={addedAdj["I+D-denominador"] ? "add" : "missing"} active={addedAdj["I+D-denominador"]}
                  label="+ Capitalizar I+D acumulado en capital invertido"
                  val="+590"
                  onClick={() => setAddedAdj(a => ({ ...a, "I+D-denominador": !a["I+D-denominador"] }))} />
                {asymmetric && (
                  <div className="tutor-msg" style={{ marginTop: 8, borderLeftColor: 'var(--red)', background: 'var(--red-soft)' }}>
                    <span className="tutor-msg-name" style={{ color: 'var(--red)' }}>Asimetría detectada</span>
                    Cada ajuste debe afectar numerador <strong>y</strong> denominador. Si solo afecta a uno, hay incoherencia.
                  </div>
                )}
                {reveal && !addedAdj["I+D-denominador"] && (
                  <div className="tutor-msg" style={{ marginTop: 8 }}>
                    <span className="tutor-msg-name">Pista</span>
                    El error está en el ajuste de I+D: el numerador lo trata como inversión, pero el denominador
                    sigue siendo el reportado.
                  </div>
                )}
              </div>
            </div>
          </div>

          {/* Final calc */}
          <div className="card" style={{ marginTop: 14, padding: 22 }}>
            <div className="kicker" style={{ marginBottom: 12 }}>Cálculo de ROIC ajustado</div>
            <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 20, alignItems: 'center' }}>
              <div>
                <div style={{ fontSize: 12, color: 'var(--ink-muted)', marginBottom: 6 }}>Reportado</div>
                <div className="bignum" style={{ fontSize: 32 }}>{roicReportedVal.toFixed(1)}%</div>
                <div className="mono" style={{ fontSize: 11, color: 'var(--ink-quiet)', marginTop: 6 }}>
                  NOPAT {nopatBase} / Capital {capBase}
                </div>
              </div>
              <div>
                <div style={{ fontSize: 12, color: 'var(--ink-muted)', marginBottom: 6, display: 'flex', alignItems: 'center', gap: 6 }}>
                  Ajustado
                  {asymmetric && <span className="chip chip-red" style={{ fontSize: 9.5 }}>incoherente</span>}
                  {addedAdj["I+D-numerador"] && addedAdj["I+D-denominador"] && <span className="chip chip-green" style={{ fontSize: 9.5 }}>simétrico</span>}
                </div>
                <div className="bignum" style={{ fontSize: 32, color: asymmetric ? 'var(--red)' : addedAdj["I+D-numerador"] ? 'var(--green)' : 'var(--ink)' }}>
                  {roicAdjVal.toFixed(1)}%
                </div>
                <div className="mono" style={{ fontSize: 11, color: 'var(--ink-quiet)', marginTop: 6 }}>
                  NOPAT <span className={addedAdj["I+D-numerador"] ? 'strong' : ''}>{nopatAdj}</span> / Capital <span className={addedAdj["I+D-denominador"] ? 'strong' : ''}>{capAdj}</span>
                </div>
              </div>
            </div>
            <hr className="rule" style={{ margin: '18px 0' }}/>
            <div style={{ fontSize: 12.5, color: 'var(--ink-muted)', lineHeight: 1.6 }}>
              <strong style={{ color: 'var(--ink)' }}>Veredicto pedagógico: </strong>
              {addedAdj["I+D-numerador"] && addedAdj["I+D-denominador"]
                ? "Buen razonamiento. Has cerrado el ajuste simétricamente: numerador y denominador hablan de lo mismo. ROIC ajustado defendible."
                : asymmetric
                ? "Has detectado el patrón clásico. Ajustar solo el NOPAT infla el ROIC al normalizar I+D. Tienes que capitalizar también el I+D acumulado en el capital invertido."
                : "Aún no has aplicado el ajuste. Capitaliza el I+D del año y observa cómo se transforma el cálculo."}
            </div>
          </div>
        </div>

        <TutorPanel
          actions={["explain_formula", "show_hint", "ask_socratic_question", "map_item_to_statement"]}
          message={asymmetric
            ? "El ajuste rompe la coherencia entre numerador y denominador. Pregunta socrática: ¿qué activo estás creando en el balance al capitalizar I+D, y dónde aparece?"
            : "Antes de ajustar, marca las líneas que crees que necesitan revisión. Eso fija la hipótesis."}
        />
      </div>
      <Disclaimer />
    </div>
  );
}

function DiffRow({ type, active, label, val, onClick }) {
  const cls = type === "add" ? "green" : type === "sub" ? "red" : "missing";
  const colors = {
    add: { bg: active ? 'var(--green-soft)' : 'var(--bg-elev-1)', fg: active ? 'var(--green)' : 'var(--ink-muted)', sign: '+' },
    sub: { bg: active ? 'var(--red-soft)'   : 'var(--bg-elev-1)', fg: active ? 'var(--red)'   : 'var(--ink-muted)', sign: '−' },
    missing: { bg: 'var(--amber-soft)', fg: 'var(--amber)', sign: '!' },
  };
  const c = colors[type] || colors.add;
  return (
    <div onClick={onClick} style={{
      display: 'flex', alignItems: 'center', gap: 10, padding: '8px 10px',
      background: c.bg, borderRadius: 'var(--radius-sm)', cursor: 'pointer',
      borderLeft: `3px solid ${c.fg}`,
      fontSize: 11.5, transition: 'background 120ms',
    }}>
      <span className="mono" style={{ color: c.fg, fontWeight: 700, fontSize: 13, width: 12 }}>{c.sign}</span>
      <span style={{ flex: 1, color: 'var(--ink)' }}>
        {type === "missing" && <em style={{ color: c.fg, marginRight: 4 }}>(pendiente)</em>}
        {label}
      </span>
      <span className="mono" style={{ color: c.fg }}>{val}</span>
    </div>
  );
}

/* ─── S3 · CASE-X · branching veredictos (M00.E00) ──────── */
function S3CaseX() {
  const { casexAnomalies } = window.FinazData;
  const [choices, setChoices] = useStateL({}); // anomalyId -> 'green'|'amber'|'red'
  const [activeAnom, setActiveAnom] = useStateL(casexAnomalies[0].id);

  const baseCredit = 100, baseCapital = 100;
  const delta = Object.entries(choices).reduce((acc, [id, c]) => {
    const a = casexAnomalies.find(x => x.id === id);
    const cs = a.consequences[c];
    return { credit: acc.credit + cs.credit, capital: acc.capital + cs.capital };
  }, { credit: 0, capital: 0 });

  const credit = baseCredit + delta.credit;
  const capital = baseCapital + delta.capital;

  return (
    <div className="screen">
      <Topbar crumbs={["M00", "E00", "S3 · CASE-X"]} mastery={Math.max(0, Math.min(100, (credit + capital - 100) / 2))} />
      <ReglaFinaz step={2} />

      <div style={{ flex: 1, display: 'grid', gridTemplateColumns: '320px 1fr 280px', minHeight: 0 }}>
        {/* anomaly list */}
        <div style={{ borderRight: '0.5px solid var(--rule)', padding: '20px 18px', display: 'flex', flexDirection: 'column', minHeight: 0, background: 'var(--bg-elev-1)' }}>
          <div className="kicker" style={{ marginBottom: 4 }}>Caso · Asteria FY24</div>
          <h3 style={{ fontSize: 14, marginBottom: 10 }}>Tres anomalías, un comité</h3>
          <div style={{ fontSize: 11.5, color: 'var(--ink-muted)', marginBottom: 14, lineHeight: 1.5 }}>
            El forense no acusa, formula hipótesis. Emite un veredicto por anomalía. Verás
            las consecuencias sobre tu credibilidad y el capital en riesgo.
          </div>
          <div className="scroll-y" style={{ flex: 1, display: 'flex', flexDirection: 'column', gap: 8 }}>
            {casexAnomalies.map((a, i) => {
              const c = choices[a.id];
              const verdict = c ? a.consequences[c] : null;
              const isActive = activeAnom === a.id;
              return (
                <button key={a.id} onClick={() => setActiveAnom(a.id)} style={{
                  textAlign: 'left', font: 'inherit', cursor: 'pointer',
                  padding: 12,
                  background: isActive ? 'var(--bg)' : 'transparent',
                  border: `0.5px solid ${isActive ? 'var(--rule-strong)' : 'transparent'}`,
                  borderRadius: 'var(--radius-sm)',
                  display: 'flex', flexDirection: 'column', gap: 4,
                }}>
                  <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>
                    <span className="mono" style={{ fontSize: 10.5, color: 'var(--ink-quiet)' }}>Anomalía {i + 1}</span>
                    {c && <span className={`chip chip-${c === 'green' ? 'green' : c === 'amber' ? 'amber' : 'red'}`} style={{ fontSize: 9.5 }}>{c}</span>}
                  </div>
                  <div style={{ fontSize: 13, fontWeight: 500 }}>{a.title}</div>
                  <div style={{ fontSize: 10.5, color: 'var(--ink-quiet)' }}>{a.noteRef}</div>
                </button>
              );
            })}
          </div>
          <hr className="rule" style={{ margin: '14px 0' }}/>
          <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 8 }}>
            <ScoreTile label="Credibilidad" value={credit} delta={delta.credit} />
            <ScoreTile label="Capital en riesgo" value={capital} delta={delta.capital} />
          </div>
        </div>

        {/* active anomaly + decision */}
        <div className="scroll-y" style={{ padding: '24px 32px' }}>
          <ActiveCaseXAnomaly
            anomaly={casexAnomalies.find(a => a.id === activeAnom)}
            choice={choices[activeAnom]}
            onChoose={(c) => setChoices(o => ({ ...o, [activeAnom]: c }))}
          />
        </div>

        <TutorPanel
          actions={["show_hint", "ask_socratic_question", "suggest_remediation"]}
          message="Recuerda la cadena: dato observable → hipótesis → evidencia pendiente. ‘Rojo’ sin evidencia destruye tu credibilidad ante el comité aunque tengas razón."
        />
      </div>
      <Disclaimer />
    </div>
  );
}

function ActiveCaseXAnomaly({ anomaly, choice, onChoose }) {
  const c = choice ? anomaly.consequences[choice] : null;
  return (
    <div style={{ display: 'flex', flexDirection: 'column', gap: 18 }}>
      <div>
        <div className="kicker" style={{ marginBottom: 6 }}>Anomalía activa</div>
        <h2 style={{ fontSize: 22, fontWeight: 550, marginBottom: 10 }}>{anomaly.title}</h2>
        <p style={{ fontSize: 13.5, color: 'var(--ink)', lineHeight: 1.55, maxWidth: 640 }}>{anomaly.data}</p>
        <div style={{ marginTop: 10, fontSize: 11.5, color: 'var(--ink-quiet)' }}>
          <span className="mono">{anomaly.noteRef}</span>
        </div>
      </div>

      <div>
        <div className="kicker" style={{ marginBottom: 10 }}>Tu veredicto</div>
        <div className="sem-group">
          <button className={`sem-btn green ${choice === 'green' ? 'active' : ''}`} onClick={() => onChoose('green')}>
            <span className="sem-lbl"><span className="sem-dot"/> Verde</span>
            <span className="sem-sub">Explicación razonable</span>
          </button>
          <button className={`sem-btn amber ${choice === 'amber' ? 'active' : ''}`} onClick={() => onChoose('amber')}>
            <span className="sem-lbl"><span className="sem-dot"/> Ámbar</span>
            <span className="sem-sub">Exige nota o llamada al management</span>
          </button>
          <button className={`sem-btn red ${choice === 'red' ? 'active' : ''}`} onClick={() => onChoose('red')}>
            <span className="sem-lbl"><span className="sem-dot"/> Rojo</span>
            <span className="sem-sub">Inconsistencias múltiples y materiales</span>
          </button>
        </div>
      </div>

      {c && (
        <div className="card" style={{ borderLeft: `3px solid ${choice === 'green' ? 'var(--green)' : choice === 'amber' ? 'var(--amber)' : 'var(--red)'}` }}>
          <div className="kicker" style={{ marginBottom: 8 }}>Consecuencia del veredicto</div>
          <p style={{ fontSize: 13, lineHeight: 1.55, color: 'var(--ink)' }}>{c.text}</p>
          <div style={{ marginTop: 12, display: 'flex', gap: 18, fontSize: 11.5 }}>
            <span>Credibilidad <span className="mono strong" style={{ color: c.credit > 0 ? 'var(--green)' : c.credit < 0 ? 'var(--red)' : 'var(--ink-muted)' }}>{c.credit > 0 ? '+' : ''}{c.credit}</span></span>
            <span>Capital en riesgo <span className="mono strong" style={{ color: c.capital > 0 ? 'var(--green)' : c.capital < 0 ? 'var(--red)' : 'var(--ink-muted)' }}>{c.capital > 0 ? '+' : ''}{c.capital}</span></span>
            {choice === anomaly.best && <span className="chip chip-green" style={{ fontSize: 9.5 }}><Icon.check /> mejor jugada</span>}
          </div>
          {choice === 'red' && anomaly.best !== 'red' && (
            <div style={{ marginTop: 10, padding: 10, background: 'var(--amber-soft)', borderRadius: 'var(--radius-sm)', fontSize: 12, color: 'var(--amber)' }}>
              <strong>Tutor Finaz:</strong> «Has convertido una señal en acusación. Reformula como hipótesis y añade evidencia pendiente.»
            </div>
          )}
        </div>
      )}
    </div>
  );
}

function ScoreTile({ label, value, delta }) {
  return (
    <div className="card" style={{ padding: 10 }}>
      <div className="kicker">{label}</div>
      <div style={{ display: 'flex', alignItems: 'baseline', gap: 6, marginTop: 4 }}>
        <span className="mono strong" style={{ fontSize: 18 }}>{value}</span>
        {delta !== 0 && (
          <span className="mono" style={{ fontSize: 10.5, color: delta > 0 ? 'var(--green)' : 'var(--red)' }}>
            {delta > 0 ? '+' : ''}{delta}
          </span>
        )}
      </div>
    </div>
  );
}

/* ─── Forensic Report Studio ─────────────────────────────── */
function ForensicReportStudio() {
  const PROHIBITED = ["compra", "vende", "venda", "fraude", "garantía", "garantia"];
  const REVIEW = ["manipula", "engaña", "miente", "estafa"];

  const [verdict, setVerdict] = useStateL('amber');
  const [linked, setLinked] = useStateL({ 0: ["nota-6"], 2: ["nota-12"] });
  const [drag, setDrag] = useStateL(null);

  const sections = [
    { key: "exec",  title: "Resumen ejecutivo · ≤ 80 palabras",
      content: "Asteria reporta crecimiento de ventas del 12% en FY24 sostenido por un comportamiento operativo correcto. No obstante, tres señales —deterioro de DSO, restructuring recurrente y EBITDA ajustado agresivo— configuran un perfil ámbar que justifica investigación y limita la trazabilidad de la calidad reportada del beneficio." },
    { key: "evcua", title: "Evidencia cuantitativa · ≥ 3 ítems",
      items: [
        { txt: "DSO 52→73 con ventas +8%; CFO/NI 1,12 → 0,71.", src: "nota-6", num: 0 },
        { txt: "Restructuring 40 M€ tres años consecutivos.", src: null, num: 1 },
        { txt: "EBITDA ajustado excluye SBC 60 M€ + impairment inventario 22 M€.", src: "nota-12", num: 2 },
      ] },
    { key: "evcua2", title: "Evidencia cualitativa · ≥ 2 ítems",
      items: [
        { txt: "Cambio de auditor sin razón divulgada en sección de gobierno.", src: null, num: 3 },
        { txt: "KAM nuevo sobre revenue recognition: estimaciones materiales.", src: null, num: 4 },
      ] },
    { key: "lim", title: "Limitaciones del análisis",
      content: "Dataset sintético; cierre fiscal sin comparativa transatlántica; pendiente revisión de cláusulas de factoring sin recurso al cierre." },
    { key: "next", title: "Próximos pasos",
      content: "Solicitar envejecimiento por edad de cuentas a cobrar; reconciliación pluri-anual de partidas no recurrentes; comparativa con percentil 50 sectorial." },
  ];

  const sources = [
    { id: "nota-6",  ref: "Nota 6", title: "Cuentas a cobrar y deterioro" },
    { id: "nota-9",  ref: "Nota 9", title: "Working capital y factoring" },
    { id: "nota-12", ref: "Nota 12", title: "Reconciliación non-GAAP" },
    { id: "nota-15", ref: "Nota 15", title: "Restructuring (3 ejercicios)" },
    { id: "nota-21", ref: "Nota 21", title: "Auditor y KAMs" },
  ];

  const flaggedText = (txt) => {
    const tl = txt.toLowerCase();
    return PROHIBITED.some(p => tl.includes(p)) ? 'banned'
         : REVIEW.some(p => tl.includes(p)) ? 'review' : 'clean';
  };

  const linkCount = Object.values(linked).reduce((s, x) => s + x.length, 0);
  const claimsTotal = sections.reduce((s, sec) => s + (sec.items ? sec.items.length : 0), 0);
  const linkPct = Math.round(linkCount / claimsTotal * 100);

  return (
    <div className="screen">
      <Topbar
        crumbs={["Proyecto final", "Forensic Report Studio"]}
        right={
          <>
            <button className="btn btn-quiet btn-sm">Pedir revisión Tutor Finaz</button>
            <button className="btn btn-sm">Export PDF</button>
          </>
        }
      />

      <div style={{ flex: 1, display: 'grid', gridTemplateColumns: '1fr 260px', minHeight: 0 }}>
        <div className="scroll-y" style={{ padding: '24px 36px', borderRight: '0.5px solid var(--rule)' }}>
          <div className="kicker" style={{ marginBottom: 8 }}>Empresa · Asteria · FY24 · sintético</div>
          <h1 style={{ fontSize: 26, fontWeight: 550, marginBottom: 16 }}>Forensic report · Asteria FY24</h1>

          {/* Verdict */}
          <div className="card" style={{ marginBottom: 16 }}>
            <div className="kicker" style={{ marginBottom: 10 }}>Semáforo Finaz · veredicto consolidado</div>
            <div className="sem-group">
              <button className={`sem-btn green ${verdict === 'green' ? 'active' : ''}`} onClick={() => setVerdict('green')}>
                <span className="sem-lbl"><span className="sem-dot"/> Verde</span>
                <span className="sem-sub">Explicación razonable</span>
              </button>
              <button className={`sem-btn amber ${verdict === 'amber' ? 'active' : ''}`} onClick={() => setVerdict('amber')}>
                <span className="sem-lbl"><span className="sem-dot"/> Ámbar</span>
                <span className="sem-sub">Exige nota o llamada</span>
              </button>
              <button className={`sem-btn red ${verdict === 'red' ? 'active' : ''}`} onClick={() => setVerdict('red')}>
                <span className="sem-lbl"><span className="sem-dot"/> Rojo</span>
                <span className="sem-sub">Inconsistencias materiales</span>
              </button>
            </div>
          </div>

          {/* Sections */}
          {sections.map(s => (
            <ReportSection key={s.key} s={s} linked={linked} setLinked={setLinked} drag={drag} flaggedText={flaggedText} />
          ))}

          <div style={{ marginTop: 24, fontSize: 11, color: 'var(--ink-quiet)' }}>
            <span className="mono">{linkCount}/{claimsTotal}</span> claims con fuente · linter: <span className="mono">0 bloqueados, 1 revisión</span>
          </div>
        </div>

        {/* Sources panel */}
        <aside style={{ padding: '24px 18px', display: 'flex', flexDirection: 'column', gap: 12 }}>
          <div>
            <div className="kicker" style={{ marginBottom: 6 }}>Fuentes</div>
            <div style={{ fontSize: 11.5, color: 'var(--ink-muted)', marginBottom: 12 }}>
              Arrastra una fuente a cualquier claim para vincularla.
            </div>
            <div style={{ display: 'flex', flexDirection: 'column', gap: 6 }}>
              {sources.map(src => (
                <div key={src.id}
                  draggable
                  onDragStart={() => setDrag(src.id)}
                  onDragEnd={() => setDrag(null)}
                  style={{
                    padding: 10, background: 'var(--bg-card)',
                    border: '0.5px solid var(--rule)', borderRadius: 'var(--radius-sm)',
                    cursor: 'grab', fontSize: 11.5,
                  }}>
                  <div className="mono strong">{src.ref}</div>
                  <div style={{ color: 'var(--ink-muted)', fontSize: 11 }}>{src.title}</div>
                </div>
              ))}
            </div>
          </div>
          <hr className="rule"/>
          <div>
            <div className="kicker" style={{ marginBottom: 6 }}>Rúbrica · 5 dimensiones</div>
            <div style={{ display: 'flex', flexDirection: 'column', gap: 6, fontSize: 11.5 }}>
              {[
                { l: "Precisión técnica", v: 28, m: 30 },
                { l: "Uso de evidencia", v: 21, m: 25 },
                { l: "Prudencia interpretativa", v: 22, m: 25 },
                { l: "Transferencia", v: 7, m: 10 },
                { l: "Claridad", v: 8, m: 10 },
              ].map(r => (
                <div key={r.l}>
                  <div style={{ display: 'flex', justifyContent: 'space-between', fontSize: 11 }}>
                    <span>{r.l}</span>
                    <span className="mono"><strong>{r.v}</strong>/{r.m}</span>
                  </div>
                  <div className="progress-bar" style={{ height: 2 }}>
                    <div className="progress-bar-fill" style={{ width: `${(r.v/r.m)*100}%` }}/>
                  </div>
                </div>
              ))}
            </div>
            <div className="mono" style={{ fontSize: 11, marginTop: 10, color: 'var(--ink-muted)' }}>
              total <strong className="strong">86</strong>/100 · <span className="chip chip-green" style={{ fontSize: 9.5 }}>≥ 75 OK</span>
            </div>
          </div>
          <hr className="rule"/>
          <div className="tutor-msg" style={{ background: 'var(--accent-soft)', borderLeftColor: 'var(--accent)' }}>
            <span className="tutor-msg-name">Tutor Finaz</span>
            Tu evidencia cuantitativa es sólida. Vincula también la observación de
            restructuring a Nota 15 antes de exportar.
          </div>
        </aside>
      </div>
      <Disclaimer />
    </div>
  );
}

function ReportSection({ s, linked, setLinked, drag, flaggedText }) {
  const handleDrop = (num) => (e) => {
    e.preventDefault();
    if (!drag) return;
    setLinked(o => ({ ...o, [num]: [...new Set([...(o[num] || []), drag])] }));
  };

  return (
    <div className="card" style={{ marginBottom: 12 }}>
      <h4 style={{ marginBottom: 10 }}>{s.title}</h4>
      {s.content && (
        <p style={{ fontSize: 13, lineHeight: 1.55, color: 'var(--ink)' }}>{s.content}</p>
      )}
      {s.items && (
        <div style={{ display: 'flex', flexDirection: 'column', gap: 6 }}>
          {s.items.map(item => {
            const flag = flaggedText(item.txt);
            const linkedSrc = linked[item.num] || [];
            return (
              <div key={item.num}
                onDragOver={(e) => e.preventDefault()}
                onDrop={handleDrop(item.num)}
                style={{
                  padding: '8px 10px',
                  borderLeft: `2px solid ${linkedSrc.length ? 'var(--green)' : 'var(--amber)'}`,
                  background: drag ? 'var(--accent-soft)' : 'var(--bg-elev-1)',
                  borderRadius: 'var(--radius-sm)',
                  display: 'flex', alignItems: 'flex-start', gap: 10, fontSize: 12.5,
                  transition: 'background 120ms',
                }}>
                <span className="mono" style={{ fontSize: 10, color: 'var(--ink-quiet)', marginTop: 2 }}>#{item.num + 1}</span>
                <span style={{ flex: 1 }}>
                  {flag === 'banned' && <span className="chip chip-red" style={{ fontSize: 9.5, marginRight: 6 }}>BLOQ</span>}
                  {flag === 'review' && <span className="chip chip-amber" style={{ fontSize: 9.5, marginRight: 6 }}>REV</span>}
                  {item.txt}
                </span>
                <div style={{ display: 'flex', gap: 4, flexShrink: 0 }}>
                  {linkedSrc.length > 0 ? linkedSrc.map(srcId => (
                    <span key={srcId} className="chip chip-mono" style={{ fontSize: 9.5 }}>{srcId}</span>
                  )) : (
                    <span style={{ fontSize: 10.5, color: 'var(--amber)' }}>sin fuente</span>
                  )}
                </div>
              </div>
            );
          })}
        </div>
      )}
    </div>
  );
}

Object.assign(window, { S3CalcBeneish, S3DbgRoic, S3CaseX, ForensicReportStudio });
