// views_answer.jsx — retained route, intentionally retired until backed by a
// canonical AI-source/citation-observation DTO.
(function () {
  const { useState, useEffect, useRef } = React;
  const D = window.JS_DATA;
  const S = window.JS_SCORE;

  const STATE_META = {
    cited:   { label: 'Cited', tone: 'green' },
    uncited: { label: 'Paraphrased', tone: 'amber' },
    absent:  { label: 'Absent', tone: 'coral' },
  };

  // ---- tokenize answer segments into per-word spans (for streaming) ------
  // Returns { nodes, count }. Each word carries its global index so CSS can
  // stagger them; the citation sup rides on the segment's final word.
  function tokenize(segs, sources) {
    let idx = 0;
    const nodes = [];
    segs.forEach((s, si) => {
      const words = s.t.split(/(\s+)/); // keep whitespace tokens
      const src = s.cite != null ? sources[s.cite] : null;
      const mine = src && src.you;
      words.forEach((w, wi) => {
        if (/^\s+$/.test(w)) { nodes.push(<span key={si + '-' + wi}>{w}</span>); return; }
        if (w === '') return;
        const isLastWord = wi === words.length - 1 || words.slice(wi + 1).every(x => /^\s*$/.test(x));
        const i = idx++;
        const cls = 'ans-tok'
          + (s.b ? ' ans-strong' : '')
          + (s.cite != null ? ' ans-ent' : '')
          + (mine ? ' is-you' : '');
        nodes.push(
          <span key={si + '-' + wi} className={cls} style={{ '--i': i }}>
            {w}{s.cite != null && isLastWord && <sup className="ans-sup">{s.cite + 1}</sup>}
          </span>
        );
      });
    });
    return { nodes, count: idx };
  }

  // ---- the engine "answer card" (chrome + streamed answer + sources) -----
  function EngineCard({ engine, phase, data, animKey }) {
    const em = D.ENGINE_META[engine] || { mark: 'AI', accent: 'gold', sub: engine };
    const accent = window.accentVar(em.accent);
    const verdict = phase === 'now' ? data.verdict : data.note;
    const { nodes, count } = tokenize(data.answer, data.sources);

    // streaming gate: replay the token stagger every time the card key changes
    const [streaming, setStreaming] = useState(true);
    const [sourcesIn, setSourcesIn] = useState(false);
    useEffect(() => {
      setStreaming(true); setSourcesIn(false);
      const reduce = window.matchMedia('(prefers-reduced-motion: reduce)').matches;
      const per = 26, total = reduce ? 0 : Math.min(count * per + 240, 1600);
      const t1 = setTimeout(() => setSourcesIn(true), reduce ? 0 : total * 0.62);
      const t2 = setTimeout(() => setStreaming(false), total + 60);
      return () => { clearTimeout(t1); clearTimeout(t2); };
    }, [animKey, count]);

    return (
      <div className={'ans-card' + (streaming ? ' is-streaming' : '')} style={{ '--eng': accent }}>
        <div className="ans-cardtop">
          <span className="ans-mark" style={{ background: accent }}>{em.mark}</span>
          <div className="ans-engmeta">
            <span className="ans-engname">{engine}</span>
            <span className="ans-engsub">{em.sub}</span>
          </div>
          <span className="ans-aibadge"><span className="ans-aidot" />{streaming ? 'Generating…' : 'AI-generated'}</span>
        </div>

        <p className="ans-text">{nodes}{streaming && <span className="ans-caret" />}</p>

        <div className={'ans-reveal' + (sourcesIn ? ' is-in' : '')}>
          <div className="ans-srchead"><span className="js-tag">Sources</span><span className="js-tag">{data.sources.length} cited</span></div>
          <div className="ans-sources">
            {data.sources.map((src, i) => (
              <div key={i} className={'ans-src' + (src.you ? ' is-you' : '') + (src.cited ? ' is-cited' : '')}>
                <span className="ans-srcnum">{i + 1}</span>
                <div className="ans-srcbody">
                  <span className="ans-srcname">{src.name}{src.you && <span className="ans-youtag">you</span>}</span>
                  <span className="ans-srcdom">{src.domain}</span>
                </div>
                {src.cited && <span className="ans-srccited">Cited</span>}
              </div>
            ))}
          </div>

          {verdict && (
            <div className={'ans-verdict' + (phase === 'after' ? ' is-good' : '')}>
              <Icon name={phase === 'after' ? 'check' : 'eye'} size={15} />
              <span>{verdict}</span>
            </div>
          )}
        </div>
      </div>
    );
  }

  // ---- head-to-head: you vs the named competitor for this query ----------
  function HeadToHead({ a }) {
    if (!a.competitor) return null;
    const youState = a.state; // cited / uncited / absent
    const youSm = STATE_META[youState];
    const youCited = youState === 'cited';
    return (
      <div className="ans-vs">
        <div className={'ans-vscard' + (youCited ? ' is-win' : ' is-lose')}>
          <span className="vs-who">Your brand <span className="ans-youtag">you</span></span>
          <span className="vs-state" style={{ color: youCited ? 'var(--lime-deep)' : 'var(--coral)' }}>
            {youCited ? 'Cited #' + a.rank : youSm.label}
          </span>
        </div>
        <span className="ans-vsbadge">vs</span>
        <div className="ans-vscard is-comp">
          <span className="vs-who">{a.competitor}</span>
          <span className="vs-state" style={{ color: 'var(--gold)' }}>Cited{youCited ? ' #' + (a.rank + 1) : ' #1'}</span>
        </div>
      </div>
    );
  }

  function AnswerPreview({ go, openSteal, onShip }) {
    return (
      <div className="js-view">
        <div className="js-pagehead">
          <div>
            <p className="eyebrow">In the answer</p>
            <h1>Evidence view <em>retired</em></h1>
            <p className="sub">The Claude answer theatre used static storytelling data. In Cloud Master it is retired until AI-source runs and citation observations define a canonical backend DTO for this view.</p>
          </div>
          <div className="js-head-actions"><Btn icon="puzzle" onClick={() => go('integrations')}>Open AI-source tracking</Btn></div>
        </div>
        <Panel>
          <div className="js-gap sev-medium" style={{ margin: 0 }}>
            <h4><Icon name="alert" size={16} style={{ color: 'var(--gold)' }} />No fixture answers shown</h4>
            <p style={{ margin: 0 }}>Use `POST /api/v1/audits/:id/ai-source-runs`, citation observations, and the AI-source dashboard to collect real evidence. This screen is intentionally not rendering synthetic answer-engine copy.</p>
          </div>
        </Panel>
      </div>
    );
    const queries = Object.keys(D.ANSWERS);
    const [active, setActive] = useState(queries[0]);
    const [phase, setPhase] = useState('now');
    const a = D.ANSWERS[active];
    const hasAfter = !!a.after;
    const showPhase = (phase === 'after' && hasAfter) ? 'after' : 'now';
    const data = a[showPhase];
    const fx = a.fix ? (S.FIXES || []).find(f => f.id === a.fix) : null;
    const steal = openSteal || (() => {});
    const canSteal = window.STEAL_HAS && window.STEAL_HAS(active);

    const counts = queries.reduce((acc, q) => { acc[D.ANSWERS[q].state] = (acc[D.ANSWERS[q].state] || 0) + 1; return acc; }, {});
    const pick = q => { setActive(q); setPhase('now'); };

    return (
      <div className="js-view js-view--wide">
        <div className="js-pagehead">
          <div>
            <p className="eyebrow">In the answer</p>
            <h1>What the engine <em>actually says</em></h1>
            <p className="sub">A faithful preview of how answer engines respond to the questions your buyers ask — streamed the way they generate it — and whether you’re the source they name. Toggle <b style={{ color: 'var(--ink)' }}>After fix</b> to watch a citation flip.</p>
          </div>
          <div className="js-head-actions">
            <span className="js-scorechip"><span className="sc-ring" style={{ background: 'var(--lime)' }} />{counts.cited || 0} cited</span>
            <span className="js-scorechip"><span className="sc-ring" style={{ background: 'var(--coral)' }} />{(counts.absent || 0) + (counts.uncited || 0)} to win</span>
          </div>
        </div>

        <div className="ans-layout">
          {/* query rail */}
          <div className="ans-rail">
            <div className="js-tag ans-railtag">Buyer queries</div>
            {queries.map(q => {
              const qa = D.ANSWERS[q];
              const sm = STATE_META[qa.state];
              return (
                <button key={q} className={'ans-qitem' + (q === active ? ' is-active' : '')} onClick={() => pick(q)}>
                  <span className="aq-q">{q}</span>
                  <span className="aq-meta">
                    <span className="aq-engine">{qa.engine}</span>
                    <Pill tone={sm.tone}>{sm.label}</Pill>
                  </span>
                </button>
              );
            })}
          </div>

          {/* answer stage */}
          <div className="ans-stage">
            <div className="ans-prompt">
              <span className="ans-promptlabel">Prompt</span>
              <span className="ans-promptq">“{active}”</span>
            </div>

            <HeadToHead a={a} />

            {hasAfter ? (
              <div className="ans-toggle">
                <button className={'ans-tg' + (showPhase === 'now' ? ' is-on' : '')} onClick={() => setPhase('now')}>Now</button>
                <button className={'ans-tg ans-tg--after' + (showPhase === 'after' ? ' is-on' : '')} onClick={() => setPhase('after')}>After fix{fx ? ' · +' + a.lift.toFixed(1) : ''}</button>
              </div>
            ) : (
              <div className="ans-own"><Icon name="star" size={15} /><span>You already own this answer — it’s cited #{a.rank}. Keep it fresh to hold the slot.</span></div>
            )}

            <EngineCard engine={a.engine} phase={showPhase} data={data} animKey={active + '·' + showPhase} />

            {/* action footer */}
            {fx && (
              <div className="ans-action">
                <div className="ans-actbody">
                  <span className="js-tag">Maps to fix</span>
                  <span className="ans-fixname">{fx.label}</span>
                  <span className="lf-deltabig">+{a.lift.toFixed(1)} JiffyScore</span>
                </div>
                <div className="row" style={{ gap: 10 }}>
                  {canSteal && <Btn sm kind="ghost" icon="quote" onClick={() => steal(active)}>Break down why</Btn>}
                  {showPhase === 'now'
                    ? <Btn sm kind="gold" icon="sparkles" onClick={() => setPhase('after')}>Preview the fix</Btn>
                    : <Btn sm kind="gold" icon="sparkles" onClick={() => onShip && onShip([a.fix])}>Add fix to pack</Btn>}
                </div>
              </div>
            )}
          </div>
        </div>
      </div>
    );
  }

  window.AnswerPreview = AnswerPreview;
})();
