// shared.jsx — shared components for Finaz C02-B screens
// All components expect to be rendered inside .screen wrapper which sets style/density.

const { useState, useEffect, useRef, useMemo, useCallback } = React;

/* ─── Icons (inline SVG, 1.5 px stroke) ───────────────────────── */
const Icon = {
  arrowR: () => <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.75" strokeLinecap="round" strokeLinejoin="round"><path d="M5 12h14M13 6l6 6-6 6"/></svg>,
  arrowL: () => <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.75" strokeLinecap="round" strokeLinejoin="round"><path d="M19 12H5M11 6l-6 6 6 6"/></svg>,
  play:   () => <svg width="12" height="12" viewBox="0 0 24 24" fill="currentColor"><path d="M8 5v14l11-7z"/></svg>,
  pause:  () => <svg width="12" height="12" viewBox="0 0 24 24" fill="currentColor"><path d="M6 5h4v14H6zM14 5h4v14h-4z"/></svg>,
  skip:   () => <svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.75" strokeLinecap="round" strokeLinejoin="round"><path d="M5 4l10 8-10 8zM19 5v14"/></svg>,
  cc:     () => <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.75" strokeLinecap="round" strokeLinejoin="round"><rect x="3" y="5" width="18" height="14" rx="2"/><path d="M8 10.5C8 9.7 7.3 9 6.5 9S5 9.7 5 10.5v3c0 .8.7 1.5 1.5 1.5S8 14.3 8 13.5"/><path d="M16 10.5c0-.8-.7-1.5-1.5-1.5s-1.5.7-1.5 1.5v3c0 .8.7 1.5 1.5 1.5s1.5-.7 1.5-1.5"/></svg>,
  close:  () => <svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><path d="M18 6L6 18M6 6l12 12"/></svg>,
  lock:   () => <svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.75" strokeLinecap="round" strokeLinejoin="round"><rect x="4" y="11" width="16" height="10" rx="2"/><path d="M8 11V7a4 4 0 0 1 8 0v4"/></svg>,
  check:  () => <svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><polyline points="20 6 9 17 4 12"/></svg>,
  edit:   () => <svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round"><path d="M12 20h9M16.5 3.5a2.121 2.121 0 1 1 3 3L7 19l-4 1 1-4 12.5-12.5z"/></svg>,
  sparkle:() => <svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round"><path d="M12 3v3M12 18v3M3 12h3M18 12h3M5.6 5.6l2.1 2.1M16.3 16.3l2.1 2.1M5.6 18.4l2.1-2.1M16.3 7.7l2.1-2.1"/></svg>,
  spark:  () => <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round"><path d="M3 17l4-4 4 4 5-5 5 5"/><circle cx="3" cy="17" r="0.5" fill="currentColor"/></svg>,
  book:   () => <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round"><path d="M4 19.5A2.5 2.5 0 0 1 6.5 17H20V4H6.5A2.5 2.5 0 0 0 4 6.5v13z"/><path d="M4 19.5V21h16"/></svg>,
  beaker: () => <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round"><path d="M9 3v6L4 19a1 1 0 0 0 .9 1.5h14.2A1 1 0 0 0 20 19l-5-10V3M9 3h6"/></svg>,
  doc:    () => <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round"><path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"/><polyline points="14 2 14 8 20 8"/></svg>,
  chart:  () => <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round"><line x1="3" y1="20" x2="21" y2="20"/><line x1="6" y1="20" x2="6" y2="14"/><line x1="11" y1="20" x2="11" y2="9"/><line x1="16" y1="20" x2="16" y2="12"/><line x1="21" y1="20" x2="21" y2="6"/></svg>,
  grid:   () => <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round"><rect x="3" y="3" width="8" height="8"/><rect x="13" y="3" width="8" height="8"/><rect x="3" y="13" width="8" height="8"/><rect x="13" y="13" width="8" height="8"/></svg>,
  bug:    () => <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round"><rect x="8" y="6" width="8" height="14" rx="4"/><path d="M12 6V3M8 10H5M16 10h3M8 14H5M16 14h3M8 18H5M16 18h3"/></svg>,
  bal:    () => <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round"><path d="M12 3v18M5 7h14M3 11l2-4 2 4M5 11a2 2 0 1 0 4 0M17 11l2-4 2 4M19 11a2 2 0 1 0 4 0"/></svg>,
};

/* ─── Brand bar ──────────────────────────────────────────────── */
function Topbar({ crumbs, right, mastery }) {
  return (
    <div className="topbar">
      <div className="brand">
        <div className="brand-glyph">FZ</div>
        <span style={{ fontSize: 13, letterSpacing: '-0.005em' }}>Finaz</span>
        <span className="mono" style={{ color: 'var(--ink-quiet)', fontSize: 11, marginLeft: 4 }}>C02-B</span>
      </div>
      {crumbs && (
        <div className="crumbs">
          <span className="sep">/</span>
          {crumbs.map((c, i) => (
            <React.Fragment key={i}>
              <span style={{ color: i === crumbs.length - 1 ? 'var(--ink)' : 'var(--ink-muted)' }}>{c}</span>
              {i < crumbs.length - 1 && <span className="sep">/</span>}
            </React.Fragment>
          ))}
        </div>
      )}
      <div className="right">
        {typeof mastery === 'number' && (
          <span className="chip chip-mono"><span className="status-dot now"/> Mastery {mastery}%</span>
        )}
        {right}
      </div>
    </div>
  );
}

/* ─── Regla Finaz breadcrumb ─────────────────────────────────── */
function ReglaFinaz({ step }) {
  // step: 1..4
  const steps = [
    { n: 1, lbl: "Dato observable" },
    { n: 2, lbl: "Hipótesis" },
    { n: 3, lbl: "Evidencia pendiente" },
    { n: 4, lbl: "Lenguaje prudente" },
  ];
  return (
    <div className="regla">
      <span className="kicker" style={{ marginRight: 16 }}>Regla Finaz</span>
      {steps.map((s, i) => (
        <React.Fragment key={s.n}>
          <div className={`regla-step ${s.n === step ? 'active' : s.n < step ? 'done' : ''}`}>
            <span className="regla-num">{s.n < step ? '✓' : s.n}</span>
            <span>{s.lbl}</span>
          </div>
          {i < steps.length - 1 && <span className="regla-arrow">→</span>}
        </React.Fragment>
      ))}
    </div>
  );
}

/* ─── Voice player ───────────────────────────────────────────── */
function VoicePlayer({ caption, progress = 0.34, time = "01:24 / 04:08", speed = "1x", cue }) {
  // caption: { voice: 's'|'m'|'t', name, cue, text }
  return (
    <div className="voiceplayer">
      <div className="vp-caption">
        {caption && (
          <>
            <div className={`vp-voice ${caption.voice}`}>
              {caption.voice === 's' ? 'SO' : caption.voice === 'm' ? 'MA' : 'TF'}
            </div>
            <div className="vp-cap-text">
              <span className="vp-cap-name">{caption.name}</span>
              <span>{caption.text}</span>
              {caption.cue && <span className="vp-cap-cue">[ {caption.cue} ]</span>}
            </div>
          </>
        )}
      </div>
      <div className="vp-row">
        <div className="vp-ctrl">
          <button className="vp-btn" aria-label="Anterior"><Icon.skip /></button>
          <button className="vp-btn play" aria-label="Play"><Icon.play /></button>
          <button className="vp-btn" aria-label="Siguiente pausa" title="Saltar a la siguiente pausa didáctica">
            <svg width="11" height="11" viewBox="0 0 24 24" fill="currentColor"><path d="M5 4l10 8-10 8zM19 5v14h-2V5h2z"/></svg>
          </button>
        </div>
        <button className="vp-btn" aria-label="Captions" style={{ background: 'var(--ink)', color: 'var(--bg)', borderColor: 'var(--ink)' }}>
          <Icon.cc />
        </button>
        <div className="vp-track"><div className="vp-track-fill" style={{ width: `${progress * 100}%` }}/></div>
        <span className="vp-time mono">{time}</span>
        <button className="vp-speed mono">{speed}</button>
      </div>
    </div>
  );
}

/* ─── Flash card (the "i" pop) ───────────────────────────────── */
function FlashCard({ term, onClose, anchor = "below" }) {
  const t = window.FinazData.glossary.find(g => g.id === term);
  if (!t) return null;
  const catColors = {
    working_capital: 'chip-accent', earnings_quality: 'chip-accent',
    forensic: 'chip-amber', normalization: 'chip-green',
    cash_flow: 'chip-accent', leases: 'chip-accent',
    notes: 'chip-accent', standards: 'chip-accent',
  };
  return (
    <div className="flashcard" role="dialog" style={anchor === "below" ? { top: '110%', left: 0 } : { bottom: '110%', left: 0 }}>
      <div className="fc-head">
        <span className="fc-term">{t.term}</span>
        <div style={{ display: 'flex', gap: 6, alignItems: 'center' }}>
          <span className={`chip ${catColors[t.cat] || 'chip-accent'} fc-cat`}>{t.cat}</span>
          {onClose && <button className="btn btn-quiet btn-sm" onClick={onClose} style={{ padding: 4 }}><Icon.close /></button>}
        </div>
      </div>
      <p style={{ color: 'var(--ink)', fontSize: 12.5 }}>{t.def}</p>
      {t.formula !== "—" && (
        <div className="fc-section">
          <div className="fc-label">Fórmula</div>
          <span className="fc-formula">{t.formula}</span>
        </div>
      )}
      <div className="fc-section">
        <div className="fc-label">Ejemplo</div>
        <p style={{ color: 'var(--ink-muted)' }}>{t.example}</p>
      </div>
      <div className="fc-section">
        <div className="fc-label">Por qué importa</div>
        <p style={{ color: 'var(--ink-muted)' }}>{t.why}</p>
      </div>
      <div className="fc-section">
        <div className="fc-label">Misconception</div>
        <p style={{ color: 'var(--ink-muted)' }}>{t.mis}</p>
      </div>
      <div className="fc-section">
        <div className="fc-label">Flash question</div>
        <div className="fc-mini-q">
          <div style={{ marginBottom: 4 }}>{t.q}</div>
          <details>
            <summary style={{ cursor: 'pointer', fontSize: 11, color: 'var(--accent-deep)', fontWeight: 600 }}>Ver respuesta</summary>
            <div style={{ marginTop: 6, color: 'var(--ink-muted)', fontStyle: 'italic' }}>{t.a}</div>
          </details>
        </div>
      </div>
    </div>
  );
}

/* ─── InfoI · clickable token with popover ───────────────────── */
function InfoI({ termId, children, consulted = false, anchor = "below" }) {
  const [open, setOpen] = useState(false);
  const [wasConsulted, setWasConsulted] = useState(consulted);
  return (
    <span style={{ position: 'relative', display: 'inline' }}>
      {children && (
        <span className="tok" onClick={() => { setOpen(o => !o); setWasConsulted(true); }}>
          {children}
          <i className={`info-i ${wasConsulted ? 'consulted' : ''}`} style={{ marginLeft: 4 }}>i</i>
        </span>
      )}
      {!children && (
        <i className={`info-i ${wasConsulted ? 'consulted' : ''}`} onClick={(e) => { e.stopPropagation(); setOpen(o => !o); setWasConsulted(true); }}>i</i>
      )}
      {open && (
        <>
          <div style={{ position: 'fixed', inset: 0, zIndex: 49 }} onClick={() => setOpen(false)} />
          <FlashCard term={termId} onClose={() => setOpen(false)} anchor={anchor} />
        </>
      )}
    </span>
  );
}

/* ─── Tutor Finaz · right rail ──────────────────────────────── */
function TutorPanel({ message, actions = ["explain_formula", "show_hint", "ask_socratic_question", "open_inline_glossary"] }) {
  const labels = {
    explain_formula: ["Explicar fórmula", "explain_formula"],
    show_hint: ["Pedir pista", "show_hint"],
    ask_socratic_question: ["Pregunta socrática", "ask_socratic_question"],
    map_item_to_statement: ["Mapear al estado", "map_item_to_statement"],
    suggest_remediation: ["Sugerir remediación", "suggest_remediation"],
    open_inline_glossary: ["Abrir glosario", "open_inline_glossary"],
  };
  return (
    <aside className="tutor scroll-y">
      <div>
        <h4>
          <span style={{ display: 'flex', alignItems: 'center', gap: 8 }}>
            <span className="tutor-glyph">TF</span>
            <span>Tutor Finaz</span>
          </span>
          <span className="chip chip-green" style={{ fontSize: 9.5 }}>MCP · activo</span>
        </h4>
      </div>
      {message && (
        <div className="tutor-msg">
          <span className="tutor-msg-name">Tutor Finaz</span>
          {message}
        </div>
      )}
      <div>
        <div className="kicker" style={{ marginBottom: 8 }}>Acciones permitidas</div>
        <div className="tutor-actions">
          {actions.map(a => (
            <button key={a} className="tutor-action">
              <span>{labels[a][0]}</span>
              <span className="mono">{labels[a][1]}()</span>
            </button>
          ))}
        </div>
      </div>
      <div>
        <div className="kicker" style={{ marginBottom: 8 }}>Acciones bloqueadas</div>
        <div className="tutor-actions" style={{ opacity: 0.55 }}>
          <div className="tutor-action" style={{ cursor: 'not-allowed' }}>
            <span style={{ textDecoration: 'line-through' }}>Consejo de inversión</span>
            <span className="mono">investment_advice</span>
          </div>
          <div className="tutor-action" style={{ cursor: 'not-allowed' }}>
            <span style={{ textDecoration: 'line-through' }}>Declarar fraude sin evidencia</span>
            <span className="mono">claim_fraud_*</span>
          </div>
        </div>
      </div>
      <div className="card" style={{ background: 'var(--bg-elev-2)', borderColor: 'var(--rule)', padding: 12, fontSize: 11.5, color: 'var(--ink-muted)' }}>
        <strong style={{ color: 'var(--ink)' }}>Tu progreso aquí</strong>
        <div style={{ marginTop: 6 }}>
          Términos consultados <span className="mono strong" style={{ marginLeft: 4 }}>3/8</span>
          <br/>
          Tiempo en escena <span className="mono strong" style={{ marginLeft: 4 }}>04:08</span>
          <br/>
          Memo abierto <span className="mono">no</span>
        </div>
      </div>
    </aside>
  );
}

/* ─── Disclaimer band ───────────────────────────────────────── */
function Disclaimer({ extra }) {
  return (
    <div className="disclaimer">
      <span>Contenido educativo. No constituye recomendación de inversión ni acusación legal.</span>
      <span className="mono">{extra || "es-ES · C02-B · v2.0.0"}</span>
    </div>
  );
}

/* ─── Mastery ring ──────────────────────────────────────────── */
function Ring({ value = 0, size = 56, stroke = 4, showLabel = true }) {
  const r = (size - stroke) / 2;
  const circ = 2 * Math.PI * r;
  const off = circ - (value / 100) * circ;
  return (
    <div className="ring" style={{ width: size, height: size }}>
      <svg>
        <circle cx={size/2} cy={size/2} r={r} className="ring-bg" strokeWidth={stroke} />
        <circle cx={size/2} cy={size/2} r={r} className="ring-fill" strokeWidth={stroke}
                strokeDasharray={circ} strokeDashoffset={off} strokeLinecap="round" />
        {/* 75% mastery mark */}
        <circle cx={size/2 + r * Math.cos((-90 + 270) * Math.PI/180)}
                cy={size/2 + r * Math.sin((-90 + 270) * Math.PI/180)}
                r={1.5} fill="var(--ink)" />
      </svg>
      {showLabel && <div className="ring-num">{value}</div>}
    </div>
  );
}

/* ─── Status dot + label ────────────────────────────────────── */
function StatusPill({ status }) {
  const map = {
    done: { cls: 'done', txt: 'completado' },
    now:  { cls: 'now',  txt: 'en progreso' },
    next: { cls: 'next', txt: 'siguiente' },
    lock: { cls: 'lock', txt: 'bloqueado' },
  };
  const s = map[status] || map.next;
  return <span className="kicker"><span className={`status-dot ${s.cls}`}/> {s.txt}</span>;
}

/* ─── Sparkline ─────────────────────────────────────────────── */
function Sparkline({ data, width = 60, height = 18, color = "var(--accent)" }) {
  const max = Math.max(...data), min = Math.min(...data);
  const range = (max - min) || 1;
  const pts = data.map((v, i) => `${(i / (data.length - 1)) * width},${height - ((v - min) / range) * height}`).join(" ");
  return (
    <svg width={width} height={height} style={{ display: 'inline-block', verticalAlign: 'middle' }}>
      <polyline points={pts} fill="none" stroke={color} strokeWidth="1.25" strokeLinecap="round" strokeLinejoin="round"/>
    </svg>
  );
}

/* Export to globals so other JSX files can use them */
Object.assign(window, {
  Icon, Topbar, ReglaFinaz, VoicePlayer, FlashCard, InfoI,
  TutorPanel, Disclaimer, Ring, StatusPill, Sparkline,
});
