// Post a Job (employer) + Create Profile (helper) — wizard-style forms

const StepHeader = ({ step, total, titles, subtitle }) => (
  <div style={{marginBottom:28}}>
    <div style={{display:'flex', alignItems:'center', gap:10, marginBottom:16}}>
      {titles.map((t,i) => (
        <React.Fragment key={i}>
          <div style={{display:'flex', alignItems:'center', gap:10}}>
            <div style={{
              width:28, height:28, borderRadius:99,
              display:'grid', placeItems:'center',
              fontSize:12, fontWeight:700,
              background: i <= step ? 'var(--trust)' : 'var(--t-paper-2)',
              color: i <= step ? 'white' : 'var(--t-ink-muted)',
              border: i === step ? '2px solid var(--trust)' : 'none',
              flexShrink:0,
            }}>{i < step ? '✓' : i+1}</div>
            <div style={{
              fontSize:13, fontWeight: i === step ? 600 : 500,
              color: i === step ? 'var(--t-ink)' : i < step ? 'var(--t-ink-soft)' : 'var(--t-ink-muted)',
              whiteSpace:'nowrap',
            }}>{t}</div>
          </div>
          {i < total-1 && <div style={{flex:1, height:2, background: i < step ? 'var(--trust)' : 'var(--t-line)', minWidth:20}}/>}
        </React.Fragment>
      ))}
    </div>
    {subtitle && <p style={{color:'var(--t-ink-muted)', fontSize:15, margin:'18px 0 0'}}>{subtitle}</p>}
  </div>
);



const Field = ({ label, required, hint, icon, children }) => {
  const { t } = window.useI18n();
  // Manifest pattern A — inline disc before label. Custom size 44px box /
  // 32px icon (between FlatIconDisc's preset md=36 and lg=56) so the icon
  // anchors the row without dominating it.
  const flatDef = icon && window.FLAT_ICONS && window.FLAT_ICONS[icon];
  const discBg = flatDef && window.CAT_BG ? (window.CAT_BG[flatDef.cat] || 'var(--t-bg)') : 'var(--t-bg)';
  return (
    <div style={{marginBottom:28}}>
      <label className="label" style={{display:'flex', alignItems:'center', gap:12, marginBottom:8, fontSize:16}}>
        {flatDef && (
          <span style={{
            width:44, height:44, borderRadius:12, background:discBg,
            display:'inline-grid', placeItems:'center', flexShrink:0,
          }}>
            <window.FlatIcon name={icon} size={32}/>
          </span>
        )}
        {label}
        {required && <span style={{fontSize:11, color:'var(--coral-dark)', fontWeight:700, background:'var(--coral-bg)', padding:'2px 7px', borderRadius:99, letterSpacing:'0.04em'}}>{t('forms.common.required')}</span>}
      </label>
      {children}
      {hint && <div style={{fontSize:13, color:'var(--t-ink-muted)', marginTop:8}}>{hint}</div>}
    </div>
  );
};

// ChipPicker: interactive chip-cloud picker. When `category` is one of
// 'language' / 'main' / 'cooking' / 'other' / 'personality' it mirrors the
// SkillsGroup chip styles used on the public detail page (filled coral pills
// for language, ochre pills for cooking, outline + colored disc + skill icon
// for the others). When `category` is omitted it falls back to the original
// trust-color picker style — used for non-skill enum pickers like job type
// or pref nationality.
const ChipPicker = ({ options, value, onChange, multi = true, showFlag = false, category }) => {
  const arr = multi ? (value || []) : value;
  const toggle = (id) => {
    if (!multi) { onChange(id); return; }
    if (arr.includes(id)) onChange(arr.filter(x => x !== id));
    else onChange([...arr, id]);
  };
  const c = category && window.SKILL_CAT_COLORS && window.SKILL_CAT_COLORS[category];
  return (
    <div style={{display:'flex', flexWrap:'wrap', gap:8}}>
      {options.map(o => {
        const id = o.id || o;
        const label = (o.id && window.pickLocalised && window.pickLocalised(o, 'label')) || o.label || o;
        const active = multi ? arr.includes(id) : value === id;

        // Skill chips — outline pill + 32×32 disc + icon, shared across
        // language / main / cooking / other / personality. Disc bg comes
        // from the icon's own CAT_BG family when active so each row reads
        // as one colour family; neutral when inactive. Languages have no
        // flat-icon, so the flag emoji sits inside the disc instead.
        if (category === 'language' || category === 'main' || category === 'cooking' ||
            category === 'other' || category === 'personality') {
          const flatDef = window.FLAT_ICONS && window.FLAT_ICONS[id];
          const discBg = active
            ? (flatDef && window.CAT_BG ? (window.CAT_BG[flatDef.cat] || c.bg) : c.bg)
            : 'var(--t-bg)';
          const isLang = category === 'language';
          return (
            <button key={id} type="button" onClick={() => toggle(id)} style={{
              display:'inline-flex', alignItems:'center', gap:10,
              padding:'7px 18px 7px 7px', borderRadius:99,
              fontSize:14, fontWeight:500, cursor:'pointer',
              background:'var(--t-paper)',
              color: active ? 'var(--t-ink)' : 'var(--t-ink-soft)',
              border: `1.5px solid ${active ? c.fg : 'var(--t-line)'}`,
            }}>
              <span style={{
                display:'grid', placeItems:'center', width:32, height:32, borderRadius:99, flexShrink:0,
                background: discBg,
                color:      active ? c.fg : 'var(--t-ink-muted)',
                fontSize:   isLang ? 18 : undefined, lineHeight: 1,
              }}>
                {isLang
                  ? (o.flag || null)
                  : (flatDef
                      ? <window.FlatIcon name={id} size={22}/>
                      : <SkillIcon name={id} size={16}/>)}
              </span>
              {label}
            </button>
          );
        }

        // Default trust-color picker (non-skill enums like job type, gender).
        return (
          <button key={id} type="button" onClick={() => toggle(id)} style={{
            display:'inline-flex', alignItems:'center', gap:6,
            padding:'8px 14px', borderRadius:99, fontSize:13, fontWeight:500,
            background: active ? 'var(--trust)' : 'var(--t-paper)',
            color: active ? 'white' : 'var(--t-ink)',
            border: active ? '1px solid var(--trust)' : '1px solid var(--t-line)',
            cursor:'pointer',
          }}>
            {showFlag && o.flag && <span>{o.flag}</span>}
            {label}
          </button>
        );
      })}
    </div>
  );
};

// Rich-text editor (contentEditable) with B / I / bullet / number list
const RichTextEditor = ({ value, onChange, placeholder = '' }) => {
  const ref = React.useRef(null);
  // Set innerHTML only once on mount — then let contentEditable drive it
  React.useEffect(() => {
    if (ref.current && ref.current.innerHTML !== value) {
      ref.current.innerHTML = value || '';
    }
  // eslint-disable-next-line
  }, []);
  const exec = (cmd, arg) => {
    document.execCommand(cmd, false, arg);
    if (ref.current) onChange(ref.current.innerHTML);
  };
  const Tool = ({ icon, cmd, arg, title }) => (
    <button type="button" title={title} onMouseDown={e => { e.preventDefault(); exec(cmd, arg); }} style={{
      width:34, height:30, display:'grid', placeItems:'center',
      background:'transparent', border:'1px solid transparent', borderRadius:6,
      cursor:'pointer', color:'var(--t-ink-soft)', fontSize:13, fontWeight:600,
    }}
    onMouseEnter={e => { e.currentTarget.style.background='var(--t-paper)'; e.currentTarget.style.borderColor='var(--t-line)'; }}
    onMouseLeave={e => { e.currentTarget.style.background='transparent'; e.currentTarget.style.borderColor='transparent'; }}
    >{icon}</button>
  );
  return (
    <div style={{border:'1px solid var(--t-line)', borderRadius:10, overflow:'hidden', background:'var(--t-paper)'}}>
      <div style={{display:'flex', gap:2, padding:6, borderBottom:'1px solid var(--t-line)', background:'var(--t-paper-2)'}}>
        <Tool icon={<b>B</b>} cmd="bold" title="Bold"/>
        <Tool icon={<i>I</i>} cmd="italic" title="Italic"/>
        <Tool icon={<u>U</u>} cmd="underline" title="Underline"/>
        <div style={{width:1, background:'var(--t-line)', margin:'4px 4px'}}/>
        <Tool icon="•" cmd="insertUnorderedList" title="Bullet list"/>
        <Tool icon="1." cmd="insertOrderedList" title="Numbered list"/>
        <div style={{width:1, background:'var(--t-line)', margin:'4px 4px'}}/>
        <Tool icon={<span style={{fontSize:15, fontWeight:700}}>H</span>} cmd="formatBlock" arg="h3" title="Heading"/>
        <Tool icon="¶" cmd="formatBlock" arg="p" title="Paragraph"/>
      </div>
      <div
        ref={ref}
        contentEditable
        suppressContentEditableWarning
        onInput={e => onChange(e.currentTarget.innerHTML)}
        data-placeholder={placeholder}
        style={{
          minHeight:200, padding:'14px 16px', fontSize:15, lineHeight:1.7,
          color:'var(--t-ink)', outline:'none',
        }}
      />
      <style>{`
        [contenteditable][data-placeholder]:empty::before {
          content: attr(data-placeholder);
          color: var(--t-ink-muted);
          pointer-events: none;
        }
        [contenteditable] ul, [contenteditable] ol { padding-left: 24px; margin: 8px 0; }
        [contenteditable] h3 { font-size: 17px; font-weight: 600; margin: 12px 0 6px; }
        [contenteditable] p { margin: 6px 0; }
      `}</style>
    </div>
  );
};

// Pseudo-range slider (double thumb) using two native ranges
const RangeSlider = ({ min, max, value, onChange, unit = '', step = 1 }) => {
  const [lo, hi] = value;
  const setLo = (v) => onChange([Math.min(v, hi), hi]);
  const setHi = (v) => onChange([lo, Math.max(v, lo)]);
  const pct = (v) => ((v - min) / (max - min)) * 100;
  return (
    <div>
      <div style={{display:'flex', justifyContent:'space-between', marginBottom:10, fontSize:13, fontWeight:600, color:'var(--t-ink)'}}>
        <span>{lo}{unit}</span>
        <span>{hi}{unit}</span>
      </div>
      <div style={{position:'relative', height:24}}>
        {/* track (rail) */}
        <div style={{position:'absolute', top:10, left:0, right:0, height:4, background:'var(--t-line)', borderRadius:2}}/>
        {/* filled portion */}
        <div style={{position:'absolute', top:10, left:`${pct(lo)}%`, width:`${pct(hi)-pct(lo)}%`, height:4, background:'var(--trust)', borderRadius:2}}/>
        {/* two native ranges stacked */}
        <input
          type="range" min={min} max={max} step={step} value={lo}
          onChange={e => setLo(+e.target.value)}
          className="rs-thumb"
        />
        <input
          type="range" min={min} max={max} step={step} value={hi}
          onChange={e => setHi(+e.target.value)}
          className="rs-thumb"
        />
      </div>
      <style>{`
        .rs-thumb {
          position: absolute; top: 0; left: 0;
          width: 100%; height: 24px;
          background: transparent; border: none; outline: none;
          -webkit-appearance: none; appearance: none;
          pointer-events: none;
          padding: 0; margin: 0;
        }
        .rs-thumb::-webkit-slider-runnable-track {
          background: transparent; height: 4px; border: none;
        }
        .rs-thumb::-moz-range-track {
          background: transparent; height: 4px; border: none;
        }
        .rs-thumb::-webkit-slider-thumb {
          -webkit-appearance: none; appearance: none;
          pointer-events: auto;
          width: 20px; height: 20px; border-radius: 50%;
          background: var(--trust);
          border: 3px solid white;
          box-shadow: 0 2px 6px rgba(0,0,0,0.25);
          cursor: pointer;
          margin-top: -8px;
          position: relative; z-index: 2;
        }
        .rs-thumb::-moz-range-thumb {
          pointer-events: auto;
          width: 20px; height: 20px; border-radius: 50%;
          background: var(--trust);
          border: 3px solid white;
          box-shadow: 0 2px 6px rgba(0,0,0,0.25);
          cursor: pointer;
        }
        .rs-thumb:focus { outline: none; }
      `}</style>
    </div>
  );
};

// Discrete 5-step slider for the post-a-job "flexibility" picker. Snaps
// between fix / 2w / 1m / 2m / 3m. Single thumb, with the active label shown
// above the track. Re-declares the slider thumb CSS locally because RangeSlider
// (the original owner of `.rs-thumb`) lives on a different step and its
// component-scoped <style> isn't mounted when this slider renders alone.
const FLEX_STEPS = ['fix', '2w', '1m', '2m', '3m'];
const FlexibilitySlider = ({ value, onChange, t }) => {
  const idx = Math.max(0, FLEX_STEPS.indexOf(value));
  const pct = (idx / (FLEX_STEPS.length - 1)) * 100;
  return (
    <div>
      <div style={{display:'flex', justifyContent:'space-between', marginBottom:10, fontSize:13, fontWeight:600, color:'var(--t-ink)'}}>
        <span style={{color:'var(--trust)'}}>{t('forms.enum.flexibility.' + value)}</span>
        <span style={{color:'var(--t-ink-muted)', fontWeight:500}}>{t('forms.enum.flexibility.' + FLEX_STEPS[FLEX_STEPS.length - 1])}</span>
      </div>
      <div style={{position:'relative', height:24}}>
        <div style={{position:'absolute', top:10, left:0, right:0, height:4, background:'var(--t-line)', borderRadius:2}}/>
        <div style={{position:'absolute', top:10, left:0, width:`${pct}%`, height:4, background:'var(--trust)', borderRadius:2}}/>
        {FLEX_STEPS.map((_, i) => (
          <div key={i} style={{position:'absolute', top:8, left:`calc(${(i/(FLEX_STEPS.length-1))*100}% - 4px)`, width:8, height:8, borderRadius:99, background: i <= idx ? 'var(--trust)' : 'var(--t-line)'}}/>
        ))}
        <input
          type="range" min={0} max={FLEX_STEPS.length - 1} step={1} value={idx}
          onChange={e => onChange(FLEX_STEPS[+e.target.value])}
          className="flex-thumb"
        />
      </div>
      <div style={{display:'flex', justifyContent:'space-between', marginTop:8, fontSize:11, color:'var(--t-ink-muted)'}}>
        {FLEX_STEPS.map(s => (
          <span key={s} style={{flex:1, textAlign:'center', fontWeight: s === value ? 600 : 400, color: s === value ? 'var(--t-ink)' : 'var(--t-ink-muted)'}}>
            {t('forms.enum.flexibility.' + s)}
          </span>
        ))}
      </div>
      <style>{`
        .flex-thumb {
          position: absolute; top: 0; left: 0;
          width: 100%; height: 24px;
          background: transparent; border: none; outline: none;
          -webkit-appearance: none; appearance: none;
          padding: 0; margin: 0;
          cursor: pointer;
        }
        .flex-thumb::-webkit-slider-runnable-track {
          background: transparent; height: 4px; border: none;
        }
        .flex-thumb::-moz-range-track {
          background: transparent; height: 4px; border: none;
        }
        .flex-thumb::-webkit-slider-thumb {
          -webkit-appearance: none; appearance: none;
          width: 20px; height: 20px; border-radius: 50%;
          background: var(--trust);
          border: 3px solid white;
          box-shadow: 0 2px 6px rgba(0,0,0,0.25);
          cursor: pointer;
          margin-top: -8px;
          position: relative; z-index: 2;
        }
        .flex-thumb::-moz-range-thumb {
          width: 20px; height: 20px; border-radius: 50%;
          background: var(--trust);
          border: 3px solid white;
          box-shadow: 0 2px 6px rgba(0,0,0,0.25);
          cursor: pointer;
        }
        .flex-thumb:focus { outline: none; }
      `}</style>
    </div>
  );
};

// ===== City dropdown per market =====
const CITIES_BY_MARKET = {
  TW: ['Taipei', 'New Taipei', 'Taoyuan', 'Taichung', 'Tainan', 'Kaohsiung', 'Hsinchu', 'Keelung', 'Chiayi', 'Changhua', 'Yilan', 'Hualien'],
  HK: ['Central', 'Mid-Levels', 'Happy Valley', 'Causeway Bay', 'Wan Chai', 'North Point', 'Kowloon Tong', 'Tsim Sha Tsui', 'Kwun Tong', 'Sha Tin', 'Discovery Bay', 'Tung Chung'],
  SG: ['Bukit Timah', 'Orchard', 'Holland Village', 'Tanglin', 'Jurong East', 'Tampines', 'Woodlands', 'Bedok', 'Punggol', 'Queenstown', 'Sentosa', 'East Coast'],
};

// =====================================================================
// POST A JOB (employer) — 4 steps + Review
// =====================================================================
const PostJobPage = ({ go, loggedIn, subscription }) => {
  const { t } = window.useI18n();
  const tax = window.SKILL_TAXONOMY;
  const [step, setStep] = useState(0);
  const [showPublish, setShowPublish] = useState(false);
  const [form, setForm] = useState({
    // Step 1 — Basics
    title: '',
    position: 'Domestic Helper',
    jobType: 'full-time',
    market: 'TW',
    city: '',
    startDate: '',
    flexibility: 'fix',  // fix | 2w | 1m | 2m | 3m — start-date wiggle room
    familyAdults: 2,
    familyKids: 0,
    kidsAges: '',
    hasElderly: false,
    hasPets: false,
    petsDetail: '',
    // Step 2 — Requirements
    reqLanguages: ['english'],
    reqMainSkills: [],
    reqCookingSkills: [],
    reqOtherSkills: [],
    // Step 3 — Preference and offerings
    prefGender: 'Any',
    prefContractStatus: 'Any',
    prefNationalities: ['Indonesia','Philippines'],
    prefReligion: 'Any',
    prefEducation: 'Any',
    prefAgeRange: [25, 50],
    prefExpYears: [1, 15],
    // Offer (moved from step 0 / new fields):
    salaryMode: 'range',  // 'range' | 'tbd'
    salaryCurrency: 'NT$',
    salaryMin: '',
    salaryMax: '',
    jobDayOff: 'To be discussed',
    jobAccommodation: 'Dont mention',
    // Step 4 — About the job
    description: '<p></p>',
  });
  const update = (k, v) => setForm(f => ({...f, [k]: v}));

  // Sync currency when market changes
  useEffect(() => {
    const cur = form.market === 'HK' ? 'HK$' : form.market === 'SG' ? 'S$' : 'NT$';
    if (cur !== form.salaryCurrency) update('salaryCurrency', cur);
    // Reset city if not in new market's city list
    if (form.city && !CITIES_BY_MARKET[form.market].includes(form.city)) update('city', '');
  // eslint-disable-next-line
  }, [form.market]);

  const stepTitles = [
    t('forms.postJob.steps.0'),
    t('forms.postJob.steps.1'),
    t('forms.postJob.steps.2'),
    t('forms.postJob.steps.3'),
  ];

  const canContinue = () => {
    if (step === 0) return form.city && form.startDate;
    if (step === 1) return form.reqLanguages.length > 0 && form.reqMainSkills.length > 0;
    // Step 2 (Preference and offerings): salary picker is required to advance.
    if (step === 2) return form.salaryMode === 'tbd' || (form.salaryMin && form.salaryMax);
    if (step === 3) return form.title && form.description && form.description.replace(/<[^>]+>/g,'').trim().length > 20;
    return true;
  };

  const publishClick = () => {
    // If not logged in or free tier, show publish modal (pricing + signup/pay)
    if (!loggedIn || subscription === 'free') {
      setShowPublish(true);
    } else {
      alert('Job submitted for review. We\'ll notify you within 24 hours.');
      go('dashboard');
    }
  };

  return (
    <div className="page">
      <div className="container" style={{maxWidth:920, padding:'40px 32px 80px'}}>
        <button className="btn btn-ghost btn-sm" onClick={()=>go('jobs')} style={{marginBottom:20}}>
          <Icon name="arrowLeft" size={14}/> {t('forms.common.backTopJobs')}
        </button>
        <div style={{marginBottom:8}}>
          <div className="eyebrow">{t('forms.postJob.eyebrow')}</div>
          <h1 className="display" style={{fontSize:32, margin:'4px 0 0'}}>{t('forms.postJob.title')}</h1>
        </div>
        <StepHeader step={Math.min(step, 3)} total={4} titles={stepTitles} subtitle={
          step === 0 ? t('forms.postJob.sub0') :
          step === 1 ? t('forms.postJob.sub1') :
          step === 2 ? t('forms.postJob.sub2') :
          step === 3 ? t('forms.postJob.sub3') :
          t('forms.postJob.sub4')
        }/>

        <div className="card-flat" style={{padding:32}}>
          {/* Step title — flat header, matching the resume form layout (no
              gradient banner). */}
          <div style={{marginBottom:24}}>
            <div style={{fontSize:12, fontWeight:700, letterSpacing:'0.08em', textTransform:'uppercase', color:'var(--trust)', marginBottom:4}}>
              {step === 4 ? `${t('forms.common.stepOf', {n: 5, total: 5})} ${t('forms.common.stepFinal')}` : t('forms.common.stepOf', {n: Math.min(step,3)+1, total: 4})}
            </div>
            <h2 className="display" style={{fontSize:26, margin:0, lineHeight:1.2}}>
              {t('forms.postJob.stepHeads.' + step)}
            </h2>
          </div>

          <div>
          {/* ===== STEP 0: BASICS ===== */}
          {step === 0 && (
            <>
              <Field label={t('forms.postJob.s0.position')} required>
                <div style={{display:'flex', gap:14, flexWrap:'wrap'}}>
                  {[{id:'Domestic Helper', icon:'pos_helper'}, {id:'Driver', icon:'pos_driver'}].map(p => {
                    const active = form.position === p.id;
                    return (
                      <button
                        key={p.id}
                        type="button"
                        onClick={() => update('position', p.id)}
                        style={{
                          display:'flex', flexDirection:'column', alignItems:'center', justifyContent:'center',
                          gap:10, padding:'18px 24px', minWidth:170,
                          borderRadius:14,
                          border: `1.5px solid ${active ? 'var(--trust)' : 'var(--t-line)'}`,
                          background: active ? 'var(--trust-bg)' : 'var(--t-paper)',
                          color: active ? 'var(--trust-ink)' : 'var(--t-ink-soft)',
                          cursor:'pointer', fontFamily:'inherit',
                          transition:'all 0.15s',
                        }}
                      >
                        <window.FlatIcon name={p.icon} size={64}/>
                        <span style={{fontSize:14, fontWeight: active ? 600 : 500}}>{t('forms.enum.position.' + p.id)}</span>
                      </button>
                    );
                  })}
                </div>
              </Field>

              <Field label={t('forms.postJob.s0.jobType')} required>
                <ChipPicker options={['full-time','part-time','temporary'].map(id => ({id, label: t('forms.enum.jobType.' + id)}))} value={form.jobType} onChange={v => update('jobType', v)} multi={false}/>
              </Field>

              <Field label={t('forms.postJob.s0.location')} required>
                <div style={{display:'grid', gridTemplateColumns:'180px 1fr', gap:12}}>
                  <select className="select" value={form.market} onChange={e => update('market', e.target.value)}>
                    <option value="TW">{t('forms.enum.market.TW')}</option>
                    <option value="HK">{t('forms.enum.market.HK')}</option>
                    <option value="SG">{t('forms.enum.market.SG')}</option>
                  </select>
                  <select className="select" value={form.city} onChange={e => update('city', e.target.value)}>
                    <option value="">{t('forms.postJob.s0.selectCity')}</option>
                    {CITIES_BY_MARKET[form.market].map(c => <option key={c}>{c}</option>)}
                  </select>
                </div>
              </Field>

              <div style={{display:'grid', gridTemplateColumns:'280px 1fr', gap:24, alignItems:'flex-start'}}>
                <Field label={t('forms.postJob.s0.startDate')} required>
                  <input className="input" type="date" value={form.startDate} onChange={e => update('startDate', e.target.value)}/>
                </Field>
                <Field label={t('forms.postJob.s0.flexibility')}>
                  <FlexibilitySlider value={form.flexibility} onChange={v => update('flexibility', v)} t={t}/>
                </Field>
              </div>

              <hr className="divider" style={{margin:'24px 0'}}/>

              <div style={{fontSize:13, fontWeight:700, letterSpacing:'0.06em', textTransform:'uppercase', color:'var(--trust)', marginBottom:14}}>{t('forms.postJob.s0.household')}</div>

              <div style={{display:'grid', gridTemplateColumns:'1fr 1fr', gap:16}}>
                <Field label={t('forms.postJob.s0.adults')} icon="adults" required>
                  <div style={{display:'flex', alignItems:'center', gap:12}}>
                    <button type="button" onClick={() => update('familyAdults', Math.max(1, form.familyAdults - 1))} className="btn btn-outline btn-sm" style={{width:36, height:36, padding:0}}>–</button>
                    <div style={{minWidth:36, textAlign:'center', fontSize:18, fontWeight:600}}>{form.familyAdults}</div>
                    <button type="button" onClick={() => update('familyAdults', form.familyAdults + 1)} className="btn btn-outline btn-sm" style={{width:36, height:36, padding:0}}>+</button>
                  </div>
                </Field>
                <Field label={t('forms.postJob.s0.children')} icon="kids" required>
                  <div style={{display:'flex', alignItems:'center', gap:12}}>
                    <button type="button" onClick={() => update('familyKids', Math.max(0, form.familyKids - 1))} className="btn btn-outline btn-sm" style={{width:36, height:36, padding:0}}>–</button>
                    <div style={{minWidth:36, textAlign:'center', fontSize:18, fontWeight:600}}>{form.familyKids}</div>
                    <button type="button" onClick={() => update('familyKids', form.familyKids + 1)} className="btn btn-outline btn-sm" style={{width:36, height:36, padding:0}}>+</button>
                  </div>
                </Field>
                <Field label={t('forms.postJob.s0.elderly')} icon="elderly">
                  <Toggle checked={form.hasElderly} onChange={v => update('hasElderly', v)} ariaLabel={t('forms.postJob.s0.elderly')}/>
                </Field>
                <Field label={t('forms.postJob.s0.pets')} icon="pets_home">
                  <Toggle checked={form.hasPets} onChange={v => update('hasPets', v)} ariaLabel={t('forms.postJob.s0.pets')}/>
                </Field>
              </div>

              {form.familyKids > 0 && (
                <Field label={t('forms.postJob.s0.kidsAges')} icon="kids" hint={t('forms.postJob.s0.kidsAgesHint')}>
                  <input className="input" value={form.kidsAges} onChange={e => update('kidsAges', e.target.value)} placeholder={t('forms.postJob.s0.kidsAgesPlaceholder')}/>
                </Field>
              )}
            </>
          )}

          {/* ===== STEP 1: REQUIREMENTS ===== */}
          {step === 1 && (
            <>
              <Field label={t('forms.postJob.s1.languages')} icon="cat_language" required hint={t('forms.postJob.s1.languagesHint')}>
                <ChipPicker category="language" options={tax.languages} value={form.reqLanguages} onChange={v => update('reqLanguages', v)} showFlag/>
              </Field>
              <hr className="divider" style={{margin:'24px 0'}}/>
              <Field label={t('forms.postJob.s1.mainSkills')} icon="cat_main" required hint={t('forms.postJob.s1.mainSkillsHint')}>
                <ChipPicker category="main" options={tax.mainSkills.filter(s => s.label !== 'Marketing')} value={form.reqMainSkills} onChange={v => update('reqMainSkills', v)}/>
              </Field>
              <hr className="divider" style={{margin:'24px 0'}}/>
              <Field label={t('forms.postJob.s1.cookingCuisines')} icon="cat_cooking" hint={t('forms.postJob.s1.cookingCuisinesHint')}>
                <ChipPicker category="cooking" options={tax.cookingSkills} value={form.reqCookingSkills} onChange={v => update('reqCookingSkills', v)}/>
              </Field>
              <hr className="divider" style={{margin:'24px 0'}}/>
              <Field label={t('forms.postJob.s1.otherSkills')} icon="cat_other" hint={t('forms.postJob.s1.otherSkillsHint')}>
                <ChipPicker category="other" options={tax.otherSkills} value={form.reqOtherSkills} onChange={v => update('reqOtherSkills', v)}/>
              </Field>
            </>
          )}

          {/* ===== STEP 2: PREFERENCE AND OFFERINGS ===== */}
          {step === 2 && (
            <>
              {/* — Preference (private; sorts candidates) — */}
              <div style={{fontSize:13, fontWeight:700, letterSpacing:'0.06em', textTransform:'uppercase', color:'var(--trust)', marginBottom:10}}>{t('forms.postJob.s2.preferenceSection')}</div>
              <div style={{marginBottom:24, padding:14, background:'var(--trust-bg)', borderRadius:10, border:'1px solid var(--trust-line)', fontSize:13, color:'var(--t-ink-soft)', display:'flex', gap:10, alignItems:'flex-start'}}>
                <div style={{width:20, height:20, borderRadius:99, background:'var(--trust)', color:'white', display:'grid', placeItems:'center', fontSize:12, fontWeight:700, flexShrink:0, fontStyle:'italic', fontFamily:'Georgia, serif'}}>i</div>
                <div>{t('forms.postJob.s2.info')}</div>
              </div>

              <div style={{display:'grid', gridTemplateColumns:'1fr 1fr', gap:16}}>
                <Field label={t('forms.postJob.s2.gender')} icon="field_gender">
                  <ChipPicker options={['Any','Female','Male'].map(id => ({id, label: t('forms.enum.gender.' + id)}))} value={form.prefGender} onChange={v => update('prefGender', v)} multi={false}/>
                </Field>
                <Field label={t('forms.postJob.s2.contractStatus')} icon="field_contract">
                  <ChipPicker options={['Any','Available now','Contract ending soon','New to the industry'].map(id => ({id, label: t('forms.enum.empContractStatus.' + id)}))} value={form.prefContractStatus} onChange={v => update('prefContractStatus', v)} multi={false}/>
                </Field>
              </div>

              <Field label={t('forms.postJob.s2.prefNationality')} icon="field_id">
                <ChipPicker options={['Indonesia','Philippines','Myanmar','Vietnam','Thailand','India','Cambodia'].map(n => ({id:n, label: t('forms.enum.prefNationality.' + n)}))} value={form.prefNationalities} onChange={v => update('prefNationalities', v)}/>
              </Field>

              <div style={{display:'grid', gridTemplateColumns:'1fr 1fr', gap:16}}>
                <Field label={t('forms.postJob.s2.religion')} icon="field_religion">
                  <select className="select" value={form.prefReligion} onChange={e => update('prefReligion', e.target.value)}>
                    {['Any','Muslim','Christian','Catholic','Buddhist','Hindu','No preference'].map(r => (
                      <option key={r} value={r}>{t('forms.enum.religion.' + r)}</option>
                    ))}
                  </select>
                </Field>
                <Field label={t('forms.postJob.s2.education')} icon="field_education">
                  <select className="select" value={form.prefEducation} onChange={e => update('prefEducation', e.target.value)}>
                    {['Any','Elementary or higher','Junior High or higher','High School or higher','Diploma or higher',"Bachelor's or higher"].map(e => (
                      <option key={e} value={e}>{t('forms.enum.empEducation.' + e)}</option>
                    ))}
                  </select>
                </Field>
              </div>

              <Field label={t('forms.postJob.s2.ageRange')} icon="field_age" hint={t('forms.postJob.s2.ageRangeHint')}>
                <RangeSlider min={18} max={65} value={form.prefAgeRange} onChange={v => update('prefAgeRange', v)} unit={t('forms.postJob.s2.yrsUnit')}/>
              </Field>

              <Field label={t('forms.postJob.s2.expYears')} icon="field_experience" hint={t('forms.postJob.s2.expYearsHint')}>
                <RangeSlider min={0} max={25} value={form.prefExpYears} onChange={v => update('prefExpYears', v)} unit={t('forms.postJob.s2.yrsExpUnit')}/>
              </Field>

              <hr className="divider" style={{margin:'32px 0 24px'}}/>

              {/* — Offer (public; shown on the job page) — */}
              <div style={{fontSize:13, fontWeight:700, letterSpacing:'0.06em', textTransform:'uppercase', color:'var(--trust)', marginBottom:6}}>{t('forms.postJob.s2.offerSection')}</div>
              <p style={{fontSize:13, color:'var(--t-ink-muted)', marginBottom:18, lineHeight:1.55}}>{t('forms.postJob.s2.offerSectionHint')}</p>

              <Field label={t('forms.postJob.s0.monthlySalary')} icon="field_money" required>
                <div style={{display:'flex', gap:10, marginBottom:12}}>
                  <button type="button" onClick={() => update('salaryMode', 'range')} className="chip" style={{
                    padding:'8px 16px', borderRadius:99, fontSize:13, fontWeight:600, cursor:'pointer',
                    background: form.salaryMode === 'range' ? 'var(--trust)' : 'var(--t-paper)',
                    color: form.salaryMode === 'range' ? 'white' : 'var(--t-ink)',
                    border: `1px solid ${form.salaryMode === 'range' ? 'var(--trust)' : 'var(--t-line)'}`,
                  }}>{t('forms.enum.salaryMode.range')}</button>
                  <button type="button" onClick={() => update('salaryMode', 'tbd')} className="chip" style={{
                    padding:'8px 16px', borderRadius:99, fontSize:13, fontWeight:600, cursor:'pointer',
                    background: form.salaryMode === 'tbd' ? 'var(--trust)' : 'var(--t-paper)',
                    color: form.salaryMode === 'tbd' ? 'white' : 'var(--t-ink)',
                    border: `1px solid ${form.salaryMode === 'tbd' ? 'var(--trust)' : 'var(--t-line)'}`,
                  }}>{t('forms.enum.salaryMode.tbd')}</button>
                </div>
                {form.salaryMode === 'range' && (
                  <div style={{display:'grid', gridTemplateColumns:'100px 1fr 20px 1fr', gap:10, alignItems:'center'}}>
                    <select className="select" value={form.salaryCurrency} onChange={e => update('salaryCurrency', e.target.value)}>
                      <option>NT$</option><option>HK$</option><option>S$</option>
                    </select>
                    <input className="input" type="number" value={form.salaryMin} onChange={e => update('salaryMin', e.target.value)} placeholder={t('forms.postJob.s0.rangeMin')}/>
                    <div style={{textAlign:'center', color:'var(--t-ink-muted)'}}>–</div>
                    <input className="input" type="number" value={form.salaryMax} onChange={e => update('salaryMax', e.target.value)} placeholder={t('forms.postJob.s0.rangeMax')}/>
                  </div>
                )}
              </Field>

              <div style={{display:'grid', gridTemplateColumns:'1fr 1fr', gap:16}}>
                <Field label={t('forms.postJob.s2.dayOff')} icon="dayoff" required>
                  <select className="select" value={form.jobDayOff} onChange={e => update('jobDayOff', e.target.value)}>
                    {['Flexible','To be discussed','Monday','Tuesday','Wednesday','Thursday','Friday','Saturday','Sunday'].map(d => (
                      <option key={d} value={d}>{t('forms.enum.dayOff.' + d)}</option>
                    ))}
                  </select>
                </Field>
                <Field label={t('forms.postJob.s2.jobAccommodation')} icon="field_accommodation" required>
                  <select className="select" value={form.jobAccommodation} onChange={e => update('jobAccommodation', e.target.value)}>
                    {['Dont mention','Live-in - separate room','Live-in - share with kid','Live-in - share with co-worker','Live-out'].map(a => (
                      <option key={a} value={a}>{t('forms.enum.jobAccommodation.' + a)}</option>
                    ))}
                  </select>
                </Field>
              </div>
            </>
          )}

          {/* ===== STEP 3: ABOUT THE JOB ===== */}
          {step === 3 && (
            <>
              <Field label={t('forms.postJob.s0.jobTitle')} icon="field_briefcase" required hint={t('forms.postJob.s0.jobTitleHint')}>
                <input className="input" value={form.title} onChange={e => update('title', e.target.value)} placeholder={t('forms.postJob.s0.jobTitlePlaceholder')}/>
              </Field>
              <Field label={t('forms.postJob.s3.about')} icon="field_bio" required hint={t('forms.postJob.s3.aboutHint')}>
                <RichTextEditor value={form.description} onChange={v => update('description', v)} placeholder={t('forms.postJob.s3.aboutPlaceholder')}/>
              </Field>
            </>
          )}

          {/* ===== STEP 4: REVIEW ===== */}
          {step === 4 && (
            <>
              <div style={{marginBottom:20, padding:14, background:'var(--t-paper)', borderRadius:10, border:'1px solid var(--t-line)', fontSize:13, color:'var(--t-ink-soft)'}}>
                {t('forms.postJob.s4.intro')}
              </div>

              <ReviewSection title={t('forms.postJob.s4.basics')} onEdit={() => setStep(0)}>
                <div style={{display:'grid', gridTemplateColumns:'1fr 1fr', gap:'14px 24px'}}>
                  <Summary label={t('forms.postJob.s4.summary.title')} value={form.title}/>
                  <Summary label={t('forms.postJob.s4.summary.position')} value={form.position ? t('forms.enum.position.' + form.position) : ''}/>
                  <Summary label={t('forms.postJob.s4.summary.jobType')} value={form.jobType ? t('forms.enum.jobType.' + form.jobType) : ''}/>
                  <Summary label={t('forms.postJob.s4.summary.location')} value={[form.city, form.market].filter(Boolean).join(', ')}/>
                  <Summary label={t('forms.postJob.s4.summary.startDate')} value={form.startDate}/>
                  <Summary label={t('forms.postJob.s4.summary.salary')} value={
                    form.salaryMode === 'tbd' ? t('forms.postJob.s4.summary.salaryTbd')
                    : (form.salaryMin && form.salaryMax) ? t('forms.postJob.s4.summary.salaryRange', {cur: form.salaryCurrency, min: Number(form.salaryMin).toLocaleString(), max: Number(form.salaryMax).toLocaleString()}) : ''
                  }/>
                  <Summary label={t('forms.postJob.s4.summary.household')} value={
                    t(form.familyAdults === 1 ? 'forms.postJob.s4.householdAdults.one' : 'forms.postJob.s4.householdAdults.many', {n: form.familyAdults})
                    + (form.familyKids > 0 ? t(form.familyKids === 1 ? 'forms.postJob.s4.householdKids.one' : 'forms.postJob.s4.householdKids.many', {n: form.familyKids}) : '')
                    + (form.hasElderly ? t('forms.postJob.s4.householdElderly') : '')
                    + (form.hasPets ? t('forms.postJob.s4.householdPets') : '')
                  }/>
                  {form.kidsAges && <Summary label={t('forms.postJob.s4.summary.kidsAges')} value={form.kidsAges}/>}
                </div>
              </ReviewSection>

              <ReviewSection title={t('forms.postJob.s4.requirements')} onEdit={() => setStep(1)}>
                <SummaryChips label={t('forms.postJob.s4.summary.languages')} items={tax.languages.filter(x => form.reqLanguages.includes(x.id)).map(x => window.pickLocalised(x, 'label') || x.label)}/>
                <SummaryChips label={t('forms.postJob.s4.summary.mainSkills')} items={tax.mainSkills.filter(x => form.reqMainSkills.includes(x.id)).map(x => window.pickLocalised(x, 'label') || x.label)}/>
                <SummaryChips label={t('forms.postJob.s4.summary.cookingCuisines')} items={tax.cookingSkills.filter(x => form.reqCookingSkills.includes(x.id)).map(x => window.pickLocalised(x, 'label') || x.label)}/>
                <SummaryChips label={t('forms.postJob.s4.summary.otherSkills')} items={tax.otherSkills.filter(x => form.reqOtherSkills.includes(x.id)).map(x => window.pickLocalised(x, 'label') || x.label)}/>
              </ReviewSection>

              <ReviewSection title={t('forms.postJob.s4.preferencesPrivate')} onEdit={() => setStep(2)}>
                <div style={{display:'grid', gridTemplateColumns:'1fr 1fr', gap:'14px 24px', marginBottom:16}}>
                  <Summary label={t('forms.postJob.s4.summary.gender')} value={form.prefGender ? t('forms.enum.gender.' + form.prefGender) : ''}/>
                  <Summary label={t('forms.postJob.s4.summary.contractStatus')} value={form.prefContractStatus ? t('forms.enum.empContractStatus.' + form.prefContractStatus) : ''}/>
                  <Summary label={t('forms.postJob.s4.summary.religion')} value={form.prefReligion ? t('forms.enum.religion.' + form.prefReligion) : ''}/>
                  <Summary label={t('forms.postJob.s4.summary.education')} value={form.prefEducation ? t('forms.enum.empEducation.' + form.prefEducation) : ''}/>
                  <Summary label={t('forms.postJob.s4.summary.ageRange')} value={t('forms.postJob.s4.summary.ageRangeValue', {from: form.prefAgeRange[0], to: form.prefAgeRange[1]})}/>
                  <Summary label={t('forms.postJob.s4.summary.experience')} value={t('forms.postJob.s4.summary.experienceValue', {from: form.prefExpYears[0], to: form.prefExpYears[1]})}/>
                </div>
                <SummaryChips label={t('forms.postJob.s4.summary.prefNationality')} items={form.prefNationalities.map(n => t('forms.enum.prefNationality.' + n))}/>
              </ReviewSection>

              <ReviewSection title={t('forms.postJob.s4.aboutSection')} onEdit={() => setStep(3)} last>
                <div
                  style={{fontSize:14.5, lineHeight:1.7, color:'var(--t-ink)'}}
                  dangerouslySetInnerHTML={{__html: form.description || `<p style="color:var(--t-ink-muted)">${t('forms.common.notProvided')}</p>`}}
                />
              </ReviewSection>
            </>
          )}

          <div style={{display:'flex', justifyContent:'space-between', gap:12, marginTop:28, paddingTop:24, borderTop:'1px solid var(--t-line)'}}>
            <button className="btn btn-ghost" onClick={() => { if (step === 0) { go('jobs'); } else { setStep(step-1); window.scrollTo(0, 0); } }}>
              {step === 0 ? t('forms.common.cancel') : t('forms.common.back')}
            </button>
            {step < 4 ? (
              <button className="btn btn-primary" disabled={!canContinue()} onClick={() => { setStep(step+1); window.scrollTo(0, 0); }} style={{opacity: canContinue() ? 1 : 0.5}}>
                {step === 3 ? t('forms.common.review') : t('forms.common.continue')}
              </button>
            ) : (
              <button className="btn btn-primary" onClick={publishClick}>{t('forms.postJob.publishBtn')}</button>
            )}
          </div>
          </div>
        </div>
      </div>

      {showPublish && (
        <PublishJobModal form={form} loggedIn={loggedIn} onClose={() => setShowPublish(false)} onDone={() => { setShowPublish(false); go('dashboard'); }}/>
      )}
    </div>
  );
};

// Small collapsible review card
const ReviewSection = ({ title, onEdit, last, children }) => {
  const { t } = window.useI18n();
  return (
    <div style={{marginBottom: last ? 0 : 20, paddingBottom: last ? 0 : 20, borderBottom: last ? 'none' : '1px solid var(--t-line)'}}>
      <div style={{display:'flex', justifyContent:'space-between', alignItems:'center', marginBottom:14}}>
        <div style={{fontSize:12, fontWeight:700, letterSpacing:'0.06em', textTransform:'uppercase', color:'var(--t-ink-muted)'}}>{title}</div>
        <button type="button" className="btn btn-ghost btn-sm" onClick={onEdit} style={{color:'var(--trust)', fontWeight:600}}>{t('forms.common.edit')}</button>
      </div>
      {children}
    </div>
  );
};

// ===== Publish modal — pricing + payment =====
const PublishJobModal = ({ form, loggedIn, onClose, onDone }) => {
  const { t } = window.useI18n();
  const [plan, setPlan] = useState('standard');
  const [view, setView] = useState(loggedIn ? 'pay' : 'signup');  // signup → pay → success
  const [email, setEmail] = useState('');
  const [password, setPassword] = useState('');
  const [cardNum, setCardNum] = useState('');
  const [cardName, setCardName] = useState('');
  const [cardExpiry, setCardExpiry] = useState('');
  const [cardCvc, setCardCvc] = useState('');

  const planBullets = (key) => {
    // Read array from packs via lookup. Fallback to English defaults if absent.
    const fallback = {
      basic:    ['1 active job', 'Up to 3 shortlists', 'Unlimited browsing'],
      standard: ['3 active jobs', 'Up to 15 shortlists', 'Priority listing', 'Chat with helpers'],
      premium:  ['Unlimited jobs', 'Unlimited shortlists', 'Featured listing', 'Video interviews', 'Dedicated support'],
    };
    const arr = window.i18n.labels(`forms.postJob.publish.plans.bullets.${key}`);
    return Array.isArray(arr) || (arr && typeof arr === 'object' && Object.keys(arr).length) ? Object.values(arr) : fallback[key];
  };
  const plans = [
    { id:'basic',    name: t('forms.postJob.publish.plans.basic.name'),    price: t('forms.postJob.publish.plans.basic.price'),    sub: t('forms.postJob.publish.plans.basic.sub'),    bullets: planBullets('basic'),    cta: t('forms.postJob.publish.plans.basic.cta') },
    { id:'standard', name: t('forms.postJob.publish.plans.standard.name'), price: t('forms.postJob.publish.plans.standard.price'), sub: t('forms.postJob.publish.plans.standard.sub'), bullets: planBullets('standard'), best:true, cta: t('forms.postJob.publish.plans.standard.cta') },
    { id:'premium',  name: t('forms.postJob.publish.plans.premium.name'),  price: t('forms.postJob.publish.plans.premium.price'),  sub: t('forms.postJob.publish.plans.premium.sub'),  bullets: planBullets('premium'),  cta: t('forms.postJob.publish.plans.premium.cta') },
  ];
  const selected = plans.find(p => p.id === plan);

  return (
    <div style={{
      position:'fixed', inset:0, background:'rgba(30,25,20,0.5)',
      display:'grid', placeItems:'center', zIndex:1000, padding:20,
    }} onClick={onClose}>
      <div style={{
        background:'white', borderRadius:16, maxWidth:720, width:'100%', maxHeight:'90vh',
        overflow:'auto', boxShadow:'0 20px 60px rgba(0,0,0,0.3)',
      }} onClick={e => e.stopPropagation()}>
        <div style={{padding:'24px 28px', borderBottom:'1px solid var(--t-line)', display:'flex', justifyContent:'space-between', alignItems:'center'}}>
          <div>
            <div className="eyebrow" style={{fontSize:11, color:'var(--trust)'}}>{t('forms.postJob.publish.eyebrow')}</div>
            <h2 style={{fontSize:20, fontWeight:600, margin:'4px 0 0'}}>
              {view === 'signup' ? t('forms.postJob.publish.createAccount') : view === 'pay' ? t('forms.postJob.publish.choosePlan') : t('forms.postJob.publish.payment')}
            </h2>
          </div>
          <button onClick={onClose} style={{background:'none', border:'none', cursor:'pointer', color:'var(--t-ink-muted)', padding:6}}><Icon name="x" size={18}/></button>
        </div>

        <div style={{padding:28}}>
          {view === 'signup' && (
            <>
              <div style={{marginBottom:20, padding:14, background:'var(--trust-bg)', borderRadius:10, fontSize:13, color:'var(--t-ink-soft)'}}>
                {t('forms.postJob.publish.signupNote')}
              </div>
              <Field label={t('forms.postJob.publish.email')} required>
                <input className="input" type="email" value={email} onChange={e => setEmail(e.target.value)} placeholder={t('forms.postJob.publish.emailPlaceholder')}/>
              </Field>
              <Field label={t('forms.postJob.publish.password')} required>
                <input className="input" type="password" value={password} onChange={e => setPassword(e.target.value)} placeholder={t('forms.postJob.publish.passwordPlaceholder')}/>
              </Field>
              <button className="btn btn-primary" style={{width:'100%'}} onClick={() => setView('pay')} disabled={!email || !password}>
                {t('forms.postJob.publish.createAccountCta')}
              </button>
              <div style={{textAlign:'center', marginTop:14, fontSize:13, color:'var(--t-ink-muted)'}}>
                {t('forms.postJob.publish.alreadyHave')} <a href="#" onClick={e => { e.preventDefault(); setView('pay'); }} style={{color:'var(--trust)', fontWeight:600}}>{t('forms.postJob.publish.signIn')}</a>
              </div>
            </>
          )}

          {view === 'pay' && (
            <>
              <div style={{display:'grid', gridTemplateColumns:'repeat(3,1fr)', gap:12, marginBottom:24}}>
                {plans.map(p => (
                  <button key={p.id} type="button" onClick={() => setPlan(p.id)} style={{
                    padding:18, borderRadius:12, textAlign:'left', cursor:'pointer',
                    background: plan === p.id ? 'var(--trust-bg)' : 'var(--t-paper)',
                    border: plan === p.id ? '2px solid var(--trust)' : '1px solid var(--t-line)',
                    position:'relative',
                  }}>
                    {p.best && <div style={{position:'absolute', top:-10, right:12, fontSize:10, fontWeight:700, color:'white', background:'var(--coral)', padding:'3px 8px', borderRadius:99, letterSpacing:'0.04em'}}>{t('forms.postJob.publish.bestValue')}</div>}
                    <div style={{fontWeight:700, fontSize:15, marginBottom:6}}>{p.name}</div>
                    <div style={{fontSize:22, fontWeight:700, color:'var(--trust)'}}>{p.price}<span style={{fontSize:12, color:'var(--t-ink-muted)', fontWeight:500}}> {p.sub}</span></div>
                    <ul style={{margin:'12px 0 0', padding:0, listStyle:'none', fontSize:12, color:'var(--t-ink-soft)'}}>
                      {p.bullets.map((b,i) => (
                        <li key={i} style={{display:'flex', gap:6, padding:'3px 0'}}>
                          <Icon name="check" size={11}/> {b}
                        </li>
                      ))}
                    </ul>
                  </button>
                ))}
              </div>
              <button className="btn btn-primary" style={{width:'100%'}} onClick={() => setView('card')}>{t('forms.postJob.publish.continueWith', {plan: selected.name, price: selected.price})}</button>
            </>
          )}

          {view === 'card' && (
            <>
              <div style={{marginBottom:20, padding:14, background:'var(--t-paper)', borderRadius:10, display:'flex', justifyContent:'space-between', alignItems:'center', fontSize:14}}>
                <span style={{color:'var(--t-ink-soft)'}}>{t('forms.postJob.publish.planLabel')} <strong>{selected.name}</strong></span>
                <span style={{fontWeight:600}}>{selected.price}{selected.sub}</span>
              </div>
              <Field label={t('forms.postJob.publish.cardNumber')} required>
                <input className="input" value={cardNum} onChange={e => setCardNum(e.target.value)} placeholder="4242 4242 4242 4242"/>
              </Field>
              <Field label={t('forms.postJob.publish.cardName')} required>
                <input className="input" value={cardName} onChange={e => setCardName(e.target.value)} placeholder="Jane Doe"/>
              </Field>
              <div style={{display:'grid', gridTemplateColumns:'1fr 1fr', gap:12}}>
                <Field label={t('forms.postJob.publish.expiry')} required>
                  <input className="input" value={cardExpiry} onChange={e => setCardExpiry(e.target.value)} placeholder="MM/YY"/>
                </Field>
                <Field label={t('forms.postJob.publish.cvc')} required>
                  <input className="input" value={cardCvc} onChange={e => setCardCvc(e.target.value)} placeholder="123"/>
                </Field>
              </div>
              <button className="btn btn-primary" style={{width:'100%', marginTop:8}} onClick={() => setView('success')}>
                {t('forms.postJob.publish.payAndPublish', {price: selected.price})}
              </button>
              <div style={{textAlign:'center', marginTop:14, fontSize:12, color:'var(--t-ink-muted)', display:'flex', justifyContent:'center', alignItems:'center', gap:6}}>
                <Icon name="shield" size={12}/> {t('forms.postJob.publish.stripeNote')}
              </div>
            </>
          )}

          {view === 'success' && (
            <div style={{textAlign:'center', padding:'20px 0'}}>
              <div style={{width:72, height:72, borderRadius:99, background:'var(--trust-bg)', color:'var(--trust)', display:'grid', placeItems:'center', margin:'0 auto 16px'}}>
                <Icon name="check" size={32}/>
              </div>
              <h3 style={{fontSize:22, fontWeight:600, marginBottom:8}}>{t('forms.postJob.publish.successTitle')}</h3>
              <p style={{color:'var(--t-ink-soft)', fontSize:14, lineHeight:1.55, marginBottom:20}}>{t('forms.postJob.publish.successBody')}</p>
              <button className="btn btn-primary" onClick={onDone}>{t('forms.postJob.publish.gotoDashboard')}</button>
            </div>
          )}
        </div>
      </div>
    </div>
  );
};

const Summary = ({ label, value }) => (
  <div>
    <div style={{fontSize:11, fontWeight:700, letterSpacing:'0.06em', textTransform:'uppercase', color:'var(--t-ink-muted)', marginBottom:4}}>{label}</div>
    <div style={{fontSize:14, fontWeight:500, color:'var(--t-ink)'}}>{value || <span style={{color:'var(--t-ink-muted)'}}>—</span>}</div>
  </div>
);

const SummaryChips = ({ label, items }) => {
  if (!items || items.length === 0) return null;
  return (
    <div style={{marginBottom:16}}>
      <div style={{fontSize:11, fontWeight:700, letterSpacing:'0.06em', textTransform:'uppercase', color:'var(--t-ink-muted)', marginBottom:8}}>{label}</div>
      <div style={{display:'flex', flexWrap:'wrap', gap:6}}>
        {items.map((x,i) => <span key={i} className="chip chip-ghost" style={{fontSize:12}}>{x}</span>)}
      </div>
    </div>
  );
};

// =====================================================================
// CREATE PROFILE (helper) — 6-step wizard
// =====================================================================

// ISO 3166 short list — common nationalities families hire from / families live in
const ALL_COUNTRIES = [
  'Afghanistan','Albania','Algeria','Andorra','Angola','Argentina','Armenia','Australia','Austria','Azerbaijan',
  'Bahamas','Bahrain','Bangladesh','Belarus','Belgium','Belize','Benin','Bhutan','Bolivia','Bosnia and Herzegovina',
  'Botswana','Brazil','Brunei','Bulgaria','Burkina Faso','Burundi','Cambodia','Cameroon','Canada','Cape Verde',
  'Central African Republic','Chad','Chile','China','Colombia','Comoros','Congo','Costa Rica','Croatia','Cuba',
  'Cyprus','Czechia','Denmark','Djibouti','Dominican Republic','Ecuador','Egypt','El Salvador','Eritrea','Estonia',
  'Eswatini','Ethiopia','Fiji','Finland','France','Gabon','Gambia','Georgia','Germany','Ghana',
  'Greece','Guatemala','Guinea','Guyana','Haiti','Honduras','Hong Kong','Hungary','Iceland','India',
  'Indonesia','Iran','Iraq','Ireland','Israel','Italy','Jamaica','Japan','Jordan','Kazakhstan',
  'Kenya','Kuwait','Kyrgyzstan','Laos','Latvia','Lebanon','Lesotho','Liberia','Libya','Lithuania',
  'Luxembourg','Madagascar','Malawi','Malaysia','Maldives','Mali','Malta','Mauritania','Mauritius','Mexico',
  'Moldova','Monaco','Mongolia','Montenegro','Morocco','Mozambique','Myanmar','Namibia','Nepal','Netherlands',
  'New Zealand','Nicaragua','Niger','Nigeria','North Korea','North Macedonia','Norway','Oman','Pakistan','Palestine',
  'Panama','Papua New Guinea','Paraguay','Peru','Philippines','Poland','Portugal','Qatar','Romania','Russia',
  'Rwanda','Saudi Arabia','Senegal','Serbia','Singapore','Slovakia','Slovenia','Somalia','South Africa','South Korea',
  'Spain','Sri Lanka','Sudan','Suriname','Sweden','Switzerland','Syria','Taiwan','Tajikistan','Tanzania',
  'Thailand','Timor-Leste','Togo','Tonga','Trinidad and Tobago','Tunisia','Turkey','Turkmenistan','Uganda','Ukraine',
  'United Arab Emirates','United Kingdom','United States','Uruguay','Uzbekistan','Venezuela','Vietnam','Yemen','Zambia','Zimbabwe',
];

// International dial codes (compact — common markets for this audience)
const DIAL_CODES = [
  {cc:'+93', flag:'🇦🇫', name:'Afghanistan'}, {cc:'+355', flag:'🇦🇱', name:'Albania'},
  {cc:'+213', flag:'🇩🇿', name:'Algeria'}, {cc:'+376', flag:'🇦🇩', name:'Andorra'},
  {cc:'+244', flag:'🇦🇴', name:'Angola'}, {cc:'+54', flag:'🇦🇷', name:'Argentina'},
  {cc:'+374', flag:'🇦🇲', name:'Armenia'}, {cc:'+61', flag:'🇦🇺', name:'Australia'},
  {cc:'+43', flag:'🇦🇹', name:'Austria'}, {cc:'+994', flag:'🇦🇿', name:'Azerbaijan'},
  {cc:'+973', flag:'🇧🇭', name:'Bahrain'}, {cc:'+880', flag:'🇧🇩', name:'Bangladesh'},
  {cc:'+375', flag:'🇧🇾', name:'Belarus'}, {cc:'+32', flag:'🇧🇪', name:'Belgium'},
  {cc:'+501', flag:'🇧🇿', name:'Belize'}, {cc:'+229', flag:'🇧🇯', name:'Benin'},
  {cc:'+975', flag:'🇧🇹', name:'Bhutan'}, {cc:'+591', flag:'🇧🇴', name:'Bolivia'},
  {cc:'+387', flag:'🇧🇦', name:'Bosnia and Herzegovina'}, {cc:'+267', flag:'🇧🇼', name:'Botswana'},
  {cc:'+55', flag:'🇧🇷', name:'Brazil'}, {cc:'+673', flag:'🇧🇳', name:'Brunei'},
  {cc:'+359', flag:'🇧🇬', name:'Bulgaria'}, {cc:'+226', flag:'🇧🇫', name:'Burkina Faso'},
  {cc:'+257', flag:'🇧🇮', name:'Burundi'}, {cc:'+855', flag:'🇰🇭', name:'Cambodia'},
  {cc:'+237', flag:'🇨🇲', name:'Cameroon'}, {cc:'+1', flag:'🇨🇦', name:'Canada'},
  {cc:'+238', flag:'🇨🇻', name:'Cape Verde'}, {cc:'+236', flag:'🇨🇫', name:'Central African Republic'},
  {cc:'+235', flag:'🇹🇩', name:'Chad'}, {cc:'+56', flag:'🇨🇱', name:'Chile'},
  {cc:'+86', flag:'🇨🇳', name:'China'}, {cc:'+57', flag:'🇨🇴', name:'Colombia'},
  {cc:'+269', flag:'🇰🇲', name:'Comoros'}, {cc:'+242', flag:'🇨🇬', name:'Congo'},
  {cc:'+243', flag:'🇨🇩', name:'Congo (DRC)'}, {cc:'+506', flag:'🇨🇷', name:'Costa Rica'},
  {cc:'+225', flag:'🇨🇮', name:'Côte d\'Ivoire'}, {cc:'+385', flag:'🇭🇷', name:'Croatia'},
  {cc:'+53', flag:'🇨🇺', name:'Cuba'}, {cc:'+357', flag:'🇨🇾', name:'Cyprus'},
  {cc:'+420', flag:'🇨🇿', name:'Czech Republic'}, {cc:'+45', flag:'🇩🇰', name:'Denmark'},
  {cc:'+253', flag:'🇩🇯', name:'Djibouti'}, {cc:'+670', flag:'🇹🇱', name:'East Timor'},
  {cc:'+593', flag:'🇪🇨', name:'Ecuador'}, {cc:'+20', flag:'🇪🇬', name:'Egypt'},
  {cc:'+503', flag:'🇸🇻', name:'El Salvador'}, {cc:'+240', flag:'🇬🇶', name:'Equatorial Guinea'},
  {cc:'+291', flag:'🇪🇷', name:'Eritrea'}, {cc:'+372', flag:'🇪🇪', name:'Estonia'},
  {cc:'+251', flag:'🇪🇹', name:'Ethiopia'}, {cc:'+679', flag:'🇫🇯', name:'Fiji'},
  {cc:'+358', flag:'🇫🇮', name:'Finland'}, {cc:'+33', flag:'🇫🇷', name:'France'},
  {cc:'+241', flag:'🇬🇦', name:'Gabon'}, {cc:'+220', flag:'🇬🇲', name:'Gambia'},
  {cc:'+995', flag:'🇬🇪', name:'Georgia'}, {cc:'+49', flag:'🇩🇪', name:'Germany'},
  {cc:'+233', flag:'🇬🇭', name:'Ghana'}, {cc:'+30', flag:'🇬🇷', name:'Greece'},
  {cc:'+502', flag:'🇬🇹', name:'Guatemala'}, {cc:'+224', flag:'🇬🇳', name:'Guinea'},
  {cc:'+592', flag:'🇬🇾', name:'Guyana'}, {cc:'+509', flag:'🇭🇹', name:'Haiti'},
  {cc:'+504', flag:'🇭🇳', name:'Honduras'}, {cc:'+852', flag:'🇭🇰', name:'Hong Kong'},
  {cc:'+36', flag:'🇭🇺', name:'Hungary'}, {cc:'+354', flag:'🇮🇸', name:'Iceland'},
  {cc:'+91', flag:'🇮🇳', name:'India'}, {cc:'+62', flag:'🇮🇩', name:'Indonesia'},
  {cc:'+98', flag:'🇮🇷', name:'Iran'}, {cc:'+964', flag:'🇮🇶', name:'Iraq'},
  {cc:'+353', flag:'🇮🇪', name:'Ireland'}, {cc:'+972', flag:'🇮🇱', name:'Israel'},
  {cc:'+39', flag:'🇮🇹', name:'Italy'}, {cc:'+1876', flag:'🇯🇲', name:'Jamaica'},
  {cc:'+81', flag:'🇯🇵', name:'Japan'}, {cc:'+962', flag:'🇯🇴', name:'Jordan'},
  {cc:'+7', flag:'🇰🇿', name:'Kazakhstan'}, {cc:'+254', flag:'🇰🇪', name:'Kenya'},
  {cc:'+965', flag:'🇰🇼', name:'Kuwait'}, {cc:'+996', flag:'🇰🇬', name:'Kyrgyzstan'},
  {cc:'+856', flag:'🇱🇦', name:'Laos'}, {cc:'+371', flag:'🇱🇻', name:'Latvia'},
  {cc:'+961', flag:'🇱🇧', name:'Lebanon'}, {cc:'+266', flag:'🇱🇸', name:'Lesotho'},
  {cc:'+231', flag:'🇱🇷', name:'Liberia'}, {cc:'+218', flag:'🇱🇾', name:'Libya'},
  {cc:'+370', flag:'🇱🇹', name:'Lithuania'}, {cc:'+352', flag:'🇱🇺', name:'Luxembourg'},
  {cc:'+853', flag:'🇲🇴', name:'Macau'}, {cc:'+389', flag:'🇲🇰', name:'Macedonia'},
  {cc:'+261', flag:'🇲🇬', name:'Madagascar'}, {cc:'+265', flag:'🇲🇼', name:'Malawi'},
  {cc:'+60', flag:'🇲🇾', name:'Malaysia'}, {cc:'+960', flag:'🇲🇻', name:'Maldives'},
  {cc:'+223', flag:'🇲🇱', name:'Mali'}, {cc:'+356', flag:'🇲🇹', name:'Malta'},
  {cc:'+222', flag:'🇲🇷', name:'Mauritania'}, {cc:'+230', flag:'🇲🇺', name:'Mauritius'},
  {cc:'+52', flag:'🇲🇽', name:'Mexico'}, {cc:'+373', flag:'🇲🇩', name:'Moldova'},
  {cc:'+377', flag:'🇲🇨', name:'Monaco'}, {cc:'+976', flag:'🇲🇳', name:'Mongolia'},
  {cc:'+382', flag:'🇲🇪', name:'Montenegro'}, {cc:'+212', flag:'🇲🇦', name:'Morocco'},
  {cc:'+258', flag:'🇲🇿', name:'Mozambique'}, {cc:'+95', flag:'🇲🇲', name:'Myanmar'},
  {cc:'+264', flag:'🇳🇦', name:'Namibia'}, {cc:'+977', flag:'🇳🇵', name:'Nepal'},
  {cc:'+31', flag:'🇳🇱', name:'Netherlands'}, {cc:'+64', flag:'🇳🇿', name:'New Zealand'},
  {cc:'+505', flag:'🇳🇮', name:'Nicaragua'}, {cc:'+227', flag:'🇳🇪', name:'Niger'},
  {cc:'+234', flag:'🇳🇬', name:'Nigeria'}, {cc:'+850', flag:'🇰🇵', name:'North Korea'},
  {cc:'+47', flag:'🇳🇴', name:'Norway'}, {cc:'+968', flag:'🇴🇲', name:'Oman'},
  {cc:'+92', flag:'🇵🇰', name:'Pakistan'}, {cc:'+970', flag:'🇵🇸', name:'Palestine'},
  {cc:'+507', flag:'🇵🇦', name:'Panama'}, {cc:'+675', flag:'🇵🇬', name:'Papua New Guinea'},
  {cc:'+595', flag:'🇵🇾', name:'Paraguay'}, {cc:'+51', flag:'🇵🇪', name:'Peru'},
  {cc:'+63', flag:'🇵🇭', name:'Philippines'}, {cc:'+48', flag:'🇵🇱', name:'Poland'},
  {cc:'+351', flag:'🇵🇹', name:'Portugal'}, {cc:'+974', flag:'🇶🇦', name:'Qatar'},
  {cc:'+40', flag:'🇷🇴', name:'Romania'}, {cc:'+7', flag:'🇷🇺', name:'Russia'},
  {cc:'+250', flag:'🇷🇼', name:'Rwanda'}, {cc:'+966', flag:'🇸🇦', name:'Saudi Arabia'},
  {cc:'+221', flag:'🇸🇳', name:'Senegal'}, {cc:'+381', flag:'🇷🇸', name:'Serbia'},
  {cc:'+232', flag:'🇸🇱', name:'Sierra Leone'}, {cc:'+65', flag:'🇸🇬', name:'Singapore'},
  {cc:'+421', flag:'🇸🇰', name:'Slovakia'}, {cc:'+386', flag:'🇸🇮', name:'Slovenia'},
  {cc:'+252', flag:'🇸🇴', name:'Somalia'}, {cc:'+27', flag:'🇿🇦', name:'South Africa'},
  {cc:'+82', flag:'🇰🇷', name:'South Korea'}, {cc:'+211', flag:'🇸🇸', name:'South Sudan'},
  {cc:'+34', flag:'🇪🇸', name:'Spain'}, {cc:'+94', flag:'🇱🇰', name:'Sri Lanka'},
  {cc:'+249', flag:'🇸🇩', name:'Sudan'}, {cc:'+597', flag:'🇸🇷', name:'Suriname'},
  {cc:'+268', flag:'🇸🇿', name:'Swaziland'}, {cc:'+46', flag:'🇸🇪', name:'Sweden'},
  {cc:'+41', flag:'🇨🇭', name:'Switzerland'}, {cc:'+963', flag:'🇸🇾', name:'Syria'},
  {cc:'+886', flag:'🇹🇼', name:'Taiwan'}, {cc:'+992', flag:'🇹🇯', name:'Tajikistan'},
  {cc:'+255', flag:'🇹🇿', name:'Tanzania'}, {cc:'+66', flag:'🇹🇭', name:'Thailand'},
  {cc:'+228', flag:'🇹🇬', name:'Togo'}, {cc:'+216', flag:'🇹🇳', name:'Tunisia'},
  {cc:'+90', flag:'🇹🇷', name:'Turkey'}, {cc:'+993', flag:'🇹🇲', name:'Turkmenistan'},
  {cc:'+256', flag:'🇺🇬', name:'Uganda'}, {cc:'+380', flag:'🇺🇦', name:'Ukraine'},
  {cc:'+971', flag:'🇦🇪', name:'United Arab Emirates'}, {cc:'+44', flag:'🇬🇧', name:'United Kingdom'},
  {cc:'+1', flag:'🇺🇸', name:'United States'}, {cc:'+598', flag:'🇺🇾', name:'Uruguay'},
  {cc:'+998', flag:'🇺🇿', name:'Uzbekistan'}, {cc:'+58', flag:'🇻🇪', name:'Venezuela'},
  {cc:'+84', flag:'🇻🇳', name:'Vietnam'}, {cc:'+967', flag:'🇾🇪', name:'Yemen'},
  {cc:'+260', flag:'🇿🇲', name:'Zambia'}, {cc:'+263', flag:'🇿🇼', name:'Zimbabwe'},
];

// Flag emoji by country name, derived from DIAL_CODES so the country dropdown
// in resume step 0 (Current location) can show flags without a separate table.
const FLAG_BY_COUNTRY = DIAL_CODES.reduce((m, d) => { m[d.name] = d.flag; return m; }, {});

// ---- Photo upload with quality heuristic ----
const PhotoUpload = ({ photo, onChange }) => {
  const { t } = window.useI18n();
  const fileRef = React.useRef(null);
  const [checking, setChecking] = React.useState(false);
  const [issues, setIssues] = React.useState([]);

  const analyse = (dataUrl) => {
    setChecking(true);
    const img = new Image();
    img.onload = () => {
      const problems = [];
      if (img.width < 400 || img.height < 400) problems.push(t('forms.photo.issues.lowRes'));
      const ratio = img.width / img.height;
      if (ratio > 1.6 || ratio < 0.5) problems.push(t('forms.photo.issues.aspect'));
      try {
        const c = document.createElement('canvas');
        const side = 120;
        c.width = side; c.height = side;
        const ctx = c.getContext('2d');
        ctx.drawImage(img, 0, 0, side, side);
        const d = ctx.getImageData(0, 0, side, side).data;
        let sum = 0, n = 0;
        for (let i = 0; i < d.length; i += 4) { sum += 0.299*d[i] + 0.587*d[i+1] + 0.114*d[i+2]; n++; }
        const avg = sum / n;
        if (avg < 50) problems.push(t('forms.photo.issues.dark'));
        else if (avg > 235) problems.push(t('forms.photo.issues.bright'));
      } catch(e) {}
      setIssues(problems);
      setChecking(false);
      onChange({ dataUrl, width: img.width, height: img.height, ok: problems.length === 0 });
    };
    img.onerror = () => { setChecking(false); setIssues([t('forms.photo.issues.unreadable')]); };
    img.src = dataUrl;
  };

  const onFile = (f) => {
    if (!f) return;
    const reader = new FileReader();
    reader.onload = (e) => analyse(e.target.result);
    reader.readAsDataURL(f);
  };

  return (
    <div style={{display:'flex', gap:18, alignItems:'flex-start'}}>
      <div style={{
        width:128, height:128, borderRadius:16, overflow:'hidden',
        background: photo?.dataUrl ? `url(${photo.dataUrl}) center/cover` : 'var(--t-bg)',
        border:'1.5px dashed var(--t-line)', display:'grid', placeItems:'center',
        flexShrink:0, cursor:'pointer'
      }} onClick={()=>fileRef.current?.click()}>
        {!photo?.dataUrl && (
          <div style={{textAlign:'center', color:'var(--t-ink-muted)', fontSize:11, padding:8}}>
            <Icon name="user" size={24}/>
            <div style={{marginTop:6}}>{t('forms.photo.upload')}</div>
          </div>
        )}
      </div>
      <div style={{flex:1}}>
        <input ref={fileRef} type="file" accept="image/*" style={{display:'none'}} onChange={e=>onFile(e.target.files?.[0])}/>
        <div style={{display:'flex', gap:8, marginBottom:10}}>
          <button type="button" className="btn btn-outline btn-sm" onClick={()=>fileRef.current?.click()}>
            <Icon name="plus" size={12}/> {photo?.dataUrl ? t('forms.photo.change') : t('forms.photo.choose')}
          </button>
          {photo?.dataUrl && (
            <button type="button" className="btn btn-ghost btn-sm" onClick={()=>{ setIssues([]); onChange(null); }}>{t('forms.photo.remove')}</button>
          )}
        </div>
        {checking && <div style={{fontSize:12, color:'var(--t-ink-muted)'}}>{t('forms.photo.checking')}</div>}
        {!checking && photo?.dataUrl && issues.length === 0 && (
          <div style={{fontSize:12, color:'var(--trust)', display:'flex', alignItems:'center', gap:6, background:'var(--trust-bg)', padding:'8px 12px', borderRadius:8, border:'1px solid var(--trust-soft)'}}>
            <Icon name="check" size={12}/> {t('forms.photo.good')}
          </div>
        )}
        {!checking && issues.length > 0 && (
          <div style={{fontSize:12, color:'var(--coral, #B9472B)', background:'var(--coral-bg, #FDECE7)', padding:'10px 12px', borderRadius:8, border:'1px solid var(--coral-light, #F8D3C8)'}}>
            <div style={{fontWeight:600, marginBottom:4}}>{t('forms.photo.fixIssues')}</div>
            <ul style={{margin:0, paddingLeft:18, lineHeight:1.5}}>
              {issues.map((x,i) => <li key={i}>{x}</li>)}
            </ul>
          </div>
        )}
        {!photo?.dataUrl && !checking && (
          <div style={{fontSize:12, color:'var(--t-ink-muted)', lineHeight:1.55}}>
            {t('forms.photo.emptyHint')}
          </div>
        )}
      </div>
    </div>
  );
};

// ---- Candidate-side video upload limits ----
// Aligned with engineer_spec.md (max_duration_seconds: 180 for SELF uploads).
// MIME types cover ~99% of phone-recorded video; min height matches the lowest
// resolution where a face/skill stays recognizable on a desktop card.
const CANDIDATE_VIDEO_LIMITS = {
  acceptMime: 'video/mp4,video/quicktime',  // MP4 (H.264/H.265) + MOV (iPhone default)
  acceptLabel: 'MP4 · MOV',
  maxSizeMB: 150,
  minDurationSec: 30,
  maxDurationSec: 180,                       // 3 minutes
  minHeightPx: 720,                          // 720p floor
};
// Hint string is reactive to current language — always read at render time.
const CANDIDATE_VIDEO_HINT_FN = () => window.i18n.t('forms.video.hintLine', {
  label: CANDIDATE_VIDEO_LIMITS.acceptLabel,
  sizeMB: CANDIDATE_VIDEO_LIMITS.maxSizeMB,
});

const formatVideoDuration = (totalSeconds) => {
  const s = Math.max(0, Math.round(totalSeconds));
  return `${Math.floor(s/60)}:${String(s%60).padStart(2,'0')}`;
};

// Reads metadata from the picked file via a hidden HTMLVideoElement
// and resolves with { duration, width, height } or rejects with a message.
const readVideoMetadata = (file) => new Promise((resolve, reject) => {
  const url = URL.createObjectURL(file);
  const v = document.createElement('video');
  v.preload = 'metadata';
  v.onloadedmetadata = () => {
    URL.revokeObjectURL(url);
    resolve({ duration: v.duration, width: v.videoWidth, height: v.videoHeight });
  };
  v.onerror = () => { URL.revokeObjectURL(url); reject(new Error(window.i18n.t('forms.video.readError'))); };
  v.src = url;
});

// ---- Skill / intro video slot (non-mandatory, can upload later) ----
const VideoUploadSlot = ({ cat, video, onChange }) => {
  const { t } = window.useI18n();
  const fileRef = React.useRef(null);
  const [error, setError] = React.useState('');
  const [reading, setReading] = React.useState(false);

  const onFile = async (f) => {
    if (!f) return;
    setError(''); setReading(true);
    try {
      // 1. Format check (some browsers report empty type for unknown formats)
      const okType = ['video/mp4','video/quicktime'].includes(f.type) || /\.(mp4|mov)$/i.test(f.name);
      if (!okType) throw new Error(t('forms.video.errFormat', {label: CANDIDATE_VIDEO_LIMITS.acceptLabel}));
      // 2. Size check
      const sizeMB = f.size / (1024 * 1024);
      if (sizeMB > CANDIDATE_VIDEO_LIMITS.maxSizeMB) throw new Error(t('forms.video.errSize', {size: sizeMB.toFixed(1), max: CANDIDATE_VIDEO_LIMITS.maxSizeMB}));
      // 3. Decode metadata (duration + resolution)
      const meta = await readVideoMetadata(f);
      if (meta.duration < CANDIDATE_VIDEO_LIMITS.minDurationSec) throw new Error(t('forms.video.errTooShort', {sec: Math.round(meta.duration), min: CANDIDATE_VIDEO_LIMITS.minDurationSec}));
      if (meta.duration > CANDIDATE_VIDEO_LIMITS.maxDurationSec) throw new Error(t('forms.video.errTooLong', {sec: Math.round(meta.duration), min: Math.round(CANDIDATE_VIDEO_LIMITS.maxDurationSec/60)}));
      if (meta.height < CANDIDATE_VIDEO_LIMITS.minHeightPx) throw new Error(t('forms.video.errResolution', {w: meta.width, h: meta.height}));
      onChange({ name: f.name, size: f.size, duration: formatVideoDuration(meta.duration), width: meta.width, height: meta.height, kind: 'self' });
    } catch (err) {
      setError(err.message || String(err));
    } finally {
      setReading(false);
    }
  };

  return (
    <div style={{border:'1px solid var(--t-line)', borderRadius:12, overflow:'hidden', background:'var(--t-paper)'}}>
      <div style={{
        aspectRatio:'16/10',
        background: video ? 'linear-gradient(135deg, var(--trust), var(--trust-ink))' : 'var(--t-bg)',
        display:'grid', placeItems:'center', position:'relative'
      }}>
        <input ref={fileRef} type="file" accept={CANDIDATE_VIDEO_LIMITS.acceptMime} style={{display:'none'}} onChange={e=>onFile(e.target.files?.[0])}/>
        {video ? (
          <div style={{width:44, height:44, borderRadius:99, background:'rgba(255,255,255,0.95)', color:'var(--trust-ink)', display:'grid', placeItems:'center'}}>
            <Icon name="play" size={18}/>
          </div>
        ) : (
          <div style={{textAlign:'center', color:'var(--t-ink-muted)', fontSize:11, padding:12}}>
            <div style={{width:36, height:36, borderRadius:99, background:'var(--t-paper)', border:'1.5px dashed var(--t-line)', display:'grid', placeItems:'center', margin:'0 auto 6px'}}>
              <Icon name={cat.icon} size={14}/>
            </div>
            {t('forms.video.optional')}
          </div>
        )}
      </div>
      <div style={{padding:'10px 12px 12px'}}>
        <div style={{fontSize:13, fontWeight:700, marginBottom:2, display:'flex', alignItems:'center', gap:5}}>
          <Icon name={cat.icon} size={12}/>
          {t('forms.video.catLabel.' + cat.id) || cat.label}
        </div>
        {t('forms.video.catHint.' + cat.id) && (
          <div style={{fontSize:11, color:'var(--t-ink-muted)', marginBottom:8}}>
            {t('forms.video.catHint.' + cat.id)}
          </div>
        )}
        {video ? (
          <>
            <div style={{fontSize:11, color:'var(--t-ink-muted)', marginBottom:6}}>
              ✓ {video.duration}{video.height ? ` · ${video.width}×${video.height}` : ''}
            </div>
            <div style={{display:'flex', gap:6}}>
              <button type="button" className="btn btn-outline btn-sm" style={{flex:1, fontSize:11, padding:'6px 8px'}} onClick={()=>fileRef.current?.click()} disabled={reading}>{reading ? t('forms.video.reading') : t('forms.video.replace')}</button>
              <button type="button" className="btn btn-ghost btn-sm" style={{padding:'6px 8px'}} onClick={()=>{ onChange(null); setError(''); }}><Icon name="close" size={11}/></button>
            </div>
          </>
        ) : (
          <button type="button" className="btn btn-outline btn-sm btn-block" style={{fontSize:11, padding:'6px 8px'}} onClick={()=>fileRef.current?.click()} disabled={reading}>
            <Icon name="plus" size={11}/> {reading ? t('forms.video.reading') : t('forms.video.upload')}
          </button>
        )}
        {error && (
          <div style={{marginTop:8, padding:'6px 8px', background:'rgba(212,69,69,0.08)', border:'1px solid rgba(212,69,69,0.25)', borderRadius:6, fontSize:11, color:'#9C2A2A', lineHeight:1.4}}>
            {error}
          </div>
        )}
      </div>
    </div>
  );
};

// Make limits + hint reachable from other modules without re-defining.
window.HM_VIDEO_LIMITS = CANDIDATE_VIDEO_LIMITS;
// Other modules should call window.HM_VIDEO_HINT_FN() at render time so they
// re-read the current language when the user switches.
window.HM_VIDEO_HINT_FN = CANDIDATE_VIDEO_HINT_FN;

// ---- Work experience entry ----
// MVP scope: helpers no longer upload reference letter files. We keep the
// per-entry hasReference Yes/No toggle (admin work history table mirrors it).
// referenceFile field is removed; if file uploads come back later, restore the
// schema field + the upload UI block in WorkExperienceEntry below.
const newWorkExperience = () => ({
  position: 'Domestic Helper',
  country: 'Hong Kong',
  startYear: '',
  startMonth: '',
  endYear: '',
  endMonth: '',
  current: false,
  duties: [],
  hasReference: false,
});

const DUTY_OPTIONS = [
  'Cooking', 'Elderly Care', 'Marketing', 'Housekeeping', 'Pet Care',
  'Driving', 'Tutoring', 'Baby Care', 'Gardening', 'Kids Care', 'Car Washing',
];

const WorkExperienceEntry = ({ entry, index, onChange, onRemove, canRemove }) => {
  const { t } = window.useI18n();
  const yearOpts = []; for (let y = new Date().getFullYear(); y >= 1985; y--) yearOpts.push(y);
  const monthOpts = ['Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec'];
  const u = (k, v) => onChange({...entry, [k]: v});
  return (
    <div className="card-flat" style={{padding:28, marginBottom:24, border:'1px solid var(--t-line)', position:'relative'}}>
      <div style={{display:'flex', justifyContent:'space-between', alignItems:'baseline', marginBottom:14}}>
        <div style={{fontSize:13, fontWeight:700, color:'var(--trust-ink)', textTransform:'uppercase', letterSpacing:'0.06em'}}>{t('forms.work.title', {n: index + 1})}</div>
        {canRemove && (
          <button type="button" className="btn btn-ghost btn-sm" onClick={onRemove} style={{color:'var(--coral)'}}>
            <Icon name="trash" size={12}/> {t('forms.work.remove')}
          </button>
        )}
      </div>
      <div style={{display:'grid', gridTemplateColumns:'1fr 1fr', gap:14}}>
        <Field label={t('forms.work.position')} required>
          <select className="select" value={entry.position} onChange={e=>u('position', e.target.value)}>
            {['Domestic Helper','Nanny','Caregiver','Cook','Driver','Housekeeper','Elder care','Other'].map(p => (
              <option key={p} value={p}>{t('forms.work.positionOptions.' + p)}</option>
            ))}
          </select>
        </Field>
        <Field label={t('forms.work.country')} required>
          <select className="select" value={entry.country} onChange={e=>u('country', e.target.value)}>
            {ALL_COUNTRIES.map(c => <option key={c}>{c}</option>)}
          </select>
        </Field>
      </div>
      <div style={{display:'grid', gridTemplateColumns:'1fr 1fr', gap:14}}>
        <Field label={t('forms.work.start')} required>
          <div style={{display:'grid', gridTemplateColumns:'1fr 1fr', gap:8}}>
            <select className="select" value={entry.startMonth} onChange={e=>u('startMonth', e.target.value)}>
              <option value="">{t('forms.work.month')}</option>
              {monthOpts.map(m => <option key={m}>{m}</option>)}
            </select>
            <select className="select" value={entry.startYear} onChange={e=>u('startYear', e.target.value)}>
              <option value="">{t('forms.work.year')}</option>
              {yearOpts.map(y => <option key={y}>{y}</option>)}
            </select>
          </div>
        </Field>
        <Field label={t('forms.work.end')} hint={entry.current ? t('forms.work.currentlyHereHint') : undefined}>
          <div style={{display:'grid', gridTemplateColumns:'1fr 1fr', gap:8}}>
            <select className="select" value={entry.endMonth} onChange={e=>u('endMonth', e.target.value)} disabled={entry.current}>
              <option value="">{t('forms.work.month')}</option>
              {monthOpts.map(m => <option key={m}>{m}</option>)}
            </select>
            <select className="select" value={entry.endYear} onChange={e=>u('endYear', e.target.value)} disabled={entry.current}>
              <option value="">{t('forms.work.year')}</option>
              {yearOpts.map(y => <option key={y}>{y}</option>)}
            </select>
          </div>
          <label style={{display:'flex', alignItems:'center', gap:6, fontSize:12, color:'var(--t-ink-soft)', marginTop:8, cursor:'pointer'}}>
            <input type="checkbox" checked={entry.current} onChange={e=>u('current', e.target.checked)}/>
            {t('forms.work.currentlyHere')}
          </label>
        </Field>
      </div>
      <Field label={t('forms.work.duties')} hint={t('forms.work.dutiesHint')}>
        <div style={{display:'flex', flexWrap:'wrap', gap:8}}>
          {DUTY_OPTIONS.map(d => {
            const active = (entry.duties || []).includes(d);
            return (
              <button
                key={d}
                type="button"
                onClick={() => {
                  const cur = entry.duties || [];
                  u('duties', active ? cur.filter(x => x !== d) : [...cur, d]);
                }}
                style={{
                  padding:'7px 13px',
                  borderRadius:99,
                  border: active ? '1.5px solid var(--trust)' : '1px solid var(--t-line)',
                  background: active ? 'var(--trust-bg)' : 'var(--t-paper)',
                  color: active ? 'var(--trust-ink)' : 'var(--t-ink)',
                  fontSize:13,
                  fontWeight: active ? 600 : 500,
                  cursor:'pointer',
                  fontFamily:'inherit',
                  transition:'all 0.15s',
                  display:'inline-flex', alignItems:'center', gap:6,
                }}
              >
                {active && <Icon name="check" size={11}/>}
                {t('forms.work.duty.' + d)}
              </button>
            );
          })}
        </div>
      </Field>
      <div style={{
        background:'var(--t-paper)', border:'1px solid var(--t-line)', borderRadius:10, padding:'12px 14px',
        display:'flex', alignItems:'center', gap:14, flexWrap:'wrap'
      }}>
        <div style={{flex:'1 1 280px', minWidth:0}}>
          <div style={{fontSize:13, fontWeight:600, marginBottom:2}}>{t('forms.work.referenceTitle')}</div>
          <div style={{fontSize:11, color:'var(--t-ink-muted)'}}>{t('forms.work.referenceSub')}</div>
        </div>
        <label style={{position:'relative', width:42, height:24, flexShrink:0, cursor:'pointer'}}>
          <input type="checkbox" checked={entry.hasReference} onChange={e=>u('hasReference', e.target.checked)} style={{opacity:0, width:0, height:0}}/>
          <span style={{position:'absolute', inset:0, background: entry.hasReference ? 'var(--trust)' : 'var(--t-line)', borderRadius:99, transition:'background 0.15s'}}>
            <span style={{position:'absolute', top:3, left: entry.hasReference ? 21 : 3, width:18, height:18, borderRadius:99, background:'white', transition:'left 0.2s'}}/>
          </span>
        </label>
      </div>
      {/* MVP: file upload removed — only the Yes/No toggle is captured. Restore
          this block when reference-letter uploads come back into scope. */}
    </div>
  );
};

// Per-field resume completion check list. Keep in sync with the form state
// shape below — order doesn't matter, but each entry contributes equally to
// the percentage shown on the helper overview card. The "Medical check" item
// was intentionally dropped (was hardcoded undone, capped progress at 75%).
const RESUME_PROGRESS_CHECKS = [
  // About
  (f) => !!(f.firstName && f.lastName),
  (f) => !!f.contactEmail,
  (f) => !!f.contactPhone,
  (f) => !!f.age,
  (f) => !!f.city,
  // Background
  (f) => !!f.maritalStatus,
  (f) => !!f.religion,
  (f) => !!(f.height && f.weight),
  (f) => !!f.education,
  (f) => f.personality?.length > 0,
  // Skills
  (f) => f.languages?.length > 0,
  (f) => f.mainSkills?.length > 0,
  (f) => !!f.yearsExperience,
  (f) => !!f.introVideo,
  // Preference
  (f) => f.market?.length > 0,
  (f) => !!f.expectedSalary,
  (f) => f.jobTypes?.length > 0,
  (f) => !!f.availableDate,
  // Working experience — at least one complete entry
  (f) => f.workExperiences?.some(w => w.position && w.country && w.startYear && w.startMonth && w.duties?.length > 0),
  // Bio — needs more than a token line
  (f) => f.bio && f.bio.trim().length > 20,
];
const computeResumeProgress = (form) => {
  const passed = RESUME_PROGRESS_CHECKS.filter(check => {
    try { return check(form); } catch(e) { return false; }
  }).length;
  return Math.round((passed / RESUME_PROGRESS_CHECKS.length) * 100);
};

const CreateProfilePage = ({ go }) => {
  const { t } = window.useI18n();
  const tax = window.SKILL_TAXONOMY;
  const videoCats = window.VIDEO_CATEGORIES || [];
  const [step, setStep] = useState(0);
  // Modal shown after the helper hits Publish — covers the "submitted for
  // review" message described in CANDIDATE_REVIEW_FLOW.md.
  const [showSubmittedModal, setShowSubmittedModal] = useState(false);
  // Default form shape. Restored from localStorage on first render so users
  // who navigate away mid-form don't lose their work.
  const defaultForm = () => ({
    // Step 1 — About
    firstName: '',
    lastName: '',
    photo: null,
    position: 'Domestic Helper',
    nationality: 'Indonesia',
    age: '',
    gender: 'Female',
    city: '',
    contactEmail: '',
    contactPhoneCC: '+62',
    contactPhone: '',
    whatsappCC: '+62',
    whatsapp: '',
    // How the candidate is joining the platform — drives the public Verification badge.
    // 'self'   = registering on their own (default)
    // 'agency' = an agency vouches for them (must specify agencyName)
    // 'official' is platform-only (set by admin after Surabaya assessment) — not selectable here.
    verification: 'self',
    agencyName: '',
    // Step 2 — Background
    maritalStatus: 'Single',
    kids: '0',
    religion: '',
    height: '',
    weight: '',
    education: '',
    personality: [],
    // Step 3 — Skills
    languages: ['english'],
    mainSkills: [],
    cookingSkills: [],
    otherSkills: [],
    yearsExperience: '',
    // Self/agency candidates upload a single intro video (no skill categorisation).
    // The 4-category videos object is reserved for HelperMatch's official assessment.
    introVideo: undefined,  // { duration } once uploaded
    // Step 4 — Preference
    market: ['TW'],           // preferred job location — multi-select
    expectedSalary: '',
    jobTypes: ['full-time'],
    contractStatus: 'Finished contract',
    dayOff: 'To be discussed',
    accommodation: 'Live-in',
    availableDate: '',
    // Step 5 — Working experience
    workExperiences: [newWorkExperience()],
    // Step 6 — Bio
    bio: '',
  });
  const [form, setForm] = useState(() => {
    // Hydrate from draft if one exists. Treat parse errors as "no draft" so
    // a corrupted blob never blocks the form.
    try {
      const raw = localStorage.getItem('hm_resume_draft');
      if (raw) {
        const saved = JSON.parse(raw);
        return { ...defaultForm(), ...saved };
      }
    } catch(e) {}
    return defaultForm();
  });
  const update = (k, v) => setForm(f => ({...f, [k]: v}));

  // Try to pre-fill contact email from registration (only if not already set
  // by a restored draft).
  useEffect(() => {
    try {
      const email = localStorage.getItem('hm_registered_email');
      if (email && !form.contactEmail) update('contactEmail', email);
    } catch(e) {}
    // eslint-disable-next-line
  }, []);

  // Persist draft + progress on every form change. The dashboard overview
  // listens for 'hm-resume-changed' to re-read progress; we dispatch on every
  // change so the meter ticks live if both pages are open in the same tab.
  useEffect(() => {
    try {
      localStorage.setItem('hm_resume_draft', JSON.stringify(form));
      localStorage.setItem('hm_resume_progress', String(computeResumeProgress(form)));
      window.dispatchEvent(new Event('hm-resume-changed'));
    } catch(e) {}
  }, [form]);

  const stepTitles = [
    t('forms.profile.steps.0'), t('forms.profile.steps.1'), t('forms.profile.steps.2'),
    t('forms.profile.steps.3'), t('forms.profile.steps.4'), t('forms.profile.steps.5'),
  ];
  const totalSteps = stepTitles.length;

  // Work-experience entry validation: all-or-nothing per entry
  const isWorkExpBlank = (w) => !w.position && !w.country && !w.startYear && !w.startMonth &&
    !w.endYear && !w.endMonth && !w.current && (!w.duties || w.duties.length === 0) &&
    !w.hasReference;
  const isWorkExpComplete = (w) => Boolean(
    w.position && w.country && w.startYear && w.startMonth &&
    (w.current || (w.endYear && w.endMonth)) &&
    w.duties && w.duties.length > 0
  );

  const canContinue = () => {
    if (step === 0) {
      const baseOK = Boolean(form.firstName && form.lastName && form.city && form.contactEmail && form.contactPhone);
      const verificationOK = form.verification === 'agency' ? Boolean(form.agencyName.trim()) : true;
      return baseOK && verificationOK;
    }
    if (step === 3) {
      return Boolean(form.market && form.market.length > 0 && form.availableDate && form.expectedSalary);
    }
    if (step === 4) {
      // Optional step — users can skip without filling anything.
      return true;
    }
    return true;
  };

  const updateWorkExp = (i, next) => {
    const copy = form.workExperiences.slice();
    copy[i] = next;
    update('workExperiences', copy);
  };
  const addWorkExp = () => update('workExperiences', [...form.workExperiences, newWorkExperience()]);
  const removeWorkExp = (i) => update('workExperiences', form.workExperiences.filter((_, idx) => idx !== i));

  const fullName = `${form.firstName} ${form.lastName}`.trim();

  return (
    <div className="page">
      <div className="container" style={{maxWidth:920, padding:'40px 32px 80px'}}>
        <button className="btn btn-ghost btn-sm" onClick={()=>go('dashboard')} style={{marginBottom:20}}>
          <Icon name="arrowLeft" size={14}/> {t('forms.common.backDashboard')}
        </button>
        <div style={{marginBottom:8}}>
          <div className="eyebrow">{t('forms.profile.eyebrow')}</div>
          <h1 className="display" style={{fontSize:32, margin:'4px 0 0'}}>{t('forms.profile.title')}</h1>
        </div>
        <StepHeader step={step} total={totalSteps} titles={stepTitles} subtitle={
          step === 0 ? t('forms.profile.sub0') :
          step === 1 ? t('forms.profile.sub1') :
          step === 2 ? t('forms.profile.sub2') :
          step === 3 ? t('forms.profile.sub3') :
          step === 4 ? t('forms.profile.sub4') :
          t('forms.profile.sub5')
        }/>

        <div className="card-flat" style={{padding:32}}>

          {/* ================== STEP 0 — ABOUT ================== */}
          {step === 0 && (
            <>
              <Field label={t('forms.profile.s0.photo')} icon="field_photo" required hint={t('forms.profile.s0.photoHint')}>
                <PhotoUpload photo={form.photo} onChange={v => update('photo', v)}/>
              </Field>
              <div style={{display:'grid', gridTemplateColumns:'1fr 1fr', gap:16}}>
                <Field label={t('forms.profile.s0.firstName')} required>
                  <input className="input" value={form.firstName} onChange={e => update('firstName', e.target.value)} placeholder={t('forms.profile.s0.firstNamePlaceholder')}/>
                </Field>
                <Field label={t('forms.profile.s0.lastName')} required>
                  <input className="input" value={form.lastName} onChange={e => update('lastName', e.target.value)} placeholder={t('forms.profile.s0.lastNamePlaceholder')}/>
                </Field>
              </div>
              <div style={{display:'grid', gridTemplateColumns:'1fr 1fr', gap:16}}>
                <Field label={t('forms.profile.s0.position')} icon="field_position" required>
                  <select className="select" value={form.position} onChange={e => update('position', e.target.value)}>
                    {['Domestic Helper','Driver'].map(p => (
                      <option key={p} value={p}>{t('forms.enum.position.' + p)}</option>
                    ))}
                  </select>
                </Field>
                <Field label={t('forms.profile.s0.nationality')} icon="field_id" required>
                  <select className="select" value={form.nationality} onChange={e => update('nationality', e.target.value)}>
                    {ALL_COUNTRIES.map(c => (
                      <option key={c} value={c}>{FLAG_BY_COUNTRY[c] ? `${FLAG_BY_COUNTRY[c]} ${c}` : c}</option>
                    ))}
                  </select>
                </Field>
              </div>
              <div style={{display:'grid', gridTemplateColumns:'1fr 1fr 1fr', gap:16}}>
                <Field label={t('forms.profile.s0.age')} icon="field_age" required>
                  <input className="input" type="number" value={form.age} onChange={e => update('age', e.target.value)} placeholder="32"/>
                </Field>
                <Field label={t('forms.profile.s0.gender')} icon="field_gender" required>
                  <select className="select" value={form.gender} onChange={e => update('gender', e.target.value)}>
                    {['Female','Male','Prefer not to say'].map(g => (
                      <option key={g} value={g}>{t('forms.enum.gender.' + g)}</option>
                    ))}
                  </select>
                </Field>
                <Field label={t('forms.profile.s0.city')} icon="field_pin" required>
                  <select className="select" value={form.city} onChange={e => update('city', e.target.value)}>
                    <option value="">{t('forms.profile.s0.cityPlaceholder')}</option>
                    {ALL_COUNTRIES.map(c => (
                      <option key={c} value={c}>{FLAG_BY_COUNTRY[c] ? `${FLAG_BY_COUNTRY[c]} ${c}` : c}</option>
                    ))}
                  </select>
                </Field>
              </div>

              {/* Phase 2: re-enable the "How you're joining" verification picker block. */}

              <hr className="divider"/>
              <div style={{fontSize:12, fontWeight:700, letterSpacing:'0.06em', textTransform:'uppercase', color:'var(--t-ink-muted)', margin:'8px 0 12px'}}>{t('forms.profile.s0.contactSection')}</div>

              <Field label={t('forms.profile.s0.contactEmail')} icon="field_email" required hint={t('forms.profile.s0.contactEmailHint')}>
                <input className="input" type="email" value={form.contactEmail} onChange={e => update('contactEmail', e.target.value)} placeholder="you@example.com"/>
              </Field>
              <Field label={t('forms.profile.s0.contactPhone')} icon="field_phone" required hint={t('forms.profile.s0.contactPhoneHint')}>
                <div style={{display:'grid', gridTemplateColumns:'160px 1fr', gap:8}}>
                  <select className="select" value={form.contactPhoneCC} onChange={e => update('contactPhoneCC', e.target.value)}>
                    {DIAL_CODES.map(d => <option key={d.cc + d.name} value={d.cc}>{d.flag} {d.cc} {d.name}</option>)}
                  </select>
                  <input className="input" value={form.contactPhone} onChange={e => update('contactPhone', e.target.value)} placeholder={t('forms.profile.s0.phonePlaceholder')}/>
                </div>
              </Field>
              <Field label={t('forms.profile.s0.whatsapp')} icon="field_whatsapp" hint={t('forms.profile.s0.whatsappHint')}>
                <div style={{display:'grid', gridTemplateColumns:'160px 1fr', gap:8}}>
                  <select className="select" value={form.whatsappCC} onChange={e => update('whatsappCC', e.target.value)}>
                    {DIAL_CODES.map(d => <option key={d.cc + d.name + 'w'} value={d.cc}>{d.flag} {d.cc} {d.name}</option>)}
                  </select>
                  <input className="input" value={form.whatsapp} onChange={e => update('whatsapp', e.target.value)} placeholder={t('forms.profile.s0.phonePlaceholder')}/>
                </div>
              </Field>
            </>
          )}

          {/* ================== STEP 1 — BACKGROUND ================== */}
          {step === 1 && (
            <>
              <div style={{display:'grid', gridTemplateColumns:'1fr 1fr', gap:16}}>
                <Field label={t('forms.profile.s1.maritalStatus')} icon="field_marital" required>
                  <select className="select" value={form.maritalStatus} onChange={e => update('maritalStatus', e.target.value)}>
                    {['Single','Married','Divorced','Separated','Widowed'].map(m => (
                      <option key={m} value={m}>{t('forms.enum.marital.' + m)}</option>
                    ))}
                  </select>
                </Field>
                <Field label={t('forms.profile.s1.numKids')} icon="kids" required>
                  <select className="select" value={form.kids} onChange={e => update('kids', e.target.value)}>
                    <option value="0">{t('forms.enum.kids.0')}</option>
                    <option>1</option><option>2</option><option>3</option><option>4</option><option>5</option>
                    <option value="5+">{t('forms.enum.kids.5+')}</option>
                  </select>
                </Field>
              </div>
              <div style={{display:'grid', gridTemplateColumns:'1fr 1fr', gap:16}}>
                <Field label={t('forms.profile.s1.religion')} icon="field_religion" required>
                  <select className="select" value={form.religion} onChange={e => update('religion', e.target.value)}>
                    <option value="">{t('forms.profile.s1.religionPlaceholder')}</option>
                    {['Atheist','Buddhist','Catholic','Christian','Hindu','Jewish','Muslim','Sikh','Other'].map(r => (
                      <option key={r} value={r}>{t('forms.enum.religion.' + r)}</option>
                    ))}
                  </select>
                </Field>
                <Field label={t('forms.profile.s1.educationLevel')} icon="field_education" required>
                  <select className="select" value={form.education} onChange={e => update('education', e.target.value)}>
                    <option value="">{t('forms.profile.s1.educationPlaceholder')}</option>
                    {['Secondary school','High school','Bachelor','Master','Doctorate'].map(e => (
                      <option key={e} value={e}>{t('forms.enum.education.' + e)}</option>
                    ))}
                  </select>
                </Field>
              </div>
              {/* MVP: Height + Weight inputs removed from the resume form. */}
              <hr className="divider" style={{margin:'24px 0'}}/>
              <Field label={t('forms.profile.s1.personality')} icon="cat_personality" hint={t('forms.profile.s1.personalityHint')}>
                <ChipPicker category="personality" options={tax.personality} value={form.personality} onChange={v => update('personality', v)}/>
              </Field>
            </>
          )}

          {/* ================== STEP 2 — SKILLS ================== */}
          {step === 2 && (
            <>
              <Field label={t('forms.profile.s2.languages')} icon="cat_language" required hint={t('forms.profile.s2.languagesHint')}>
                <ChipPicker category="language" options={tax.languages} value={form.languages} onChange={v => update('languages', v)} showFlag/>
              </Field>
              <hr className="divider" style={{margin:'24px 0'}}/>
              <Field label={t('forms.profile.s2.mainSkills')} icon="cat_main" required>
                <ChipPicker category="main" options={tax.mainSkills.filter(s => s.label !== 'Marketing')} value={form.mainSkills} onChange={v => update('mainSkills', v)}/>
              </Field>
              <hr className="divider" style={{margin:'24px 0'}}/>
              <Field label={t('forms.profile.s2.cookingCuisines')} icon="cat_cooking" hint={t('forms.profile.s2.cookingCuisinesHint')}>
                <ChipPicker category="cooking" options={tax.cookingSkills} value={form.cookingSkills} onChange={v => update('cookingSkills', v)}/>
              </Field>
              <hr className="divider" style={{margin:'24px 0'}}/>
              <Field label={t('forms.profile.s2.otherSkills')} icon="cat_other">
                <ChipPicker category="other" options={tax.otherSkills} value={form.otherSkills} onChange={v => update('otherSkills', v)}/>
              </Field>
              <hr className="divider" style={{margin:'24px 0'}}/>
              <Field label={t('forms.profile.s2.yearsExperience')} icon="field_experience" required>
                <input className="input" type="number" value={form.yearsExperience} onChange={e => update('yearsExperience', e.target.value)} placeholder="5" style={{maxWidth:200}}/>
              </Field>

              <hr className="divider"/>
              <div style={{marginBottom:14}}>
                <div style={{fontSize:15, fontWeight:700, marginBottom:4}}>{t('forms.profile.s2.videoSection')} <span style={{fontSize:12, fontWeight:500, color:'var(--t-ink-muted)', marginLeft:6}}>{t('forms.profile.s2.videoOptional')}</span></div>
                <div style={{fontSize:13, color:'var(--t-ink-muted)', lineHeight:1.55, marginBottom:8}}>
                  {t('forms.profile.s2.videoBody')}
                </div>
                <div style={{fontSize:12, color:'var(--t-ink-muted)', padding:'8px 12px', background:'var(--t-bg)', border:'1px solid var(--t-line)', borderRadius:8, display:'inline-flex', alignItems:'center', gap:6}}>
                  <Icon name="info" size={12}/>
                  <span><strong style={{color:'var(--t-ink)'}}>{t('forms.profile.s2.videoRequirementsLabel')}</strong> {CANDIDATE_VIDEO_HINT_FN()}</span>
                </div>
              </div>
              <div style={{maxWidth:360}}>
                <VideoUploadSlot cat={{id:'intro', label:t('forms.profile.s2.videoIntroLabel'), icon:'play'}} video={form.introVideo}
                  onChange={v => update('introVideo', v || undefined)}/>
              </div>
            </>
          )}

          {/* ================== STEP 3 — PREFERENCE ================== */}
          {step === 3 && (
            <>
              <Field label={t('forms.profile.s3.preferredLocation')} icon="field_pin" required hint={t('forms.profile.s3.preferredLocationHint')}>
                <ChipPicker options={[
                  {id:'TW',  label: t('forms.enum.marketLabel.TW')},
                  {id:'HK',  label: t('forms.enum.marketLabel.HK')},
                  {id:'SG',  label: t('forms.enum.marketLabel.SG')},
                  {id:'Any', label: t('forms.enum.marketLabel.Any')},
                ]} value={form.market} onChange={v => update('market', v)} multi={true}/>
              </Field>

              <div style={{display:'grid', gridTemplateColumns:'1fr 1fr', gap:16}}>
                <Field label={t('forms.profile.s3.contractStatus')} icon="field_contract" required>
                  <select className="select" value={form.contractStatus} onChange={e => update('contractStatus', e.target.value)}>
                    {['Finished contract','Terminated','Break contract','Transfer'].map(c => (
                      <option key={c} value={c}>{t('forms.enum.profContractStatus.' + c)}</option>
                    ))}
                  </select>
                </Field>
                <Field label={t('forms.profile.s3.availableFrom')} icon="field_calendar" required>
                  <input className="input" type="date" value={form.availableDate} onChange={e => update('availableDate', e.target.value)}/>
                </Field>
              </div>

              <div style={{display:'grid', gridTemplateColumns:'1fr 1fr', gap:16}}>
                <Field label={t('forms.profile.s3.dayOff')} icon="dayoff" required>
                  <select className="select" value={form.dayOff} onChange={e => update('dayOff', e.target.value)}>
                    {['To be discussed','Flexible','Monday','Tuesday','Wednesday','Thursday','Friday','Saturday','Sunday'].map(d => (
                      <option key={d} value={d}>{t('forms.enum.dayOff.' + d)}</option>
                    ))}
                  </select>
                </Field>
                <Field label={t('forms.profile.s3.accommodation')} icon="field_accommodation" required hint={t('forms.profile.s3.accommodationHint')}>
                  <select className="select" value={form.accommodation} onChange={e => update('accommodation', e.target.value)}>
                    {['Live-in','Live-out','Either'].map(a => (
                      <option key={a} value={a}>{t('forms.enum.accommodation.' + a)}</option>
                    ))}
                  </select>
                </Field>
              </div>

              <Field label={t('forms.profile.s3.openJobTypes')} icon="field_jobtype" required>
                <ChipPicker options={['full-time','part-time','temporary'].map(id => ({id, label: t('forms.enum.jobType.' + id)}))} value={form.jobTypes} onChange={v => update('jobTypes', v)}/>
              </Field>

              <Field label={t('forms.profile.s3.expectedSalary')} icon="field_money" required hint={t('forms.profile.s3.expectedSalaryHint')}>
                <input className="input" value={form.expectedSalary} onChange={e => update('expectedSalary', e.target.value)} placeholder={t('forms.profile.s3.expectedSalaryPlaceholder')}/>
              </Field>
            </>
          )}

          {/* ================== STEP 4 — WORKING EXPERIENCE ================== */}
          {step === 4 && (
            <>
              <div style={{marginBottom:16, fontSize:13, color:'var(--t-ink-soft)', lineHeight:1.55}}>
                {t('forms.profile.s4.optionalNote')}
              </div>
              {form.workExperiences.map((w, i) => (
                <WorkExperienceEntry
                  key={i}
                  entry={w}
                  index={i}
                  onChange={next => updateWorkExp(i, next)}
                  onRemove={() => removeWorkExp(i)}
                  canRemove={form.workExperiences.length > 1}
                />
              ))}
              <button type="button" className="btn btn-outline btn-block" onClick={addWorkExp} style={{marginTop:4}}>
                <Icon name="plus" size={14}/> {t('forms.profile.s4.addAnother')}
              </button>
            </>
          )}

          {/* ================== STEP 5 — BIO & REVIEW ================== */}
          {step === 5 && (
            <>
              <Field label={t('forms.profile.s5.bio')} icon="field_bio" required hint={t('forms.profile.s5.bioHint')}>
                <textarea className="input" rows={5} value={form.bio} onChange={e => update('bio', e.target.value)}
                  placeholder={t('forms.profile.s5.bioPlaceholder')}
                  style={{resize:'vertical'}}/>
              </Field>

              <hr className="divider"/>

              <div style={{display:'flex', gap:16, padding:20, background:'var(--t-paper)', borderRadius:12, marginBottom:24, border:'1px solid var(--t-line)'}}>
                <div style={{
                  width:72, height:72, borderRadius:99, flexShrink:0,
                  background: form.photo?.dataUrl ? `url(${form.photo.dataUrl}) center/cover` : 'var(--trust)',
                  color:'white', display:'grid', placeItems:'center', fontSize:28, fontWeight:700
                }}>
                  {!form.photo?.dataUrl && (fullName[0] || '?').toUpperCase()}
                </div>
                <div style={{flex:1}}>
                  <div className="display" style={{fontSize:22, marginBottom:4}}>{fullName || t('forms.profile.s5.yourName')}</div>
                  <div style={{fontSize:14, color:'var(--t-ink-muted)', marginBottom:8}}>
                    {form.age && `${form.age} · `}{form.nationality} · {form.city} · {form.position ? t('forms.enum.position.' + form.position) : ''}
                  </div>
                  <div style={{display:'flex', gap:6, flexWrap:'wrap'}}>
                    {form.jobTypes.slice(0,3).map(jt => <span key={jt} className="chip chip-ghost" style={{fontSize:11}}>{t('forms.enum.jobType.' + jt)}</span>)}
                  </div>
                </div>
              </div>

              <div style={{display:'grid', gridTemplateColumns:'1fr 1fr', gap:'16px 28px', marginBottom:24}}>
                <Summary label={t('forms.profile.s5.contactEmail')} value={form.contactEmail}/>
                <Summary label={t('forms.profile.s5.contactNumber')} value={form.contactPhone ? `${form.contactPhoneCC} ${form.contactPhone}` : ''}/>
                <Summary label={t('forms.profile.s5.experience')} value={form.yearsExperience ? t('forms.profile.s5.experienceValue', {n: form.yearsExperience}) : ''}/>
                <Summary label={t('forms.profile.s5.expectedSalary')} value={form.expectedSalary}/>
                <Summary label={t('forms.profile.s5.preferredLocation')} value={(form.market || []).map(m => t('forms.enum.marketLabel.' + m)).join(', ')}/>
                <Summary label={t('forms.profile.s5.contractStatus')} value={form.contractStatus ? t('forms.enum.profContractStatus.' + form.contractStatus) : ''}/>
                <Summary label={t('forms.profile.s5.dayOffShort')} value={form.dayOff ? t('forms.enum.dayOff.' + form.dayOff) : ''}/>
                <Summary label={t('forms.profile.s5.accommodation')} value={form.accommodation ? t('forms.enum.accommodation.' + form.accommodation) : ''}/>
                <Summary label={t('forms.profile.s5.marital')} value={form.maritalStatus ? t('forms.enum.marital.' + form.maritalStatus) : ''}/>
                <Summary label={t('forms.profile.s5.kids')} value={form.kids === '0' ? t('forms.enum.kids.0') : form.kids === '5+' ? t('forms.enum.kids.5+') : form.kids}/>
                <Summary label={t('forms.profile.s5.religion')} value={form.religion ? t('forms.enum.religion.' + form.religion) : ''}/>
                <Summary label={t('forms.profile.s5.education')} value={form.education ? t('forms.enum.education.' + form.education) : ''}/>
              </div>

              <hr className="divider"/>
              <SummaryChips label={t('forms.profile.s5.languages')} items={tax.languages.filter(x => form.languages.includes(x.id)).map(x => window.pickLocalised(x, 'label') || x.label)}/>
              <SummaryChips label={t('forms.profile.s5.mainSkills')} items={tax.mainSkills.filter(x => form.mainSkills.includes(x.id)).map(x => window.pickLocalised(x, 'label') || x.label)}/>
              <SummaryChips label={t('forms.profile.s5.cookingCuisines')} items={tax.cookingSkills.filter(x => form.cookingSkills.includes(x.id)).map(x => window.pickLocalised(x, 'label') || x.label)}/>
              <SummaryChips label={t('forms.profile.s5.otherSkills')} items={tax.otherSkills.filter(x => form.otherSkills.includes(x.id)).map(x => window.pickLocalised(x, 'label') || x.label)}/>
              <SummaryChips label={t('forms.profile.s5.personality')} items={tax.personality.filter(x => form.personality.includes(x.id)).map(x => window.pickLocalised(x, 'label') || x.label)}/>

              <hr className="divider"/>
              <div style={{marginBottom:20}}>
                <div style={{fontSize:12, fontWeight:700, letterSpacing:'0.06em', textTransform:'uppercase', color:'var(--t-ink-muted)', marginBottom:10}}>{t('forms.profile.s5.workHistory')}</div>
                {form.workExperiences.map((w, i) => {
                  const dates = `${w.startMonth || ''} ${w.startYear || ''} — ${w.current ? t('forms.profile.s5.dateRangePresent') : `${w.endMonth || ''} ${w.endYear || ''}`}`.trim();
                  return (
                    <div key={i} style={{padding:'10px 0', borderBottom: i < form.workExperiences.length-1 ? '1px solid var(--t-line)' : 'none'}}>
                      <div style={{fontSize:14, fontWeight:600}}>{w.position ? t('forms.enum.position.' + w.position) : ''} — {w.country}</div>
                      <div style={{fontSize:12, color:'var(--t-ink-muted)'}}>{dates} {w.hasReference && t('forms.profile.s5.referenceAvailable')}</div>
                      {w.duties && w.duties.length > 0 && (
                        <div style={{display:'flex', flexWrap:'wrap', gap:6, marginTop:6}}>
                          {w.duties.map((d, di) => (
                            <span key={di} className="chip" style={{fontSize:11}}>{t('forms.work.duty.' + d)}</span>
                          ))}
                        </div>
                      )}
                    </div>
                  );
                })}
              </div>

              <hr className="divider"/>
              <div>
                <div style={{fontSize:12, fontWeight:700, letterSpacing:'0.06em', textTransform:'uppercase', color:'var(--t-ink-muted)', marginBottom:10}}>{t('forms.profile.s5.yourStory')}</div>
                <div style={{fontSize:14, lineHeight:1.65, color:'var(--t-ink-soft)', whiteSpace:'pre-wrap'}}>{form.bio || <span style={{color:'var(--t-ink-muted)'}}>{t('forms.common.notProvided')}</span>}</div>
              </div>

              <hr className="divider"/>
              <div>
                <div style={{fontSize:12, fontWeight:700, letterSpacing:'0.06em', textTransform:'uppercase', color:'var(--t-ink-muted)', marginBottom:10}}>{t('forms.profile.s5.videoSection')}</div>
                <div style={{fontSize:13, color:'var(--t-ink-soft)'}}>
                  {form.introVideo ? t('forms.profile.s5.videoUploaded') : <>{t('forms.profile.s5.videoNotUploaded')} <span style={{color:'var(--t-ink-muted)'}}>{t('forms.profile.s5.videoCanAddLater')}</span></>}
                </div>
              </div>
            </>
          )}

          <div style={{display:'flex', justifyContent:'space-between', gap:12, marginTop:28, paddingTop:24, borderTop:'1px solid var(--t-line)'}}>
            <button className="btn btn-ghost" onClick={() => { if (step === 0) { go('dashboard'); } else { setStep(step-1); window.scrollTo(0, 0); } }}>
              {step === 0 ? t('forms.common.cancel') : t('forms.common.back')}
            </button>
            {step < totalSteps - 1 ? (
              <button className="btn btn-primary" onClick={() => { setStep(step+1); window.scrollTo(0, 0); }} disabled={!canContinue()} style={{opacity: canContinue() ? 1 : 0.5}}>{t('forms.common.continue')}</button>
            ) : (
              <button className="btn btn-primary" onClick={() => {
                try {
                  localStorage.setItem('hm_resume_complete', '1');
                  localStorage.setItem('hm_resume_progress', '100');
                  // Draft no longer needed once the resume is live — keeping
                  // it would silently overwrite future edits with stale data.
                  localStorage.removeItem('hm_resume_draft');
                  window.dispatchEvent(new Event('hm-resume-changed'));
                  // Enter the review pipeline (see CANDIDATE_REVIEW_FLOW.md).
                  // Production: server validates payload, sets reviewStatus,
                  // queues RESUME_SUBMITTED email. Prototype just flips the
                  // localStorage broker so other pages can react.
                  localStorage.setItem('hm_review_status', 'pending_review');
                  localStorage.setItem('hm_review_submittedAt', String(Date.now()));
                  window.dispatchEvent(new Event('hm-review-status-changed'));
                } catch(e) {}
                setShowSubmittedModal(true);
              }}>{t('forms.profile.s5.publishBtn')}</button>
            )}
          </div>
        </div>
      </div>
      {showSubmittedModal && (
        <div onClick={()=>{ setShowSubmittedModal(false); go('dashboard'); }} style={{position:'fixed', inset:0, background:'rgba(22,18,15,0.55)', display:'grid', placeItems:'center', zIndex:100, padding:20}}>
          <div onClick={e=>e.stopPropagation()} className="card-flat" style={{maxWidth:480, width:'100%', padding:36, background:'var(--t-paper)', borderRadius:16, boxShadow:'0 24px 60px rgba(0,0,0,0.3)', textAlign:'center'}}>
            <div style={{width:64, height:64, borderRadius:99, background:'var(--trust-bg)', color:'var(--trust)', display:'grid', placeItems:'center', margin:'0 auto 18px'}}>
              <Icon name="clock" size={28}/>
            </div>
            <h2 className="display" style={{fontSize:24, marginBottom:10}}>{t('forms.profile.s5.submittedTitle')}</h2>
            <p style={{color:'var(--t-ink-soft)', fontSize:15, lineHeight:1.6, marginBottom:24}}>
              {t('forms.profile.s5.submittedBody')}
            </p>
            <button className="btn btn-primary btn-block" onClick={()=>{ setShowSubmittedModal(false); go('dashboard'); }}>
              {t('forms.profile.s5.submittedCta')}
            </button>
          </div>
        </div>
      )}
    </div>
  );
};

Object.assign(window, { PostJobPage, CreateProfilePage });
