// Survey — full multi-step working flow with multiple question types
//
// Conditional follow-ups: any 'I' (yes/no) question can carry a `followups`
// array of sub-questions. When the user picks "Yes" they slide down inline;
// the parent question can't advance until they're answered. This is how the
// AI gets real material instead of a useless bare "Yes".
const SURVEY_QUESTIONS = [
  // Section 1 — Basics
  { id: 1, sec: 1, type: 'A', q: "Let's start easy — what's your name?", hint: "First and last is fine.", placeholder: "e.g. Jane Smith", why: "We use this in the resume header and any auto-saved filename." },
  { id: 2, sec: 1, type: 'A', q: "What's the best email for callbacks?", placeholder: "you@email.com", why: "This appears at the top of your resume." },
  { id: 3, sec: 1, type: 'A', q: "Phone number?", hint: "Optional, but most recruiters still call.", placeholder: "+1 (415) 555-0142", optional: true },
  { id: 4, sec: 1, type: 'A', q: "Where are you based?", placeholder: "San Francisco, CA", hint: "City + state/region is plenty.", why: "Recruiters filter by location even for remote roles. Be specific." },
  { id: 5, sec: 1, type: 'I', q: "Want to include LinkedIn?", hint: "Optional, but recommended.", followups: [
      { id: '5a', type: 'A', q: "LinkedIn URL", placeholder: "linkedin.com/in/your-handle" },
  ] },
  { id: 6, sec: 1, type: 'I', q: "Do you have a portfolio or personal site?", followups: [
      { id: '6a', type: 'A', q: "Link", placeholder: "your-name.design" },
  ] },
  { id: 6.5, sec: 1, type: 'I', q: "Authorized to work in the country you're applying to?", hint: "Affects whether we add a “Work Authorization” note.", followups: [
      { id: '6.5a', type: 'C', q: "Status to mention on the resume", options: [
          { label: "US Citizen", desc: "Or naturalized" },
          { label: "Green card holder", desc: "Permanent resident" },
          { label: "Work visa", desc: "We'll add “Visa sponsorship not required”" },
          { label: "Need sponsorship", desc: "We'll add “Open to sponsorship”" },
      ] },
  ] },

  // Section 2 — Target
  { id: 7, sec: 2, type: 'J', q: "What role are you aiming for?", hint: "Pick from the list or type your own — recruiters search by these exact phrases.", suggestions: ['Senior Product Designer', 'Product Designer', 'UX Designer', 'Design Lead', 'Staff Designer', 'Design Director'] },
  { id: 8, sec: 2, type: 'E', q: "How many years in this kind of work?", min: 0, max: 25, step: 1, why: "Helps us match phrasing to seniority. We never put a literal “years” count on the resume." },
  { id: 9, sec: 2, type: 'D', q: "Which industries interest you?", options: ['Fintech', 'Healthtech', 'AI / ML', 'Consumer social', 'Marketplaces', 'Climate tech', 'Developer tools', 'E-commerce', 'Edtech', 'Productivity', 'Gaming', 'Hardware'] },
  { id: 9.5, sec: 2, type: 'C', q: "Where are you applying, mostly?", options: [
      { label: "On-site", desc: "In-office or hybrid" },
      { label: "Remote", desc: "Distributed teams" },
      { label: "Open to either", desc: "Don't filter for me" },
  ] },
  { id: 9.7, sec: 2, type: 'I', q: "Open to relocation?", followups: [
      { id: '9.7a', type: 'D', q: "Where to?", options: ['NYC', 'San Francisco', 'Seattle', 'Austin', 'London', 'Berlin', 'Toronto', 'Anywhere'] },
  ] },

  // Section 3 — Story
  { id: 10, sec: 3, type: 'B', q: "In a couple sentences, who are you professionally?", hint: "Don't worry about phrasing. Tell us in your own words. We'll tighten it.", placeholder: "I'm a senior designer who…", why: "This becomes your summary. AI will polish — your voice survives." },
  { id: 10.5, sec: 3, type: 'B', q: "If a peer recommended you, what would they say you're best at?", hint: "One or two specific things. Be honest, not modest.", placeholder: "She turns vague PM briefs into shipped UI…", why: "This shapes which bullets we highlight." },

  // Section 4 — Experience repeater
  { id: 11, sec: 4, type: 'G', q: "Let's talk about your work experience.", hint: "Add any roles you've had. No work history yet? That's fine — just continue.", optional: true },

  // Section 5 — Education
  { id: 12, sec: 5, type: 'C', q: "What's your highest level of education?", options: [
      { label: "High school / GED", desc: "Diploma or equivalent" },
      { label: "Associate", desc: "Community college, 2-year program" },
      { label: "Bachelor's", desc: "BA, BS, BFA…" },
      { label: "Master's", desc: "MA, MS, MFA, MBA…" },
      { label: "Doctorate", desc: "PhD, MD, JD…" },
      { label: "Bootcamp / Certificate", desc: "General Assembly, Lambda, etc." },
  ] },
  { id: 12.5, sec: 5, type: 'I', q: "Want to include GPA?", hint: "Usually only worth it if it's 3.5+ and you graduated within the last 3 years.", followups: [
      { id: '12.5a', type: 'A', q: "GPA", placeholder: "3.8 / 4.0" },
  ] },

  // Section 6 — Skills
  { id: 13, sec: 6, type: 'D', q: "Pick your technical / hard skills.", hint: "We suggested some based on “Senior Product Designer.” Tap to remove or add your own.", options: ['Figma', 'Prototyping', 'User research', 'Design systems', 'Accessibility', 'Webflow', 'HTML / CSS', 'Workshop facilitation', 'Motion design', 'Usability testing', 'Sketch', 'After Effects'] },
  { id: 13.5, sec: 6, type: 'I', q: "Speak any languages besides English at a professional level?", followups: [
      { id: '13.5a', type: 'LANGS', q: "Add languages and proficiency" },
  ] },

  // Section 7 — Extras (each Yes opens its own follow-ups)
  { id: 14, sec: 7, type: 'I', q: "Any notable side projects?", hint: "Optional. Side projects help, but only the good ones.", followups: [
      { id: '14a', type: 'A', q: "Project name", placeholder: "e.g. Tilt — a Pomodoro for designers" },
      { id: '14b', type: 'B', q: "One or two sentences on what it is and why it matters", placeholder: "A Mac menubar timer with…", rows: 3 },
      { id: '14c', type: 'A', q: "URL (optional)", placeholder: "tiltapp.io", optional: true },
      { id: '14d', type: 'A', q: "Year", placeholder: "2024" },
  ] },
  { id: 14.2, sec: 7, type: 'I', q: "Any certifications?", followups: [
      { id: '14.2a', type: 'A', q: "Certification name", placeholder: "Google UX Certificate" },
      { id: '14.2b', type: 'A', q: "Issued by", placeholder: "Google / Coursera" },
      { id: '14.2c', type: 'A', q: "Year earned", placeholder: "2023" },
      { id: '14.2d', type: 'I', q: "Does it expire?", followups: [
          { id: '14.2d-i', type: 'A', q: "Expiration year", placeholder: "2027" },
      ] },
  ] },
  { id: 14.4, sec: 7, type: 'I', q: "Any awards or honors?", followups: [
      { id: '14.4a', type: 'A', q: "Award name", placeholder: "ADC Bronze Cube" },
      { id: '14.4b', type: 'A', q: "Given by", placeholder: "Art Directors Club" },
      { id: '14.4c', type: 'A', q: "Year", placeholder: "2022" },
  ] },
  { id: 14.6, sec: 7, type: 'I', q: "Volunteer work you want to mention?", hint: "If it shows leadership or relevant skill, it's worth including.", followups: [
      { id: '14.6a', type: 'A', q: "Organization", placeholder: "826 Valencia" },
      { id: '14.6b', type: 'A', q: "Your role there", placeholder: "Tutor & curriculum designer" },
      { id: '14.6c', type: 'B', q: "What did you do?", placeholder: "Designed a 6-week workshop on…", rows: 2 },
  ] },
  { id: 14.8, sec: 7, type: 'I', q: "Publications, talks, or media?", followups: [
      { id: '14.8a', type: 'A', q: "Title", placeholder: "“Designing for Trust at Scale”" },
      { id: '14.8b', type: 'C', q: "Format", options: [
          { label: "Talk", desc: "Conference or meetup" },
          { label: "Article", desc: "Blog, magazine, journal" },
          { label: "Podcast", desc: "Guest appearance" },
          { label: "Book or chapter", desc: "Authored or co-authored" },
      ] },
      { id: '14.8c', type: 'A', q: "Venue", placeholder: "Config 2024" },
      { id: '14.8d', type: 'A', q: "URL", placeholder: "Optional", optional: true },
  ] },

  // Section 8 — Final Touches
  { id: 14.9, sec: 8, type: 'I', q: "Have a specific job description in mind?", hint: "Paste it and we'll tune phrasing, skills, and emphasis to match.", followups: [
      { id: '14.9a', type: 'B', q: "Paste the job description", placeholder: "Title, requirements, responsibilities… up to 5,000 characters.", rows: 6 },
  ] },
  { id: 15, sec: 8, type: 'C', q: "Pick a tone.", hint: "We'll mirror this in every bullet.", options: [
      { label: "Confident", desc: '"Owned a $2.1M revenue lift…"' },
      { label: "Friendly", desc: '"Helped grow the team from 3 to 12…"' },
      { label: "Formal", desc: '"Spearheaded an enterprise initiative…"' },
  ] },
  { id: 15.5, sec: 8, type: 'I', q: "Want a photo on your resume?", hint: "Not recommended for US-market ATS — fine for portfolios and EU CVs.", followups: [
      { id: '15.5a', type: 'PHOTO', q: "Upload a square photo" },
  ] },
  { id: 16, sec: 8, type: 'CONFIRM', q: "Ready to generate?", hint: "Last look. You can edit anything afterward." },
];
const SECTIONS = [
  { n: 1, name: 'The Basics' },
  { n: 2, name: 'Your Target' },
  { n: 3, name: 'Your Story' },
  { n: 4, name: 'Work Experience' },
  { n: 5, name: 'Education' },
  { n: 6, name: 'Skills' },
  { n: 7, name: 'Extras' },
  { n: 8, name: 'Final Touches' },
];

// The work history is captured by the ExperienceRepeater (question id 11) and
// stored in answers[11] as an array of { title, company, location, dates, summary }.

// Flatten the survey answers into a readable Q&A transcript for the model.
function buildSurveyPayload(answers) {
  const lines = [];
  const fmtSub = (followups, sub) => {
    (followups || []).forEach(f => {
      const v = sub?.[f.id];
      if (v === undefined || v === null || v === '') return;
      if (f.type === 'I') { lines.push(`  - ${f.q}: ${v.choice || ''}`); fmtSub(f.followups, v.sub); }
      else if (f.type === 'LANGS') lines.push(`  - ${f.q}: ${(v || []).map(l => `${l.name} (${['Basic','Conversational','Professional','Fluent','Native'][l.level-1]})`).join(', ')}`);
      else if (Array.isArray(v)) lines.push(`  - ${f.q}: ${v.join(', ')}`);
      else lines.push(`  - ${f.q}: ${typeof v === 'object' ? (v.choice || JSON.stringify(v)) : v}`);
    });
  };
  SURVEY_QUESTIONS.forEach(q => {
    const v = answers[q.id];
    if (v === undefined || v === null || v === '') return;
    if (q.type === 'G' || q.type === 'CONFIRM') return;
    if (q.type === 'I') {
      lines.push(`${q.q} ${v.choice || ''}`);
      if (v.choice === 'Yes') fmtSub(q.followups, v.sub);
    } else if (q.type === 'D') {
      if (v.length) lines.push(`${q.q} ${v.join(', ')}`);
    } else if (q.type === 'E') {
      lines.push(`${q.q} ${v}`);
    } else {
      lines.push(`${q.q} ${v}`);
    }
  });
  const jobs = Array.isArray(answers[11]) ? answers[11] : [];
  // Fold any per-job notes the user wrote into the transcript so the model can use them.
  jobs.forEach((j) => {
    if (j.summary && j.summary.trim()) {
      lines.push(`What I did at ${j.company || 'this job'} (${j.title || ''}): ${j.summary.trim()}`);
    }
  });
  return {
    transcript: lines.join('\n'),
    jobs,
    name: answers[1] || '',
    email: answers[2] || '',
    phone: answers[3] || '',
    location: answers[4] || '',
    role: answers[7] || '',
    skills: Array.isArray(answers[13]) ? answers[13] : [],
    tone: answers[15] || 'Confident',
  };
}

function SurveyScreen({ go, onComplete, resume }) {
  const [idx, setIdx] = useState(0);
  const [maxIdx, setMaxIdx] = useState(0);
  const [answers, setAnswers] = useState({});
  const hydratedRef = useRef(false);
  const [showInterstitial, setShowInterstitial] = useState(false);
  const [showSaveExit, setShowSaveExit] = useState(false);
  const [whyOpen, setWhyOpen] = useState(true);

  const q = SURVEY_QUESTIONS[idx];
  const total = SURVEY_QUESTIONS.length;
  const progress = ((idx + 1) / total) * 100;
  const section = SECTIONS.find(s => s.n === q.sec);

  const setAnswer = (val) => setAnswers(a => ({ ...a, [q.id]: val }));

  // Validate recursively — conditional follow-ups must be filled when "Yes".
  const isFilled = (qq, val) => {
    if (qq.optional) return true;
    if (qq.type === 'A') return !!val && String(val).trim().length > 0;
    if (qq.type === 'B') return !!val && String(val).trim().length > 0;
    if (qq.type === 'C') return !!(val && (val.choice || val));
    if (qq.type === 'D') return Array.isArray(val) && val.length > 0;
    if (qq.type === 'E') return val !== undefined;
    if (qq.type === 'I') {
      if (!val || !val.choice) return false;
      if (val.choice === 'No') return true;
      if (qq.followups) {
        return qq.followups.every(f => isFilled(f, val.sub?.[f.id]));
      }
      return true;
    }
    if (qq.type === 'J') return !!val;
    if (qq.type === 'LANGS') return Array.isArray(val) && val.length > 0;
    if (qq.type === 'PHOTO') return !!val;
    if (qq.type === 'G') return true; // work history is optional (students, career changers)
    if (qq.type === 'CONFIRM') return true;
    return true;
  };
  const isValid = () => isFilled(q, answers[q.id]);

  const finish = () => {
    onComplete?.(buildSurveyPayload(answers));
    go('generating');
  };

  const next = () => {
    if (idx === total - 1) { finish(); return; }
    const newIdx = idx + 1;
    setMaxIdx(m => Math.max(m, newIdx));
    const nextQ = SURVEY_QUESTIONS[newIdx];
    if (nextQ.sec !== q.sec) {
      setShowInterstitial(true);
      setTimeout(() => {
        setShowInterstitial(false);
        setIdx(newIdx);
      }, 1400);
    } else {
      setIdx(newIdx);
    }
  };
  const back = () => { if (idx > 0) setIdx(idx - 1); };
  const forward = () => { if (idx < maxIdx) setIdx(idx + 1); };
  const jumpToQuestion = (qid) => {
    const i = SURVEY_QUESTIONS.findIndex(x => x.id === qid);
    if (i >= 0) { setMaxIdx(m => Math.max(m, i)); setIdx(i); }
  };
  const canGoForward = idx < maxIdx;
  const isFinal = idx === total - 1;

  // Resume an in-progress survey from autosave (when arriving via the dashboard).
  useEffect(() => {
    if (resume && window.RR?.survey) {
      window.RR.survey.get().then(s => {
        if (s && s.answers) { setAnswers(s.answers); setIdx(s.idx || 0); setMaxIdx(s.idx || 0); }
        hydratedRef.current = true;
      });
    } else {
      hydratedRef.current = true;
    }
  }, []);

  // Autosave progress (debounced) so the user can stop and pick up later.
  useEffect(() => {
    if (!hydratedRef.current || !window.RR?.survey) return undefined;
    const t = setTimeout(() => {
      window.RR.survey.save({ answers, idx, progress: Math.round(progress), label: `Section ${section.n}: ${section.name}` });
    }, 500);
    return () => clearTimeout(t);
  }, [answers, idx]);

  // Keyboard — Enter advances, but not when focus is in a textarea
  // (Enter inside textarea = newline).
  useEffect(() => {
    const fn = (e) => {
      if (e.key !== 'Enter') return;
      const tag = (e.target?.tagName || '').toLowerCase();
      if (tag === 'textarea') return;
      if (isValid()) { e.preventDefault(); next(); }
    };
    window.addEventListener('keydown', fn);
    return () => window.removeEventListener('keydown', fn);
  });

  return (
    <div style={{ minHeight: '100%', display:'flex', flexDirection:'column', background: 'var(--bg-canvas)' }}>
      {/* Top bar */}
      <div style={{ padding: '16px 32px', borderBottom: '1px solid var(--border-default)', display:'flex', alignItems:'center', gap: 24, background:'var(--bg-canvas)' }}>
        <Wordmark size="sm"/>
        <div style={{ flex: 1, position:'relative' }}>
          <div className="progress" style={{ height: 4 }}><div className="progress-fill" style={{ width: `${progress}%` }}/></div>
        </div>
        <div className="chip tag" style={{ background: 'var(--bg-sunken)' }}>
          Section {section.n} of 8 — {section.name}
        </div>
        <button onClick={()=>setShowSaveExit(true)} style={{ background:'transparent', border: 0, fontFamily:'inherit', fontSize: 13, color:'var(--text-secondary)', cursor:'pointer' }}>Save & exit</button>
      </div>

      {/* Content */}
      <div className="grow" style={{ display: 'grid', gridTemplateColumns: '1fr 320px', gap: 48, padding: '56px 64px', maxWidth: 1200, margin: '0 auto', width: '100%', alignItems:'start' }}>
        <div key={idx} className="fade-up">
          <div className="t-mono muted" style={{ marginBottom: 16 }}>Q{String(idx + 1).padStart(2,'0')}</div>
          <h2 className="t-h1" style={{ marginTop: 0, marginBottom: 12 }}>{q.q}</h2>
          {q.hint && <p className="t-body-lg secondary" style={{ marginTop: 0, marginBottom: 36 }}>{q.hint}</p>}

          <QuestionInput q={q} value={answers[q.id]} onChange={setAnswer} onAutoAdvance={next} role={answers[7]} tone={answers[15]} answers={answers} jumpTo={jumpToQuestion}/>

          {/* Inline Continue affordance — only when the question's input doesn't
              auto-advance on selection. */}
          {(() => {
            const a = answers[q.id];
            const autoAdv = (q.type === 'C')
                         || (q.type === 'I' && (a?.choice === 'No' || (a?.choice === 'Yes' && !q.followups)));
            if (autoAdv) return null;
            if (q.type === 'CONFIRM') return null; // bottom bar has Generate
            if (!isValid()) return null;
            return (
              <div style={{ marginTop: 32, animation: 'fadeUp var(--d-base) var(--e-out)' }}>
                <Btn variant="primary" onClick={next} iconRight={<Icon.arrowRight size={16}/>}>Continue</Btn>
                <span className="t-body-sm muted" style={{ marginLeft: 12 }}>or press <span className="kbd">Enter</span></span>
              </div>
            );
          })()}
        </div>

        {/* Helper panel */}
        {q.why && (
          <div className="card" style={{ padding: 18, alignSelf:'start', background:'var(--bg-sunken)', border: 0 }}>
            <button onClick={()=>setWhyOpen(!whyOpen)} style={{ background:'transparent', border: 0, fontFamily:'inherit', fontSize: 12, fontWeight: 600, color:'var(--text-secondary)', textTransform:'uppercase', letterSpacing:'0.08em', cursor:'pointer', display:'flex', alignItems:'center', gap: 6, padding: 0, width: '100%', justifyContent:'space-between' }}>
              <span style={{ display:'flex', gap: 6, alignItems:'center' }}><Icon.sparkles size={13}/> Why we ask this</span>
              <span style={{ transform: whyOpen ? 'rotate(180deg)' : 'none', transition:'transform var(--d-fast)' }}><Icon.chevDown size={14}/></span>
            </button>
            {whyOpen && <p className="t-body-sm" style={{ marginTop: 10, marginBottom: 0, color:'var(--text-secondary)' }}>{q.why}</p>}
          </div>
        )}
      </div>

      {/* Bottom bar */}
      <div style={{ padding: '16px 32px', borderTop: '1px solid var(--border-default)', display:'flex', alignItems:'center', justifyContent:'space-between', background:'var(--bg-canvas)' }}>
        <Btn variant="text" disabled={idx === 0} onClick={back} icon={<Icon.arrowLeft size={16}/>}>Back</Btn>
        <div className="t-body-sm muted" style={{ display:'flex', alignItems:'center', gap: 10 }}>
          Question {idx + 1} of {total}
          {!isFinal && !canGoForward && (
            <span style={{ display:'inline-flex', gap: 4, alignItems:'center' }}>
              <span className="kbd">Enter</span>
              <span className="t-caption muted">when ready</span>
            </span>
          )}
        </div>
        {isFinal ? (
          <Btn variant="primary" disabled={!isValid()} onClick={next} iconRight={<Icon.sparkles size={16}/>}>Generate</Btn>
        ) : canGoForward ? (
          <Btn variant="text" onClick={forward} iconRight={<Icon.arrowRight size={16}/>}>Forward</Btn>
        ) : (
          <div style={{ width: 96 }}/>
        )}
      </div>

      {/* Section interstitial */}
      {showInterstitial && (
        <div style={{ position:'fixed', inset: 0, background: 'var(--bg-canvas)', zIndex: 50, display:'flex', alignItems:'center', justifyContent:'center', animation:'fadeIn 0.3s var(--e-out)' }}>
          <div className="fade-up" style={{ textAlign:'center' }}>
            <div className="t-mono muted" style={{ marginBottom: 16, letterSpacing:'0.14em' }}>SECTION {SURVEY_QUESTIONS[idx + 1]?.sec}</div>
            <h1 className="t-display" style={{ fontSize: 64, margin: 0 }}>Nice. Now let's talk<br/>about your <span style={{ color:'var(--accent-primary)' }}>{SECTIONS.find(s=>s.n === SURVEY_QUESTIONS[idx+1]?.sec)?.name.toLowerCase()}</span>.</h1>
          </div>
        </div>
      )}

      <Modal open={showSaveExit} onClose={()=>setShowSaveExit(false)}>
        <h3 className="t-h3" style={{ margin: 0 }}>You're saved.</h3>
        <p className="t-body secondary" style={{ marginTop: 8 }}>Pick up where you left off from your dashboard. You're <strong style={{ color:'var(--text-primary)' }}>{Math.round(progress)}%</strong> through.</p>
        <div style={{ display:'flex', gap: 8, justifyContent:'flex-end', marginTop: 24 }}>
          <Btn variant="secondary" onClick={()=>setShowSaveExit(false)}>Back to survey</Btn>
          <Btn variant="primary" onClick={()=>go('dashboard')}>Exit to dashboard</Btn>
        </div>
      </Modal>
    </div>
  );
}

function QuestionInput({ q, value, onChange, onAutoAdvance, role, tone, answers, jumpTo }) {
  if (q.type === 'A') {
    return (
      <input
        className="input input-xl"
        placeholder={q.placeholder}
        value={value || ''}
        onChange={e=>onChange(e.target.value)}
        autoFocus
        style={{ width: '100%' }}
      />
    );
  }

  if (q.type === 'B') {
    const [phrasing, setPhrasing] = useState(false);
    const len = (value || '').length;
    const max = 1000;
    const helpPhrase = async () => {
      if (!value || !value.trim() || !window.RR?.helpPhrase) return;
      setPhrasing(true);
      const better = await window.RR.helpPhrase({ text: value, question: q.q, role, tone });
      setPhrasing(false);
      if (better) onChange(better);
    };
    return (
      <div>
        <textarea
          rows={6}
          placeholder={q.placeholder}
          value={value || ''}
          onChange={e=>onChange(e.target.value)}
          autoFocus
          style={{
            width: '100%', resize: 'vertical', minHeight: 140,
            fontFamily: 'inherit', fontSize: 18, lineHeight: 1.5,
            background:'transparent', border: 0, borderBottom:'2px solid var(--border-default)',
            padding: '12px 0', outline: 'none', color:'inherit',
          }}
          onFocus={e=>e.target.style.borderBottomColor='var(--accent-primary)'}
          onBlur={e=>e.target.style.borderBottomColor='var(--border-default)'}
        />
        <div style={{ display:'flex', justifyContent:'space-between', alignItems:'center', marginTop: 8 }}>
          <Btn variant="text" size="sm" icon={<Icon.sparkles size={14}/>} loading={phrasing} onClick={helpPhrase}>Help me phrase this</Btn>
          <div className="t-mono muted" style={{ fontSize: 11 }}>{len} / {max}</div>
        </div>
      </div>
    );
  }

  if (q.type === 'C') {
    return (
      <div className="stack-sm">
        {q.options.map((opt, i) => {
          const label = typeof opt === 'string' ? opt : opt.label;
          const desc = typeof opt === 'string' ? null : opt.desc;
          const sel = value === label;
          return (
            <div key={i} className={`card-selectable ${sel ? 'selected' : ''}`} onClick={()=>{ onChange(label); setTimeout(onAutoAdvance, 250); }}>
              <span className="kbd" style={{ width: 22, height: 22 }}>{i+1}</span>
              <div style={{ flex: 1 }}>
                <div style={{ fontWeight: 500, fontSize: 16 }}>{label}</div>
                {desc && <div className="t-body-sm muted" style={{ marginTop: 2 }}>{desc}</div>}
              </div>
              {sel && <Icon.check size={20} style={{ color: 'var(--accent-primary)' }}/>}
            </div>
          );
        })}
      </div>
    );
  }

  if (q.type === 'D') {
    const sel = value || [];
    const [custom, setCustom] = useState('');
    const [showCustom, setShowCustom] = useState(false);
    const toggle = (o) => onChange(sel.includes(o) ? sel.filter(x => x !== o) : [...sel, o]);
    return (
      <div>
        <div style={{ display:'flex', flexWrap:'wrap', gap: 8 }}>
          {q.options.map(o => <Chip key={o} selected={sel.includes(o)} onClick={()=>toggle(o)}>{o}</Chip>)}
          {sel.filter(o => !q.options.includes(o)).map(o => <Chip key={o} selected onClick={()=>toggle(o)}>{o} <Icon.x size={12}/></Chip>)}
          {showCustom ? (
            <input
              autoFocus
              value={custom}
              onChange={e=>setCustom(e.target.value)}
              onKeyDown={e=>{ if (e.key === 'Enter' && custom.trim()) { onChange([...sel, custom.trim()]); setCustom(''); setShowCustom(false); } }}
              onBlur={()=>{ if (custom.trim()) onChange([...sel, custom.trim()]); setCustom(''); setShowCustom(false); }}
              placeholder="Type and press Enter"
              className="input"
              style={{ height: 34, fontSize: 14, padding:'0 12px', borderRadius: 999, width: 200 }}
            />
          ) : (
            <Chip onClick={()=>setShowCustom(true)}><Icon.plus size={12}/> Add your own</Chip>
          )}
        </div>
        <div className="t-body-sm muted" style={{ marginTop: 16 }}>{sel.length} selected</div>
      </div>
    );
  }

  if (q.type === 'E') {
    const v = value ?? Math.floor((q.min + q.max) / 2);
    const pct = ((v - q.min) / (q.max - q.min)) * 100;
    return (
      <div style={{ paddingTop: 32 }}>
        <div style={{ position:'relative', height: 56 }}>
          <div style={{ position:'absolute', left: `calc(${pct}% - 28px)`, top: 0, padding: '4px 10px', background:'var(--text-primary)', color:'var(--bg-canvas)', borderRadius: 6, fontSize: 14, fontWeight: 600, transform: 'translateY(-100%)', marginTop: -8 }}>
            {v} {v === 1 ? 'year' : 'years'}
          </div>
          <div style={{ position:'absolute', top: 26, left: 0, right: 0, height: 4, background:'var(--border-default)', borderRadius: 999 }}>
            <div style={{ height: '100%', width: `${pct}%`, background: 'var(--accent-primary)', borderRadius: 999 }}/>
          </div>
          <input
            type="range"
            min={q.min} max={q.max} step={q.step} value={v}
            onChange={e=>onChange(Number(e.target.value))}
            style={{ position:'absolute', top: 18, left: 0, width:'100%', appearance:'none', background:'transparent', height: 20 }}
          />
        </div>
        <div style={{ display:'flex', justifyContent:'space-between', color:'var(--text-muted)', fontSize: 12, marginTop: 8 }}>
          <span>{q.min}</span><span>{q.max}+</span>
        </div>
      </div>
    );
  }

  if (q.type === 'J') {
    const [q2, setQ2] = useState(value || '');
    useEffect(() => onChange(q2), [q2]);
    const filtered = q.suggestions.filter(s => s.toLowerCase().includes(q2.toLowerCase()) && s !== q2);
    return (
      <div style={{ position:'relative' }}>
        <input
          className="input input-xl"
          placeholder="Start typing…"
          value={q2}
          onChange={e=>setQ2(e.target.value)}
          autoFocus
        />
        {q2.length > 0 && filtered.length > 0 && (
          <div style={{ position:'absolute', top: '100%', left: 0, right: 0, marginTop: 8, background:'var(--bg-surface)', border:'1px solid var(--border-default)', borderRadius: 'var(--r-md)', boxShadow:'var(--shadow-md)', zIndex: 5, overflow:'hidden' }}>
            {filtered.slice(0, 6).map((s, i) => (
              <div key={s} onClick={()=>setQ2(s)} style={{ padding: '12px 16px', cursor:'pointer', fontSize: 15, borderTop: i ? '1px solid var(--border-default)' : 0 }} onMouseEnter={e=>e.currentTarget.style.background='var(--bg-sunken)'} onMouseLeave={e=>e.currentTarget.style.background='transparent'}>
                {s}
              </div>
            ))}
          </div>
        )}
      </div>
    );
  }

  if (q.type === 'I') {
    const val = value || {};
    const choice = val.choice;
    const sub = val.sub || {};
    const setChoice = (c) => {
      const next = { choice: c, sub };
      onChange(next);
      if (c === 'No' || !q.followups) setTimeout(onAutoAdvance, 250);
    };
    const setSub = (subId, v) => onChange({ choice, sub: { ...sub, [subId]: v } });

    return (
      <div>
        <div style={{ display:'flex', gap: 16 }}>
          {['Yes', 'No'].map(opt => (
            <div key={opt} onClick={()=>setChoice(opt)}
                 className={`card-selectable ${choice === opt ? 'selected' : ''}`}
                 style={{ flex: 1, justifyContent:'center', padding:'24px 24px' }}>
              <div style={{ fontSize: 20, fontWeight: 600 }}>{opt}</div>
            </div>
          ))}
        </div>

        {/* Sliding follow-ups */}
        {q.followups && (
          <div className={`sub-reveal ${choice === 'Yes' ? 'open' : ''}`}>
            <div style={{ paddingTop: 28 }}>
              <div className="t-mono muted" style={{ marginBottom: 14, letterSpacing:'0.1em', display:'flex', alignItems:'center', gap: 8 }}>
                <span style={{ width: 16, height: 1, background:'var(--accent-primary)' }}/>
                TELL US MORE
              </div>
              <div className="stack-lg">
                {q.followups.map((f, i) => (
                  <SubQuestion key={f.id} q={f} value={sub[f.id]} onChange={(v)=>setSub(f.id, v)} index={i}/>
                ))}
              </div>
            </div>
          </div>
        )}
      </div>
    );
  }

  if (q.type === 'LANGS') {
    return <LanguagesInput value={value} onChange={onChange}/>;
  }

  if (q.type === 'PHOTO') {
    return <PhotoInput value={value} onChange={onChange}/>;
  }

  if (q.type === 'G') {
    return <ExperienceRepeater value={value} onChange={onChange}/>;
  }

  if (q.type === 'CONFIRM') {
    return <ConfirmationSummary answers={answers} jumpTo={jumpTo}/>;
  }

  return null;
}

// Controlled work-history editor. value/onChange manage an array of
// { title, company, location, dates, summary }.
function ExperienceRepeater({ value, onChange }) {
  const jobs = Array.isArray(value) ? value : [];
  const [editing, setEditing] = useState(null); // index being edited, or 'new'
  const [draft, setDraft] = useState({ title: '', company: '', location: '', dates: '', summary: '' });

  const startAdd = () => { setDraft({ title: '', company: '', location: '', dates: '', summary: '' }); setEditing('new'); };
  const startEdit = (i) => { setDraft({ ...jobs[i] }); setEditing(i); };
  const cancel = () => setEditing(null);
  const remove = (i) => onChange(jobs.filter((_, j) => j !== i));
  const save = () => {
    if (!draft.title.trim() && !draft.company.trim()) { setEditing(null); return; }
    if (editing === 'new') onChange([...jobs, draft]);
    else onChange(jobs.map((j, i) => (i === editing ? draft : j)));
    setEditing(null);
  };

  const field = (label, key, placeholder) => (
    <div>
      <label className="sub-label">{label}</label>
      <input className="input sub-input" placeholder={placeholder} value={draft[key]}
             onChange={e => setDraft(d => ({ ...d, [key]: e.target.value }))}/>
    </div>
  );

  const form = (
    <div className="card" style={{ padding: 18 }}>
      <div className="stack">
        <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 12 }}>
          {field('Job title', 'title', 'e.g. Product Designer')}
          {field('Company', 'company', 'e.g. Acme Inc.')}
          {field('Location', 'location', 'e.g. Remote · Austin, TX')}
          {field('Dates', 'dates', 'e.g. Jan 2022 — Present')}
        </div>
        <div>
          <label className="sub-label">What did you do here? <span className="muted">(plain English — we'll write the bullets)</span></label>
          <textarea className="input sub-input" rows={3} placeholder="e.g. Owned the checkout redesign, ran user tests, shipped a design system…"
                    value={draft.summary} onChange={e => setDraft(d => ({ ...d, summary: e.target.value }))}
                    style={{ resize: 'vertical', fontFamily: 'inherit', lineHeight: 1.5 }}/>
        </div>
        <div style={{ display: 'flex', gap: 8, justifyContent: 'flex-end' }}>
          <Btn variant="text" onClick={cancel}>Cancel</Btn>
          <Btn variant="primary" onClick={save} disabled={!draft.title.trim() && !draft.company.trim()}>Save job</Btn>
        </div>
      </div>
    </div>
  );

  return (
    <div className="stack">
      {jobs.map((j, i) => (
        editing === i ? <div key={i}>{form}</div> : (
          <div key={i} className="card" style={{ display: 'flex', alignItems: 'center', gap: 16, padding: '16px 20px' }}>
            <div style={{ width: 40, height: 40, borderRadius: 8, background: 'var(--bg-sunken)', display: 'flex', alignItems: 'center', justifyContent: 'center', color: 'var(--text-secondary)' }}>
              <Icon.briefcase size={18}/>
            </div>
            <div style={{ flex: 1, minWidth: 0 }}>
              <div style={{ fontWeight: 500 }}>{j.title || 'Untitled role'}</div>
              <div className="t-body-sm muted">{[j.company, j.dates].filter(Boolean).join(' · ') || 'No details'}</div>
            </div>
            <Btn variant="text" size="sm" icon={<Icon.pencil size={14}/>} onClick={() => startEdit(i)}>Edit</Btn>
            <Btn variant="text" size="sm" icon={<Icon.trash size={14}/>} onClick={() => remove(i)}/>
          </div>
        )
      ))}

      {editing === 'new' && form}

      {editing !== 'new' && (
        <Btn variant="secondary" icon={<Icon.plus size={16}/>} style={{ alignSelf: 'start' }} onClick={startAdd}>
          {jobs.length ? 'Add another job' : 'Add your first job'}
        </Btn>
      )}
      {jobs.length === 0 && editing === null && (
        <div className="t-body-sm muted" style={{ marginTop: 8 }}>No work experience yet? No problem — you can continue without adding any.</div>
      )}
    </div>
  );
}

function ConfirmationSummary({ answers = {}, jumpTo }) {
  const a = answers;
  const yes = (id) => a[id]?.choice === 'Yes';
  const sub = (id, subId) => a[id]?.sub?.[subId];
  const jobs = Array.isArray(a[11]) ? a[11] : [];
  const eduLevel = a[12]?.choice || a[12] || null;
  const skills = Array.isArray(a[13]) ? a[13] : [];
  const industries = Array.isArray(a[9]) ? a[9] : [];

  const contact = [a[1], a[2], a[3], a[4]].filter(Boolean);
  if (yes(5)) contact.push(sub(5, '5a'));
  if (yes(6)) contact.push(sub(6, '6a'));

  const sections = [
    { jump: 1,  title: 'Contact', items: contact.length ? contact : ['Not provided'] },
    { jump: 7,  title: 'Target', items: [
        [a[7], a[8] != null ? `${a[8]} yrs` : null].filter(Boolean).join(' · ') || 'Not provided',
        industries.length ? industries.join(', ') : null,
      ].filter(Boolean) },
    { jump: 11, title: 'Experience', items: jobs.length
        ? jobs.map(j => [j.title, j.company].filter(Boolean).join(' — ') || 'Untitled role')
        : ['No jobs added'] },
    { jump: 12, title: 'Education', items: [eduLevel || 'Not provided'] },
    { jump: 13, title: 'Skills', items: [skills.length ? skills.join(', ') : 'None selected'] },
    { jump: 15, title: 'Tone', items: [a[15] || 'Confident'] },
  ];

  return (
    <div className="card card-lg" style={{ padding: 28 }}>
      <p className="t-body" style={{ margin: 0, marginBottom: 24 }}>Here's what we have. Tap Edit on any section to jump back.</p>
      <div className="stack">
        {sections.map(s => (
          <div key={s.title} style={{ display: 'grid', gridTemplateColumns: '160px 1fr auto', gap: 16, alignItems: 'start', padding: '12px 0', borderTop: '1px solid var(--border-default)' }}>
            <div className="t-mono" style={{ fontSize: 11, textTransform: 'uppercase', letterSpacing: '0.1em', color: 'var(--text-muted)' }}>{s.title}</div>
            <div className="t-body" style={{ color: 'var(--text-primary)' }}>{(s.items.length ? s.items : ['Not provided']).map((it, i) => <div key={i}>{it}</div>)}</div>
            <Btn variant="text" size="sm" icon={<Icon.pencil size={12}/>} onClick={() => jumpTo?.(s.jump)}>Edit</Btn>
          </div>
        ))}
      </div>
    </div>
  );
}

// SubQuestion — inline, lighter-chrome renderer used inside an "I" question's
// follow-ups. Recursive: a sub-question of type "I" can have its own follow-ups.
function SubQuestion({ q, value, onChange, index = 0 }) {
  const id = `sub-${q.id}`;

  if (q.type === 'A') {
    return (
      <div>
        <label htmlFor={id} className="sub-label">{q.q}{q.optional && <span className="muted"> · optional</span>}</label>
        <input id={id} className="input sub-input" placeholder={q.placeholder} value={value || ''} onChange={e=>onChange(e.target.value)} autoFocus={index === 0}/>
      </div>
    );
  }

  if (q.type === 'B') {
    return (
      <div>
        <label htmlFor={id} className="sub-label">{q.q}{q.optional && <span className="muted"> · optional</span>}</label>
        <textarea id={id} rows={q.rows || 3} placeholder={q.placeholder} value={value || ''} onChange={e=>onChange(e.target.value)} className="input sub-input" style={{ resize: 'vertical', fontFamily:'inherit', lineHeight: 1.5 }}/>
      </div>
    );
  }

  if (q.type === 'C') {
    const choice = value?.choice ?? value;
    return (
      <div>
        <div className="sub-label">{q.q}</div>
        <div style={{ display:'grid', gridTemplateColumns:'repeat(auto-fit, minmax(180px, 1fr))', gap: 8 }}>
          {q.options.map((opt, i) => {
            const label = typeof opt === 'string' ? opt : opt.label;
            const desc = typeof opt === 'string' ? null : opt.desc;
            const sel = choice === label;
            return (
              <div key={i} className={`card-selectable ${sel ? 'selected' : ''}`} onClick={()=>onChange(label)} style={{ padding: '12px 14px' }}>
                <div style={{ flex: 1 }}>
                  <div style={{ fontWeight: 500, fontSize: 14 }}>{label}</div>
                  {desc && <div className="t-body-sm muted" style={{ marginTop: 2, fontSize: 12 }}>{desc}</div>}
                </div>
                {sel && <Icon.check size={16} style={{ color:'var(--accent-primary)' }}/>}
              </div>
            );
          })}
        </div>
      </div>
    );
  }

  if (q.type === 'D') {
    const sel = value || [];
    const toggle = (o) => onChange(sel.includes(o) ? sel.filter(x => x !== o) : [...sel, o]);
    return (
      <div>
        <div className="sub-label">{q.q}</div>
        <div style={{ display:'flex', flexWrap:'wrap', gap: 6 }}>
          {q.options.map(o => <Chip key={o} selected={sel.includes(o)} onClick={()=>toggle(o)}>{o}</Chip>)}
        </div>
      </div>
    );
  }

  if (q.type === 'I') {
    const val = value || {};
    const choice = val.choice;
    const sub = val.sub || {};
    const setChoice = (c) => onChange({ choice: c, sub });
    const setSub = (sid, v) => onChange({ choice, sub: { ...sub, [sid]: v } });
    return (
      <div>
        <div className="sub-label">{q.q}</div>
        <div style={{ display:'flex', gap: 8 }}>
          {['Yes', 'No'].map(opt => (
            <button key={opt} onClick={()=>setChoice(opt)} className={`chip ${choice === opt ? 'selected' : ''}`} style={{ flex: 1, height: 36, justifyContent:'center', fontWeight: 600 }}>{opt}</button>
          ))}
        </div>
        {q.followups && (
          <div className={`sub-reveal ${choice === 'Yes' ? 'open' : ''}`}>
            <div style={{ paddingTop: 16 }} className="stack">
              {q.followups.map((f, i) => <SubQuestion key={f.id} q={f} value={sub[f.id]} onChange={(v)=>setSub(f.id, v)} index={i}/>)}
            </div>
          </div>
        )}
      </div>
    );
  }

  if (q.type === 'LANGS') {
    return (
      <div>
        <div className="sub-label">{q.q}</div>
        <LanguagesInput value={value} onChange={onChange}/>
      </div>
    );
  }

  if (q.type === 'PHOTO') {
    return (
      <div>
        <div className="sub-label">{q.q}</div>
        <PhotoInput value={value} onChange={onChange}/>
      </div>
    );
  }

  return null;
}

// Languages — chip-style with inline proficiency slider.
function LanguagesInput({ value = [], onChange }) {
  const [name, setName] = useState('');
  const add = () => {
    if (!name.trim()) return;
    onChange([...(value || []), { name: name.trim(), level: 3 }]);
    setName('');
  };
  const update = (i, patch) => onChange(value.map((v, j) => j === i ? { ...v, ...patch } : v));
  const remove = (i) => onChange(value.filter((_, j) => j !== i));
  const levels = ['Basic', 'Conversational', 'Professional', 'Fluent', 'Native'];
  return (
    <div className="stack-sm">
      {(value || []).map((lang, i) => (
        <div key={i} className="card" style={{ display:'grid', gridTemplateColumns:'140px 1fr 100px 32px', gap: 14, alignItems:'center', padding: 14 }}>
          <div style={{ fontWeight: 500, fontSize: 15 }}>{lang.name}</div>
          <input type="range" min={1} max={5} step={1} value={lang.level} onChange={e=>update(i, { level: Number(e.target.value) })} style={{ width:'100%' }}/>
          <div className="t-body-sm" style={{ color:'var(--accent-primary)', fontWeight: 600 }}>{levels[lang.level - 1]}</div>
          <button onClick={()=>remove(i)} style={{ background:'transparent', border: 0, cursor:'pointer', color:'var(--text-muted)', padding: 4 }}><Icon.x size={14}/></button>
        </div>
      ))}
      <div style={{ display:'flex', gap: 8 }}>
        <input className="input" placeholder="e.g. Spanish" value={name} onChange={e=>setName(e.target.value)} onKeyDown={e=>{ if (e.key === 'Enter') { e.preventDefault(); add(); } }} style={{ flex: 1 }}/>
        <Btn variant="secondary" onClick={add} icon={<Icon.plus size={14}/>}>Add</Btn>
      </div>
    </div>
  );
}

function PhotoInput({ value, onChange }) {
  return (
    <div>
      {value ? (
        <div style={{ display:'flex', gap: 16, alignItems:'center' }}>
          <div style={{ width: 96, height: 96, borderRadius:'50%', background:'var(--bg-sunken)', display:'flex', alignItems:'center', justifyContent:'center', fontFamily:'var(--font-display)', fontSize: 36, color:'var(--text-secondary)' }}>MO</div>
          <div>
            <div style={{ fontWeight: 500, marginBottom: 4 }}>Photo uploaded</div>
            <div className="t-body-sm muted">You can crop & reframe in the Beautify Studio.</div>
            <Btn variant="text" size="sm" onClick={()=>onChange(null)} style={{ marginTop: 8, paddingLeft: 0 }}>Remove</Btn>
          </div>
        </div>
      ) : (
        <div onClick={()=>onChange('photo.jpg')} style={{ border:'2px dashed var(--border-default)', borderRadius: 12, padding:'32px 24px', background:'var(--bg-sunken)', textAlign:'center', cursor:'pointer' }}>
          <Icon.image size={28} style={{ color:'var(--text-muted)', marginBottom: 12 }}/>
          <div className="t-body" style={{ marginBottom: 4 }}>Drop a photo here</div>
          <div className="t-body-sm muted">JPG or PNG · we'll crop to square</div>
        </div>
      )}
    </div>
  );
}

Object.assign(window, { SurveyScreen });
