/* Questionnaire.jsx — Muna Health screening questionnaire flow controller.
   Renders the clustered screens, dual-phase progress, branching (inline +
   forward-screen), per-section DEV skip, and the Phase-1→Phase-2 transition.
   Exports window.MunaQuestionnaire = { Questionnaire }.
   Depends on: MunaQ (data), MunaComponents (Icon/Button/RadioOption/etc),
   QuestionInputs, MunaFlow.Stage. */

const { SECTIONS, SCREENS, devFillScreen } = window.MunaQ;
const { Stage } = window.MunaFlow;
const DEV_TOOLS = true; /* ⚠ PROTOTYPE ONLY — remove this block + all `DEV_TOOLS &&` usages for production. */

// ─── bare single-line text input (plain text questions) ─────────────────
function TextLine({ value, onChange, placeholder, inputMode, autoComplete }) {
  const [f, setF] = React.useState(false);
  const border = f ? 'var(--amber-500)' : 'var(--border-default)';
  const bw = f ? 2 : 1;
  return (
    <input value={value || ''} placeholder={placeholder} inputMode={inputMode} autoComplete={autoComplete}
      onChange={e => onChange(e.target.value)} onFocus={() => setF(true)} onBlur={() => setF(false)}
      style={{
        width: '100%', boxSizing: 'border-box', border: `${bw}px solid ${border}`,
        borderRadius: 'var(--radius-m)', padding: `${14 - (bw - 1)}px ${15 - (bw - 1)}px`,
        font: 'var(--type-body)', color: 'var(--fg-1)', background: '#fff', outline: 'none',
        boxShadow: f ? 'var(--focus-ring)' : 'var(--shadow-xs)', fontFamily: 'var(--font-sans)',
        transition: 'border-color var(--dur-fast) var(--ease-out), box-shadow var(--dur-fast) var(--ease-out)',
      }}/>
  );
}

// ─── blood-pressure pair ────────────────────────────────────────────────
function BPInput({ value = {}, onChange }) {
  return (
    <div style={{ display: 'flex', alignItems: 'center', gap: 10 }}>
      <NumberInput value={value.sys} onChange={v => onChange({ ...value, sys: v })} placeholder="120" width={92}/>
      <span style={{ font: 'var(--type-display-s)', color: 'var(--fg-4)' }}>/</span>
      <NumberInput value={value.dia} onChange={v => onChange({ ...value, dia: v })} placeholder="80" width={92}/>
      <span style={{ font: 'var(--type-body)', color: 'var(--fg-3)' }}>mmHg</span>
    </div>
  );
}

function renderInput(q, value, set) {
  switch (q.type) {
    case 'single': return <SingleSelect options={q.options} value={value} onChange={set}/>;
    case 'multi': return <MultiSelect options={q.options} value={value || []} exclusive={q.exclusive || []} onChange={set}/>;
    case 'frequency': return <FrequencyScale value={value} onChange={set} labels={q.labels}/>;
    case 'number': return <NumberInput value={value} onChange={set} suffix={q.suffix} placeholder={q.placeholder} width={q.width}/>;
    case 'date': return <DateInput value={value || {}} onChange={set}/>;
    case 'textarea': return <TextArea value={value} onChange={set} placeholder={q.placeholder} rows={q.rows}/>;
    case 'bp': return <BPInput value={value || {}} onChange={set}/>;
    case 'text': default: return <TextLine value={value} onChange={set} placeholder={q.placeholder} inputMode={q.inputMode} autoComplete={q.autoComplete}/>;
  }
}

// ─── Dual-phase progress header ─────────────────────────────────────────
function ProgressHeader({ phase, p1frac, p2frac, p2ticks, sectionLabel }) {
  const inP2 = phase === 2;
  return (
    <div style={{ padding: '12px var(--gutter-screen) 12px', display: 'flex', flexDirection: 'column', gap: 9, background: 'var(--bg)' }}>
      {/* Phase 1 bar — amber; mutes once Phase 1 is complete */}
      <div style={{ height: 4, borderRadius: 2, background: 'var(--stone-200)', overflow: 'hidden' }}>
        <div style={{
          height: '100%', width: (p1frac * 100) + '%', borderRadius: 2,
          background: inP2 ? 'var(--amber-200)' : 'var(--amber-500)',
          transition: 'width var(--dur-base) var(--ease-out), background var(--dur-base) var(--ease-out)',
        }}/>
      </div>
      {/* Phase 2 segmented band — distinct (stone), only in the refinement portion */}
      {inP2 && (
        <div style={{ position: 'relative', height: 4, borderRadius: 2, background: 'var(--stone-200)', overflow: 'hidden' }}>
          <div style={{ height: '100%', width: (p2frac * 100) + '%', background: 'var(--stone-500)', borderRadius: 2, transition: 'width var(--dur-base) var(--ease-out)' }}/>
          {p2ticks.map((t, i) => (
            <div key={i} style={{ position: 'absolute', top: 0, bottom: 0, left: `calc(${t * 100}% - 0.5px)`, width: 1, background: 'var(--bg)' }}/>
          ))}
        </div>
      )}
      <div style={{ display: 'flex', alignItems: 'center', gap: 8 }}>
        {inP2 && <span style={{ font: 'var(--type-overline)', letterSpacing: 'var(--tracking-loose)', textTransform: 'uppercase', color: 'var(--stone-400)' }}>Refining&nbsp;·&nbsp;</span>}
        <span className="overline">{sectionLabel}</span>
      </div>
    </div>
  );
}

// ─── One question block (label + control + inline sub-reveals) ──────────
function QuestionBlock({ q, subs, answers, setAnswer, first }) {
  return (
    <div style={{ marginTop: first ? 0 : 30 }}>
      <QField label={q.label} help={q.help}>
        {renderInput(q, answers[q.id], v => setAnswer(q.id, v))}
      </QField>
      {subs.map(sq => (
        <InlineReveal key={sq.id} open={sq.visible(answers)}>
          <QField label={sq.label} help={sq.help}>
            {renderInput(sq, answers[sq.id], v => setAnswer(sq.id, v))}
          </QField>
        </InlineReveal>
      ))}
    </div>
  );
}

// ─── Phase transition screen ────────────────────────────────────────────
function TransitionScreen({ onContinue, onSkip }) {
  return (
    <div style={{ height: '100%', display: 'flex', flexDirection: 'column', justifyContent: 'center', padding: '0 var(--gutter-screen)' }}>
      <div style={{ width: 60, height: 60, borderRadius: '50%', background: 'var(--sage-50)', color: 'var(--sage-600)', display: 'flex', alignItems: 'center', justifyContent: 'center', marginBottom: 26 }}>
        <Icon name="check" size={30} strokeWidth={2.25}/>
      </div>
      <h2 style={{ font: 'var(--type-display-m)', color: 'var(--fg-1)', letterSpacing: 'var(--tracking-tight)', marginBottom: 14, textWrap: 'pretty' }}>That’s the core of the screening done.</h2>
      <p style={{ font: 'var(--type-body-l)', color: 'var(--fg-2)', textWrap: 'pretty' }}>
        We’ll ask a few more questions to refine your profile, then move to photos. You can stop here if you’d like.
      </p>
    </div>
  );
}

// ─── Privacy / consent screen ───────────────────────────────────────────
function PrivacyScreen() {
  return (
    <div style={{ padding: '6px var(--gutter-screen) 0' }}>
      <h2 style={{ font: 'var(--type-display-s)', color: 'var(--fg-1)', letterSpacing: 'var(--tracking-snug)', marginBottom: 18 }}>Before we read your screening</h2>
      <div style={{ display: 'flex', flexDirection: 'column', gap: 16 }}>
        <div style={{ display: 'flex', gap: 12 }}>
          <div style={{ flexShrink: 0, color: 'var(--amber-600)', marginTop: 1 }}><Icon name="lock" size={20}/></div>
          <p style={{ font: 'var(--type-body)', color: 'var(--fg-2)', textWrap: 'pretty' }}>
            Everything you’ve shared is confidential and used only for your health assessment and care.
          </p>
        </div>
        <div style={{ display: 'flex', gap: 12 }}>
          <div style={{ flexShrink: 0, color: 'var(--amber-600)', marginTop: 1 }}><Icon name="shield" size={20}/></div>
          <p style={{ font: 'var(--type-body)', color: 'var(--fg-2)', textWrap: 'pretty' }}>
            Your data is protected under Nigerian data protection law and HIPAA guidelines.
          </p>
        </div>
        <p style={{ font: 'var(--type-body)', color: 'var(--fg-3)', textWrap: 'pretty', marginTop: 2 }}>
          By submitting, you agree to let Muna use this information to give you personalised recommendations and coordinate your care.
        </p>
      </div>
    </div>
  );
}

// ─── Main controller ────────────────────────────────────────────────────
function Questionnaire({ answers, setAnswers, onComplete, onExit, onDevSkip, startSectionId }) {
  const [idx, setIdx] = React.useState(() => {
    if (!startSectionId) return 0;
    const vis = SCREENS.filter(s => !s.visible || s.visible(answers));
    const p1 = vis.filter(s => SECTIONS[s.section].phase === 1);
    const p2 = vis.filter(s => SECTIONS[s.section].phase === 2);
    const ordered = [...p1.map(s => s.section), '__transition__', ...p2.map(s => s.section)];
    const i = ordered.indexOf(startSectionId);
    return i >= 0 ? i : 0;
  });
  const [dir, setDir] = React.useState(1);
  // Off-screen unanswered guidance (system pattern for any pinned-CTA + overflow screen)
  const [below, setBelow] = React.useState({ count: 0, firstId: null });
  const [highlightId, setHighlightId] = React.useState(null);
  const [pulse, setPulse] = React.useState(false);
  const scrollRef = React.useRef(null);
  const hlTimer = React.useRef(null);
  const pulseTimer = React.useRef(null);

  const setAnswer = (id, value) => {
    setAnswers(prev => {
      const next = { ...prev, [id]: value };
      if (id === '1.2' && value && /^\d{4}$/.test(value.y || '')) {
        const age = 2026 - Number(value.y);
        if (age > 0 && age < 130) next['1.3'] = String(age);
      }
      return next;
    });
  };

  // Build the live sequence from current answers (branching = forward screens)
  const seq = React.useMemo(() => {
    const vis = SCREENS.filter(s => !s.visible || s.visible(answers));
    const p1 = vis.filter(s => SECTIONS[s.section].phase === 1).map(screen => ({ kind: 'q', screen, phase: 1 }));
    const p2 = vis.filter(s => SECTIONS[s.section].phase === 2).map(screen => ({ kind: 'q', screen, phase: 2 }));
    return [...p1, { kind: 'transition', phase: 1 }, ...p2, { kind: 'privacy', phase: 2 }];
  }, [answers]);

  const clampedIdx = Math.min(idx, seq.length - 1);
  const cur = seq[clampedIdx];

  // progress
  const p1qs = seq.filter(s => s.kind === 'q' && s.phase === 1);
  const p2qs = seq.filter(s => s.kind === 'q' && s.phase === 2);
  const passedP1 = seq.slice(0, clampedIdx + 1).filter(s => s.kind === 'q' && s.phase === 1).length;
  const passedP2 = seq.slice(0, clampedIdx + 1).filter(s => s.kind === 'q' && s.phase === 2).length;
  const p1frac = cur.phase === 2 || cur.kind === 'transition' ? 1 : (p1qs.length ? passedP1 / p1qs.length : 1);
  const p2frac = cur.phase === 2 ? (p2qs.length ? passedP2 / p2qs.length : 1) : 0;
  // section ticks for the phase-2 segmented band
  const p2ticks = (() => {
    if (!p2qs.length) return [];
    const ticks = []; let seen = 0; let lastSection = null;
    p2qs.forEach((it, i) => { if (it.screen.section !== lastSection) { if (i !== 0) ticks.push(i / p2qs.length); lastSection = it.screen.section; } });
    return ticks;
  })();

  const sectionLabel = cur.kind === 'q' ? SECTIONS[cur.screen.section].label
    : cur.kind === 'privacy' ? 'REVIEW & CONSENT' : 'SCREENING COMPLETE';

  const go = (nextIdx) => { setDir(nextIdx >= clampedIdx ? 1 : -1); setIdx(nextIdx); };
  const next = () => { if (clampedIdx < seq.length - 1) go(clampedIdx + 1); else onComplete(); };
  const back = () => { if (clampedIdx > 0) go(clampedIdx - 1); else onExit && onExit(); };

  // Continue gating: every visible single / frequency question must be answered
  const screenComplete = (() => {
    if (cur.kind !== 'q') return true;
    return cur.screen.questions.every(q => {
      const shown = !q.visible || q.visible(answers);
      if (!shown) return true;
      if (q.type === 'single' || q.type === 'frequency') return answers[q.id] != null && answers[q.id] !== '';
      return true;
    });
  })();

  const devSkip = () => {
    if (cur.kind !== 'q') return;
    // DEV · skip opens the router-owned Demo-mode persona sheet on every screen;
    // picking a persona jumps straight to their outcome (no per-screen fill/advance).
    if (onDevSkip) onDevSkip();
  };

  // ── Off-screen unanswered guidance ──────────────────────────────────
  // List required (single / frequency) questions still unanswered on this screen.
  const requiredUnanswered = () => {
    if (cur.kind !== 'q') return [];
    return cur.screen.questions.filter(q => {
      const shown = !q.visible || q.visible(answers);
      if (!shown) return false;
      if (q.type === 'single' || q.type === 'frequency') return answers[q.id] == null || answers[q.id] === '';
      return false;
    }).map(q => q.id);
  };
  // How many of those sit below the current scroll fold.
  const computeBelow = () => {
    const sc = scrollRef.current;
    if (!sc || cur.kind !== 'q') return { count: 0, firstId: null };
    const ids = requiredUnanswered();
    if (!ids.length) return { count: 0, firstId: null };
    const fold = sc.scrollTop + sc.clientHeight - 40;
    let count = 0, firstId = null;
    ids.forEach(id => {
      const el = sc.querySelector('[data-q="' + id + '"]');
      if (el && el.offsetTop > fold) { count++; if (!firstId) firstId = id; }
    });
    return { count, firstId };
  };
  React.useEffect(() => {
    const raf = requestAnimationFrame(() => setBelow(computeBelow()));
    const t = setTimeout(() => setBelow(computeBelow()), 320); // after slide + inline-reveal settle
    return () => { cancelAnimationFrame(raf); clearTimeout(t); };
  }, [clampedIdx, answers]);
  const onBodyScroll = () => setBelow(computeBelow());
  // Calm correction: scroll to the first unanswered question, ring it, bump the indicator.
  const guide = () => {
    const ids = requiredUnanswered();
    if (!ids.length) return;
    const targetId = ids[0];
    const sc = scrollRef.current;
    const el = sc && sc.querySelector('[data-q="' + targetId + '"]');
    if (sc && el) sc.scrollTo({ top: Math.max(0, el.offsetTop - 16), behavior: 'smooth' });
    setHighlightId(targetId);
    if (hlTimer.current) clearTimeout(hlTimer.current);
    hlTimer.current = setTimeout(() => setHighlightId(null), 1500);
    setPulse(true);
    if (pulseTimer.current) clearTimeout(pulseTimer.current);
    pulseTimer.current = setTimeout(() => setPulse(false), 650);
  };
  React.useEffect(() => () => { if (hlTimer.current) clearTimeout(hlTimer.current); if (pulseTimer.current) clearTimeout(pulseTimer.current); }, []);

  // ── body renderer (by sequence index, for slide transitions) ──
  // Each screen owns its OWN scroll container so content can scroll fully past
  // the pinned CTA (Stage clips, so a shared outer scroll wouldn't grow).
  const renderItem = (i) => {
    const isActive = i === clampedIdx;
    const item = seq[Math.min(i, seq.length - 1)];
    let body;
    if (item.kind === 'transition') body = <TransitionScreen/>;
    else if (item.kind === 'privacy') body = <PrivacyScreen/>;
    else {
      const s = item.screen;
      const sec = SECTIONS[s.section];
      // Clearance = CTA height + 16pt gap + bottom safe area (+ room for the indicator when shown)
      const clearance = 120 + (isActive && below.count > 0 ? 44 : 0);
      body = (
        <div style={{ padding: '4px var(--gutter-screen) 0', paddingBottom: clearance }}>
          {s.sectionStart && sec.phase === 2 && (
            <div style={{ marginBottom: 22 }}>
              <div className="overline" style={{ color: 'var(--amber-600)' }}>About to ask · {sec.about}</div>
              <p style={{ font: 'var(--type-body)', color: 'var(--fg-2)', marginTop: 8, textWrap: 'pretty' }}>{sec.why}</p>
            </div>
          )}
          {s.sectionStart && sec.phase === 1 && (
            <p style={{ font: 'var(--type-body)', color: 'var(--fg-3)', marginBottom: 20, textWrap: 'pretty' }}>{sec.intro}</p>
          )}
          <h2 style={{ font: 'var(--type-display-s)', color: 'var(--fg-1)', letterSpacing: 'var(--tracking-snug)', marginBottom: s.subtitle ? 6 : 22, textWrap: 'pretty' }}>{s.title}</h2>
          {s.subtitle && <p style={{ font: 'var(--type-body-s)', color: 'var(--fg-3)', marginBottom: 22 }}>{s.subtitle}</p>}
          {s.questions.map((q, qi) => {
            const shown = !q.visible || q.visible(answers);
            const hl = highlightId === q.id;
            const block = (
              <div data-q={q.id} style={{
                borderRadius: 'var(--radius-m)',
                boxShadow: hl ? 'var(--focus-ring)' : 'none',
                transition: 'box-shadow var(--dur-base) var(--ease-out)',
              }}>
                <QField label={q.label} help={q.help}>
                  {renderInput(q, answers[q.id], v => setAnswer(q.id, v))}
                </QField>
              </div>
            );
            if (q.visible) return <InlineReveal key={q.id} open={shown}>{block}</InlineReveal>;
            return <div key={q.id} style={{ marginTop: qi === 0 ? 0 : 30 }}>{block}</div>;
          })}
        </div>
      );
    }
    return (
      <div ref={isActive ? scrollRef : null} onScroll={isActive ? onBodyScroll : undefined}
        style={{ position: 'relative', height: '100%', overflowY: 'auto', WebkitOverflowScrolling: 'touch' }}>
        {body}
      </div>
    );
  };

  const isTransition = cur.kind === 'transition';
  const ctaLabel = cur.kind === 'privacy' ? 'Continue to photos' : 'Continue';

  return (
    <div style={{ position: 'absolute', inset: 0, background: 'var(--bg)', display: 'flex', flexDirection: 'column' }}>
      {/* Nav: back + DEV skip */}
      <div style={{ height: 40, flexShrink: 0, display: 'flex', alignItems: 'center', justifyContent: 'space-between', paddingLeft: 8, paddingRight: 8, paddingTop: 52 }}>
        <button onClick={back} aria-label="Back" style={{ background: 'transparent', border: 0, cursor: 'pointer', color: 'var(--fg-1)', width: 40, height: 40, display: 'flex', alignItems: 'center', justifyContent: 'center' }}>
          <Icon name="chevron-left" size={26}/>
        </button>
        {DEV_TOOLS && cur.kind === 'q' && (
          <button onClick={devSkip} style={{
            background: 'var(--stone-100)', border: '1px dashed var(--stone-400)', borderRadius: 'var(--radius-pill)',
            cursor: 'pointer', color: 'var(--stone-500)', padding: '6px 12px', marginRight: 8,
            font: 'var(--type-overline)', letterSpacing: 'var(--tracking-loose)', textTransform: 'uppercase', whiteSpace: 'nowrap',
          }}>DEV · skip</button>
        )}
      </div>

      {/* Progress */}
      <ProgressHeader phase={cur.phase} p1frac={p1frac} p2frac={p2frac} p2ticks={p2ticks} sectionLabel={sectionLabel}/>

      {/* Sliding body — each screen owns its own scroll (see renderItem) */}
      <div style={{ flex: 1, position: 'relative', overflow: 'hidden' }}>
        <Stage activeKey={String(clampedIdx)} direction={dir} render={(k) => renderItem(Number(k))}/>
      </div>

      {/* Footer */}
      <div style={{ flexShrink: 0, padding: '12px var(--gutter-screen) 38px', display: 'flex', flexDirection: 'column', gap: 10, alignItems: 'center', background: 'linear-gradient(180deg, rgba(250,248,245,0) 0%, var(--bg) 26%)' }}>
        {!screenComplete && cur.kind === 'q' && below.count > 0 && (
          <button onClick={guide} style={{
            display: 'flex', alignItems: 'center', gap: 7, cursor: 'pointer',
            background: '#fff', border: '1px solid var(--border-default)', borderRadius: 'var(--radius-pill)',
            padding: '7px 14px 7px 12px', color: 'var(--fg-2)', font: 'var(--type-label)', whiteSpace: 'nowrap',
            boxShadow: 'var(--shadow-xs)', animation: pulse ? 'mh-bump 0.6s var(--ease-out)' : 'none',
          }}>
            <Icon name="chevron-down" size={16}/>
            {below.count} more question{below.count > 1 ? 's' : ''} below
          </button>
        )}
        <Button full variant="primary" disabled={!screenComplete} glow={cur.kind === 'privacy'} onClick={next} onDisabledClick={guide}>{ctaLabel}</Button>
        {isTransition && (
          <button onClick={onComplete} style={{ background: 'none', border: 0, cursor: 'pointer', font: 'var(--type-button)', color: 'var(--fg-2)', padding: '4px 8px' }}>
            Skip the rest, go to photos
          </button>
        )}
      </div>
    </div>
  );
}

window.MunaQuestionnaire = { Questionnaire };
