/* cst-conversation.jsx — the shared "strategist session" engine.
   One prompt at a time, reflects understanding, occasionally pushes back.
   Used by every tool. Exported to window as ConversationFlow. */

const { useState: _cuS, useEffect: _cuE, useRef: _cuR } = React;
const __C = window.CST;
const { FONT: _F, TEXT: _T, HAZE: _H, HAZE_DIM: _HD, HAIR: _HR, GLASS: _G, GLASS_HI: _GH, INK: _I } = __C;

// resolve a value-or-function prop against the current answers
const _resolve = (v, ans) => (typeof v === 'function' ? v(ans) : v);

// a confirmed prior answer, shown in the compact memory strip
function MemoryChip({ text, color }) {
  return (
    <div style={{
      display: 'flex', gap: 7, alignItems: 'baseline', padding: '5px 0',
      borderBottom: `1px solid ${_HR}`,
    }}>
      <span style={{ color, fontSize: 11, lineHeight: 1.3, flexShrink: 0 }}>✓</span>
      <span style={{
        fontFamily: _F, fontSize: 11.5, color: _H, lineHeight: 1.4,
        overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap',
      }}>{text}</span>
    </div>);
}

function AdvisorLine({ color, children }) {
  return (
    <div style={{ display: 'flex', gap: 9, alignItems: 'flex-start' }}>
      <span style={{ width: 8, height: 8, borderRadius: 99, background: color, marginTop: 7, flexShrink: 0, boxShadow: `0 0 10px ${color}` }} />
      <div style={{ flex: 1 }}>{children}</div>
    </div>);
}

function ConversationFlow({ steps, accent, onComplete, onStep, eyebrow, advisorName = 'ADVISOR', examplesFor, examplesLoading, prefill }) {
  const c0 = accent[0];
  const [idx, setIdx] = _cuS(0);
  const [answers, setAnswers] = _cuS({});
  const [draft, setDraft] = _cuS(() => (prefill && prefill[steps[0].id]) || '');
  const [phase, setPhase] = _cuS('ask');        // ask | reflect | pushback
  const [reflectText, setReflectText] = _cuS('');
  const [pushText, setPushText] = _cuS('');
  const [revealing, setRevealing] = _cuS(false); // typing beat before reflection text
  const timers = _cuR([]);
  const memRef = _cuR(null);

  const step = steps[idx];
  const _skip = (s, ans) => !!(s && s.skipIf && s.skipIf(ans));
  const nextVisible = (from, ans) => { let j = from; while (j < steps.length && _skip(steps[j], ans)) j++; return j; };
  const last = nextVisible(idx + 1, answers) >= steps.length;
  // visible-step bookkeeping for the counter/dots (excludes skipped steps)
  const visibleSteps = steps.filter((s) => !_skip(s, answers));
  const visTotal = visibleSteps.length;
  const visIdx = steps.slice(0, idx + 1).filter((s) => !_skip(s, answers)).length - 1;

  _cuE(() => { onStep && onStep(idx, answers); }, [idx]);
  _cuE(() => () => timers.current.forEach(clearTimeout), []);
  _cuE(() => { if (memRef.current) memRef.current.scrollTop = memRef.current.scrollHeight; }, [idx, phase]);

  const advance = (ans) => {
    const j = nextVisible(idx + 1, ans);
    if (j >= steps.length) { onComplete && onComplete(ans); return; }
    const nextStep = steps[j];
    setIdx(j);
    setDraft((prefill && nextStep && prefill[nextStep.id]) || '');
    setPhase('ask');
    setReflectText(''); setPushText('');
  };

  const commit = (value, displayLabel) => {
    const v = value != null ? value : draft;
    if (typeof v === 'string' && !v.trim() && !step.optional) return;
    const nextAns = { ...answers, [step.id]: v, [step.id + '__label']: displayLabel || (typeof v === 'string' ? v : String(v)) };
    setAnswers(nextAns);

    const reflection = step.reflect ? step.reflect(v, nextAns) : '';
    const pushback = step.pushback ? step.pushback(v, nextAns) : null;

    if (reflection || pushback) {
      setPhase('reflect'); setRevealing(true); setReflectText(reflection || '');
      timers.current.push(setTimeout(() => setRevealing(false), 680));
      if (pushback) {
        timers.current.push(setTimeout(() => { setPushText(pushback); setPhase('pushback'); }, reflection ? 1500 : 700));
      } else {
        timers.current.push(setTimeout(() => advance(nextAns), 1400));
      }
    } else {
      advance(nextAns);
    }
  };

  // ----- render the input for the current step -----
  const renderInput = () => {
    if (step.kind === 'choice') {
      return (
        <div style={{ display: 'flex', flexDirection: 'column', gap: 8 }}>
          {step.choices.map((ch, i) => (
            <ChoiceCard key={ch.value} label={ch.label} sub={ch.desc} glyph={ch.glyph}
              accent={accent[i % accent.length]} onPick={() => commit(ch.value, ch.label)} />
          ))}
        </div>);
    }
    if (step.kind === 'number') {
      const _prefix = _resolve(step.prefix, answers);
      const _unit = _resolve(step.unit, answers);
      const _ph = _resolve(step.placeholder, answers);
      return (
        <div style={{ display: 'flex', flexDirection: 'column', gap: 12 }}>
          <div style={{ display: 'flex', alignItems: 'center', gap: 10, borderBottom: `2px solid ${_HR}`, paddingBottom: 8 }}>
            {_prefix && <span style={{ fontFamily: _F, fontSize: 30, fontWeight: 700, color: _HD }}>{_prefix}</span>}
            <input type="number" value={draft} autoFocus inputMode="decimal"
              onChange={(e) => setDraft(e.target.value)}
              onKeyDown={(e) => { if (e.key === 'Enter') commit(); }}
              placeholder={_ph || '0'}
              style={{
                flex: 1, minWidth: 0, background: 'transparent', border: 'none', outline: 'none',
                color: _T, fontFamily: _F, fontWeight: 700, fontSize: 30, letterSpacing: -0.5, padding: 0,
              }} />
            {_unit && <span style={{ fontFamily: _F, fontSize: 14, fontWeight: 600, color: _H }}>{_unit}</span>}
          </div>
          <PrimaryBtn accent={c0} disabled={!String(draft).trim() && !step.optional} onClick={() => commit()}>
            {step.optional && !String(draft).trim() ? 'Skip →' : (last ? 'See the read →' : 'Continue →')}
          </PrimaryBtn>
        </div>);
    }
    // default: free text
    return (
      <div style={{ display: 'flex', flexDirection: 'column', gap: 10 }}>
        <textarea className="cst-idea-input" value={draft} autoFocus
          onChange={(e) => setDraft(e.target.value)}
          placeholder={step.placeholder || 'Type your answer…'}
          style={{
            width: '100%', boxSizing: 'border-box', resize: 'none', userSelect: 'text', minHeight: 84,
            background: _G, border: `1px solid ${_HR}`, borderRadius: 12, outline: 'none',
            color: _T, fontFamily: _F, fontWeight: 600, fontSize: 16, lineHeight: 1.4, padding: 12,
          }} />
        {(() => {
          const dyn = examplesFor && examplesFor[step.id];
          const ex = dyn || step.examples;
          const loading = examplesLoading && examplesLoading[step.id];
          if (loading && !dyn) {
            return (
              <div style={{ display: 'flex', alignItems: 'center', gap: 8 }}>
                <TypingDots color={c0} />
                <span style={{ fontFamily: _F, fontSize: 11, color: _HD, letterSpacing: 0.5 }}>Reading your business…</span>
              </div>);
          }
          if (!ex) return null;
          return (
            <div style={{ display: 'flex', flexWrap: 'wrap', gap: 7, alignItems: 'center' }}>
              <span style={{ fontFamily: _F, fontSize: 10, color: _HD, letterSpacing: 1 }}>{dyn ? 'COMMON FOR YOU:' : 'TRY:'}</span>
              {ex.map((x) => (
                <button key={x} onClick={() => setDraft(x)} style={{
                  cursor: 'pointer', padding: '6px 10px', borderRadius: 9, fontFamily: _F, fontSize: 11,
                  color: dyn ? _T : _H, background: dyn ? c0 + '14' : _G, border: `1px solid ${dyn ? c0 + '55' : _HR}`,
                }}>{x.length > 32 ? x.slice(0, 30) + '…' : x}</button>
              ))}
            </div>);
        })()}
        <PrimaryBtn accent={c0} disabled={!draft.trim() && !step.optional} onClick={() => commit()}>
          {last ? 'See the read →' : (draft.trim() || step.optional ? 'Continue →' : 'Type an answer to continue')}
        </PrimaryBtn>
      </div>);
  };

  const priorChips = steps.slice(0, idx)
    .map((s) => ({ s, label: answers[s.id + '__label'] }))
    .filter((x) => x.label);

  return (
    <div style={{ position: 'relative', height: '100%', display: 'flex', flexDirection: 'column', padding: '0 22px 26px', gap: 12 }}>
      <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between' }}>
        <Eyebrow color={c0}>{eyebrow}</Eyebrow>
        <span style={{ fontFamily: _F, fontSize: 10.5, color: _HD, letterSpacing: 1 }}>{visIdx + 1} / {visTotal}</span>
      </div>

      {/* memory strip — prior confirmed answers */}
      {priorChips.length > 0 && (
        <div ref={memRef} className="cst-scroll" style={{ maxHeight: 92, overflowY: 'auto', flexShrink: 0 }}>
          {priorChips.map(({ s, label }) => <MemoryChip key={s.id} text={label} color={c0} />)}
        </div>
      )}

      {/* advisor prompt + reflection/pushback */}
      <div style={{ flex: 1, minHeight: 0, display: 'flex', flexDirection: 'column', justifyContent: 'flex-end', gap: 14 }}>
        <AdvisorLine color={c0}>
          <div style={{ fontFamily: _F, fontSize: 9.5, letterSpacing: 2, color: _HD, marginBottom: 6 }}>{advisorName}</div>
          <div style={{ fontFamily: _F, fontWeight: 700, fontSize: 19.5, lineHeight: 1.25, letterSpacing: -0.4, color: _T }}>
            {_resolve(step.prompt, answers)}
          </div>
          {step.hint && phase === 'ask' && (
            <div style={{ fontFamily: _F, fontSize: 12, color: _H, lineHeight: 1.45, marginTop: 8 }}>{_resolve(step.hint, answers)}</div>
          )}
          {(phase === 'reflect' || phase === 'pushback') && (
            <div style={{ marginTop: 12, paddingLeft: 12, borderLeft: `2px solid ${c0}55` }}>
              {revealing
                ? <TypingDots color={c0} />
                : <div style={{ fontFamily: _F, fontSize: 13, lineHeight: 1.5, color: 'rgba(236,237,241,0.82)' }}>{reflectText}</div>}
              {phase === 'pushback' && !revealing && (
                <div style={{ fontFamily: _F, fontSize: 13.5, lineHeight: 1.5, color: _T, fontWeight: 600, marginTop: 8 }}>{pushText}</div>
              )}
            </div>
          )}
        </AdvisorLine>

        {/* input dock OR pushback choice */}
        {phase === 'ask' && <div>{renderInput()}</div>}
        {phase === 'pushback' && !revealing && (
          <div style={{ display: 'flex', gap: 9 }}>
            <button onClick={() => { setPhase('ask'); setDraft(typeof answers[step.id] === 'string' ? answers[step.id] : ''); }}
              style={{ flex: 1, cursor: 'pointer', padding: '12px', borderRadius: 11, fontFamily: _F, fontWeight: 600, fontSize: 12.5, color: _H, background: 'transparent', border: `1px solid ${_HR}` }}>
              Let me reconsider
            </button>
            <button onClick={() => advance(answers)}
              style={{ flex: 1, cursor: 'pointer', padding: '12px', borderRadius: 11, fontFamily: _F, fontWeight: 700, fontSize: 12.5, color: _I, background: c0, border: 'none', boxShadow: `0 6px 18px -8px ${c0}` }}>
              I'll stand by it →
            </button>
          </div>
        )}
      </div>

      <Dots index={visIdx} total={visTotal} accent={c0} />
    </div>);
}

window.ConversationFlow = ConversationFlow;
