// app.jsx — Branching funnel state machine (v2, peptide-first).
// The flow is computed from answers (buildFlow) so each goal injects its own
// deep-dive block and conditional screens appear/disappear. Navigation is by
// screen id (not a fixed index) so insertion never desyncs the position.
const { useState: appS, useEffect: appE, useRef: appR } = React;

// Branch deep-dive blocks, keyed by primary goal.
const GOAL_BLOCKS = {
  fat_loss:   ['fl_bodytype','fl_bodyfat','fl_storage','fl_appetite','fl_glp1','fl_target'],
  muscle:     ['mu_training','mu_bodytype','mu_target','mu_recovery','mu_priority'],
  recover:    ['re_painmap','re_duration','re_cause','re_priortx','re_limiting'],
  aesthetics: ['ae_skin','ae_hair','ae_sun','ae_routine','ae_bioage'],
  mind:       ['mi_focus','mi_fog','mi_mood','mi_memory','mi_sleeponset'],
  vitality:   ['vi_crash','vi_libido','vi_morning'],
  unsure:     [],
};

// Screens that only appear under certain answers.
const NEEDS_BODY = ['fat_loss','muscle','aesthetics']; // height/weight relevant

function buildFlow(state) {
  const goal = state.goal;
  const ids = [];
  const push = (...x) => ids.push(...x);

  // 1 — Hook & trust
  push('landing', 'edu_peptides', 'source');
  // 2 — Goal & ambition
  push('goal');
  if (goal) push('subgoals', 'readiness');
  // 3 — About you
  if (goal) {
    push('sex', 'age');
    if (NEEDS_BODY.includes(goal)) push('height', 'weight');
    // 4 — Goal deep-dive
    push(...(GOAL_BLOCKS[goal] || []));
    // 5 — Lifestyle
    push('sleep', 'energy', 'stress', 'activity', 'diet', 'alcohol', 'caffeine', 'nicotine');
    // 6 — Medical & readiness
    push('doctor_intro', 'peptide_history', 'injection_comfort', 'delivery_pref', 'meds', 'conditions');
    if (state.sex === 'female') push('pregnancy');
    push('supplements');
    // 7 — Commitment & projection
    push('halfway', 'timeline', 'budget', 'projection');
    // 8 — Lead capture
    push('name', 'dob', 'email', 'phone');
    // 9 — Reveal & convert
    push('loading', 'result', 'education', 'cta');
  }

  // id → screen config. Counted screens drive the progress bar.
  const NO_COUNT = new Set(['landing','edu_peptides','doctor_intro','halfway','projection','loading','result','education','cta']);
  const NO_BACK = new Set(['landing','loading','result']);
  return ids.map(id => ({
    id,
    Comp: window['SCREEN_' + id],
    count: !NO_COUNT.has(id),
    back: !NO_BACK.has(id),
  }));
}

const TWEAK_DEFAULTS = /*EDITMODE-BEGIN*/{
  "accent": "#E8B5A8",
  "scheme": "light"
}/*EDITMODE-END*/;

const ACCENT_SWATCHES = ['#E8B5A8','#C68B7C','#E8C76B','#6FD8FF','#FF4A1C','#0A0A0A'];

function accentSet(hex) {
  const n = hex.replace('#','');
  const r = parseInt(n.slice(0,2),16), g = parseInt(n.slice(2,4),16), b = parseInt(n.slice(4,6),16);
  return { soft: `rgba(${r}, ${g}, ${b}, 0.16)`, glow: `rgba(${r}, ${g}, ${b}, 0.45)` };
}

function App() {
  const [curId, setCurId] = appS('landing');
  const [state, setState] = appS({});
  const [t, setT] = appS(TWEAK_DEFAULTS);

  // Refs so set()+next() in the same handler see the latest values synchronously.
  const stateRef = appR(state); stateRef.current = state;
  const curRef = appR(curId); curRef.current = curId;

  const setTweak = (k, v) => {
    const edits = typeof k === 'object' ? k : { [k]: v };
    setT(prev => ({ ...prev, ...edits }));
    window.parent.postMessage({ type: '__edit_mode_set_keys', edits }, '*');
  };

  appE(() => {
    const a = accentSet(t.accent);
    const r = document.documentElement.style;
    r.setProperty('--accent', t.accent);
    r.setProperty('--accent-soft', a.soft);
    r.setProperty('--accent-glow', a.glow);
  }, [t.accent]);

  const set = (k, v) => {
    const ns = { ...stateRef.current, [k]: v };
    stateRef.current = ns;
    setState(ns);
  };
  const scrollTop = () => requestAnimationFrame(() => window.scrollTo({ top: 0, behavior: 'smooth' }));
  const goTo = (id) => { curRef.current = id; setCurId(id); scrollTop(); };
  const next = () => {
    const flow = buildFlow(stateRef.current);
    const i = Math.max(0, flow.findIndex(f => f.id === curRef.current));
    goTo(flow[Math.min(flow.length - 1, i + 1)].id);
  };
  const back = () => {
    const flow = buildFlow(stateRef.current);
    const i = Math.max(0, flow.findIndex(f => f.id === curRef.current));
    goTo(flow[Math.max(0, i - 1)].id);
  };

  const flow = buildFlow(state);
  let idx = flow.findIndex(f => f.id === curId);
  if (idx < 0) idx = 0;
  const cur = flow[idx];
  const counted = flow.filter(f => f.count);
  const total = counted.length;
  const step = flow.slice(0, idx + 1).filter(f => f.count).length;
  const showHeader = cur.id !== 'loading';
  const canBack = cur.back !== false && idx > 0;
  // Hide the numeric progress until a goal is chosen — the flow expands then,
  // so an early "1/2" would look misleadingly near-complete.
  const showProgress = cur.count && !!state.goal;

  return (
    <>
      <div className="sp-app" data-screen-label={cur.id}>
        {showHeader && (
          <SPHeader step={showProgress ? step : 0} total={showProgress ? total : 0} onBack={back} canBack={canBack} />
        )}
        <main className="sp-main">
          {cur.Comp
            ? <cur.Comp state={state} set={set} next={next} back={back} t={t} />
            : <div className="sp-screen-inner"><p className="sp-sub">Missing screen: {cur.id}</p></div>}
        </main>
      </div>

      <TweaksPanel title="Tweaks">
        <TweakSection label="Accent color" />
        <TweakColor label="Brand" value={t.accent} options={ACCENT_SWATCHES} onChange={(v) => setTweak('accent', v)} />
        <TweakSection label="Navigation" />
        <TweakSelect label="Jump to" value={cur.id}
          options={flow.map(f => ({ value: f.id, label: f.id }))}
          onChange={(v) => goTo(v)} />
      </TweaksPanel>
    </>
  );
}

window.SuperstarApp = App;
