// ===== Helper Dashboard =====

const HelperDashPage = ({ go, subscription, logout }) => {
  const { t } = window.useI18n();
  // Default landing section is 'profile' — the previous Overview page was
  // mostly mock stats with no real signal value, so it was removed.
  const [section, setSection] = React.useState('profile');
  const { candidates, jobs } = window.MOCK_DATA;
  // Use a candidate as "me" for avatar + profile data
  const me = candidates.find(c => c.id === 1234) || candidates[0];
  // Applications shown to helper. Status reflects employer-driven actions
  // (helper cannot self-advance application state — see DOMAIN_MODEL.md
  // §4.13). `threadId` is set ONLY when the employer has reached out — only
  // then does the card show the Message button (helper cannot initiate
  // contact; see asymmetric messaging rule in DOMAIN_MODEL.md §4.15).
  const applications = [
    { jobId: jobs[0]?.id, status: 'Contacted by employer', when: '2 days ago', badge: 'trust', threadId: 1234 },
    { jobId: jobs[2]?.id, status: 'Shortlisted by employer', when: '5 days ago', badge: 'mint' },
    { jobId: jobs[3]?.id, status: 'Application viewed', when: '6 days ago', badge: 'sand' },
    { jobId: jobs[5]?.id, status: 'Awaiting employer review', when: '1 week ago', badge: 'ghost' },
  ].filter(a => a.jobId);

  return (
    <div className="page container-wide dash-layout">
      {/* Sidebar */}
      <aside className="dash-side">
        <div style={{display:'flex', alignItems:'center', gap:10, padding:'12px 14px', marginBottom:12, background:'var(--t-paper)', border:'1px solid var(--t-line)', borderRadius:12}}>
          <Avatar person={me} size={40}/>
          <div style={{minWidth:0}}>
            <div style={{fontSize:13, fontWeight:600, display:'flex', alignItems:'center', gap:4}}>
              {me.name}
              <Icon name="verified" size={11} style={{color:'var(--trust)'}}/>
            </div>
            <div style={{fontSize:11, color:'var(--t-ink-muted)', display:'flex', alignItems:'center', gap:4}}>
              {me.flag} {me.nationality} · Active now
            </div>
          </div>
        </div>
        <div className="dash-nav">
          {[
            {id:'profile', label: t('helperDash.nav.profile'), icon:'user'},
            {id:'matches', label: t('helperDash.nav.matches'), icon:'sparkle'},
            {id:'applications', label: t('helperDash.nav.applications'), icon:'briefcase', count:applications.length},
            {id:'saved', label: t('helperDash.nav.savedJobs'), icon:'heart', count:3},
            {id:'earnings', label: t('helperDash.nav.earnings'), icon:'coin'},
            {id:'settings', label: t('helperDash.nav.settings'), icon:'settings'},
          ].map(n => (
            <button key={n.id} className={`dash-nav-item ${section===n.id?'active':''}`} onClick={()=>setSection(n.id)}>
              <Icon name={n.icon} size={16}/>
              {n.label}
              {n.count != null && <span className="badge-count">{n.count}</span>}
            </button>
          ))}
        </div>
        <div style={{marginTop:20, padding:16, background:'var(--trust-bg)', border:'1px solid var(--trust-soft)', borderRadius:12}}>
          <div style={{fontSize:12, fontWeight:700, color:'var(--trust-ink)', marginBottom:6, display:'flex', alignItems:'center', gap:6}}>
            <Icon name="shield" size={12}/> Helper Support
          </div>
          <div style={{fontSize:12, color:'var(--t-ink-muted)', lineHeight:1.5, marginBottom:10}}>
            Questions about your application or contract? Our team replies in Bahasa, Tagalog & English.
          </div>
          <button className="btn btn-outline btn-sm btn-block" style={{fontSize:12}}>Get help</button>
        </div>
        {logout && (
          <button
            onClick={logout}
            className="dash-nav-item"
            style={{marginTop:16, color:'var(--t-ink-muted)', justifyContent:'flex-start'}}
            title={t('dash.signOutTitle')}
          >
            <Icon name="arrowLeft" size={16}/>
            {t('dash.signOut')}
          </button>
        )}
      </aside>

      {/* Main content */}
      <div>
        {section === 'profile' && <HelperProfile me={me} go={go}/>}
        {section === 'matches' && <HelperMatches go={go} me={me} matchedJobs={jobs}/>}
        {section === 'applications' && <HelperApplications go={go} applications={applications}/>}
        {section === 'saved' && <HelperSaved go={go} jobs={jobs.slice(0, 3)}/>}
        {section === 'earnings' && <HelperEarnings/>}
        {section === 'settings' && <HelperAccount me={me}/>}
      </div>
    </div>
  );
};

// ===== Profile =====
const HelperProfile = ({ me, go }) => {
  const { t } = window.useI18n();
  const tax = window.SKILL_TAXONOMY;
  const d = me.demographics || {};
  const ts = me.typedSkills || {};
  const isOfficial = me.verification === 'official';
  const officialVideoCount = me.videos ? Object.values(me.videos).filter(Boolean).length : 0;
  const hasIntroVideo = !!me.introVideo;

  // Review status from CANDIDATE_REVIEW_FLOW.md. Read once + listen for the
  // hm-review-status-changed event so admin Approve/Reject in another tab
  // updates the banner live.
  const readStatus = () => {
    try { return localStorage.getItem('hm_review_status') || 'approved'; } catch(e) { return 'approved'; }
  };
  const [reviewStatus, setReviewStatus] = React.useState(readStatus);
  React.useEffect(() => {
    const sync = () => setReviewStatus(readStatus());
    window.addEventListener('storage', sync);
    window.addEventListener('hm-review-status-changed', sync);
    return () => { window.removeEventListener('storage', sync); window.removeEventListener('hm-review-status-changed', sync); };
  }, []);
  const rejectReason = (() => { try { return localStorage.getItem('hm_review_reject_reason') || ''; } catch(e) { return ''; } })();
  // Tags here mirror the SkillsGroup styling on the single helper page so the
  // helper-side preview matches what employers see. Per-category render:
  //   - 'language' : filled coral pill + flag glyph
  //   - 'cooking'  : filled coral pill (no icon — cuisines lack glyphs)
  //   - 'main' / 'other' / 'personality' : white pill with mini-disc + SkillIcon + label
  const PillGroup = ({title, category = 'main', items, lookup}) => {
    const c = window.SKILL_CAT_COLORS[category] || window.SKILL_CAT_COLORS.main;
    const enriched = (items || []).map(id => lookup?.find(x => x.id === id) || {id, label: id});
    if (enriched.length === 0) return null;
    const itemLabel = (x) => window.pickLocalised(x, 'label') || x.label || x.id;
    return (
      <div>
        <div style={{fontSize:12, fontWeight:700, letterSpacing:'0.06em', textTransform:'uppercase', color:'var(--t-ink-muted)', marginBottom:10}}>{title}</div>
        <div style={{display:'flex', flexWrap:'wrap', gap:6}}>
          {enriched.map(x => {
            if (category === 'cooking') {
              return (
                <span key={x.id} style={{display:'inline-flex', padding:'6px 12px', borderRadius:99, background:c.bg, color:c.fg, fontSize:12.5, fontWeight:500}}>
                  {itemLabel(x)}
                </span>
              );
            }
            if (category === 'language') {
              return (
                <span key={x.id} style={{display:'inline-flex', alignItems:'center', gap:6, padding:'6px 12px', borderRadius:99, background:c.bg, color:c.fg, fontSize:12.5, fontWeight:500}}>
                  {x.flag && <span style={{fontSize:14, lineHeight:1}}>{x.flag}</span>}
                  {itemLabel(x)}
                </span>
              );
            }
            return (
              <div key={x.id} style={{display:'inline-flex', alignItems:'center', gap:7, padding:'5px 12px 5px 5px', background:'var(--t-paper)', border:'1px solid var(--t-line)', borderRadius:99, fontSize:13}}>
                <span style={{display:'grid', placeItems:'center', width:22, height:22, borderRadius:99, background:c.bg, color:c.fg, flexShrink:0}}>
                  <window.SkillIcon name={x.id} size={13}/>
                </span>
                <span style={{fontWeight:500, whiteSpace:'nowrap'}}>{itemLabel(x)}</span>
              </div>
            );
          })}
        </div>
      </div>
    );
  };

  return (
    <div>
      <div className="dash-header" style={{display:'flex', justifyContent:'space-between', alignItems:'flex-start'}}>
        <div>
          <h1>My profile</h1>
          <p>This is what families see when they view your profile. Keep it accurate and up-to-date.</p>
        </div>
        <button className="btn btn-trust btn-sm" onClick={()=>go && go('create-profile')}>
          <Icon name="edit" size={13}/> Edit resume
        </button>
      </div>

      {/* Review status banner — surfaces where the helper is in the
          approval pipeline (see CANDIDATE_REVIEW_FLOW.md). Hidden when
          status is 'approved' (no signal needed) or 'pending_resume'
          (the resume completion banner upstream covers it). */}
      {reviewStatus === 'pending_review' && (
        <div className="card-flat" style={{padding:18, marginBottom:16, display:'flex', gap:14, alignItems:'center', background:'linear-gradient(135deg, #FFF7E6, #FDECC8)', border:'1.5px solid #F0C674'}}>
          <div style={{width:40, height:40, borderRadius:99, background:'#F0C674', color:'#7A4F00', display:'grid', placeItems:'center', flexShrink:0}}>
            <Icon name="clock" size={18}/>
          </div>
          <div style={{flex:1, minWidth:0}}>
            <div style={{fontSize:14, fontWeight:700, color:'#7A4F00', marginBottom:2}}>Profile under review</div>
            <div style={{fontSize:12.5, color:'#7A4F00', opacity:0.85, lineHeight:1.5}}>Our team typically reviews new profiles within 24 hours. We'll email you the moment it's approved.</div>
          </div>
        </div>
      )}
      {reviewStatus === 'rejected' && (
        <div className="card-flat" style={{padding:18, marginBottom:16, display:'flex', gap:14, alignItems:'flex-start', background:'var(--coral-bg)', border:'1.5px solid var(--coral-light)'}}>
          <div style={{width:40, height:40, borderRadius:99, background:'var(--coral-dark)', color:'white', display:'grid', placeItems:'center', flexShrink:0}}>
            <Icon name="x" size={18}/>
          </div>
          <div style={{flex:1, minWidth:0}}>
            <div style={{fontSize:14, fontWeight:700, color:'var(--coral-dark)', marginBottom:2}}>Profile needs updates</div>
            <div style={{fontSize:12.5, color:'var(--t-ink-soft)', lineHeight:1.5, marginBottom:rejectReason ? 6 : 10}}>{rejectReason || 'Our team flagged a few items that need attention before you can apply to jobs.'}</div>
            <button className="btn btn-sm" style={{background:'var(--coral-dark)', color:'white', borderColor:'var(--coral-dark)', padding:'6px 14px', fontSize:12.5, fontWeight:600, borderRadius:8}} onClick={()=>go && go('create-profile')}>
              Edit and resubmit
            </button>
          </div>
        </div>
      )}
      {reviewStatus === 'approved' && (() => {
        // Show the "approved" banner once and stash a flag so it doesn't
        // sit forever — once the helper has dismissed it, it stays gone
        // until status flips back to non-approved.
        let dismissed = false;
        try { dismissed = localStorage.getItem('hm_review_approved_seen') === '1'; } catch(e) {}
        if (dismissed) return null;
        return (
          <div className="card-flat" style={{padding:18, marginBottom:16, display:'flex', gap:14, alignItems:'center', background:'var(--mint-light, #DCF5EE)', border:'1.5px solid var(--mint, #48B8A0)'}}>
            <div style={{width:40, height:40, borderRadius:99, background:'var(--mint, #48B8A0)', color:'white', display:'grid', placeItems:'center', flexShrink:0}}>
              <Icon name="check" size={18}/>
            </div>
            <div style={{flex:1, minWidth:0}}>
              <div style={{fontSize:14, fontWeight:700, color:'var(--mint-dark, #1F7D6A)', marginBottom:2}}>Profile approved</div>
              <div style={{fontSize:12.5, color:'var(--t-ink-soft)', lineHeight:1.5}}>You can now apply to jobs and receive employer messages.</div>
            </div>
            <button
              className="btn btn-ghost btn-sm"
              onClick={() => { try { localStorage.setItem('hm_review_approved_seen', '1'); } catch(e) {} setReviewStatus(s => s); }}
              style={{flexShrink:0}}
              aria-label="Dismiss"
            >
              <Icon name="x" size={14}/>
            </button>
          </div>
        );
      })()}

      {/* Identity card */}
      <div className="card-flat" style={{padding:24, marginBottom:16, display:'flex', gap:20, alignItems:'center'}}>
        <Avatar person={me} size={84}/>
        <div style={{flex:1}}>
          <div style={{display:'flex', alignItems:'center', gap:8, marginBottom:4}}>
            <h2 style={{fontSize:22, fontWeight:700, letterSpacing:'-0.01em'}}>{me.name}</h2>
            {/* Verified badge is reserved for HelperMatch-official assessed
                helpers — agency/self-registered profiles render without it. */}
            {isOfficial && <Icon name="verified" size={16} style={{color:'var(--trust)'}}/>}
          </div>
          <div style={{fontSize:13, color:'var(--t-ink-muted)'}}>
            {me.age} · {me.flag} {me.nationality} · {me.city}
          </div>
        </div>
      </div>

      {/* Personal details — demographic grid + short bio captured from the
          resume form's Bio step. */}
      <div className="card-flat" style={{padding:24, marginBottom:16}}>
        <h3 style={{fontSize:15, fontWeight:700, marginBottom:18}}>Personal details</h3>
        <div style={{display:'grid', gridTemplateColumns:'repeat(4, 1fr)', gap:20}}>
          {[
            {label:'Gender', value:d.gender || 'Female'},
            {label:'Marital', value:d.maritalStatus || '—'},
            {label:'Children', value:d.kids || '—'},
            {label:'Religion', value:d.religion || '—'},
            {label:'Height', value:d.height || '—'},
            {label:'Weight', value:d.weight || '—'},
            {label:'Education', value:d.education || '—'},
            {label:'Experience', value: me.experience || '8 years'},
          ].map((x, i) => (
            <div key={i}>
              <div style={{fontSize:11, color:'var(--t-ink-muted)', textTransform:'uppercase', letterSpacing:'0.06em', fontWeight:600, marginBottom:4}}>{x.label}</div>
              <div style={{fontSize:14, fontWeight:500}}>{x.value}</div>
            </div>
          ))}
        </div>
        {(window.pickLocalised(me, 'bio') || me.bio) && (
          <div style={{marginTop:22, paddingTop:18, borderTop:'1px solid var(--t-line)'}}>
            <div style={{fontSize:11, color:'var(--t-ink-muted)', textTransform:'uppercase', letterSpacing:'0.06em', fontWeight:600, marginBottom:6}}>Short bio</div>
            <p style={{fontSize:14, lineHeight:1.6, color:'var(--t-ink-soft)', margin:0}}>{window.pickLocalised(me, 'bio') || me.bio}</p>
          </div>
        )}
      </div>

      {/* Skills & languages — tags mirror the public single-helper page */}
      <div className="card-flat" style={{padding:24, marginBottom:16}}>
        <h3 style={{fontSize:15, fontWeight:700, marginBottom:18}}>Skills & languages</h3>
        <div style={{display:'grid', gridTemplateColumns:'1fr 1fr', gap:'22px 28px'}}>
          <PillGroup title="Languages" category="language" items={ts.languages} lookup={tax?.languages}/>
          <PillGroup title="Main skills" category="main" items={ts.mainSkills} lookup={tax?.mainSkills}/>
          <PillGroup title="Cooking cuisines" category="cooking" items={ts.cookingSkills} lookup={tax?.cookingSkills}/>
          <PillGroup title="Other skills" category="other" items={ts.otherSkills} lookup={tax?.otherSkills}/>
          <PillGroup title="Personality" category="personality" items={ts.personality} lookup={tax?.personality}/>
        </div>
      </div>

      {/* My preference — captured from the resume form's Preference step.
          Reuses the candidate.expectations + jobTypes + contractStatus +
          availableDate fields populated by the prototype mock data. */}
      <div className="card-flat" style={{padding:24, marginBottom:16}}>
        <h3 style={{fontSize:15, fontWeight:700, marginBottom:18}}>My preference</h3>
        <div style={{display:'grid', gridTemplateColumns:'repeat(4, 1fr)', gap:20}}>
          {[
            {label:'Position', value: me.jobTypes?.[0] || 'Domestic Helper'},
            {label:'Job type', value: me.expectations?.accommodation === 'Live-out' ? 'Live-out' : 'Live-in'},
            {label:'Expected salary', value: me.expectations?.salary || '—'},
            {label:'Day off', value: me.expectations?.dayOff || '—'},
            {label:'Accommodation', value: me.expectations?.accommodation || '—'},
            {label:'Contract status', value: me.contractStatus || '—'},
            {label:'Available from', value: me.availableDate || '—'},
            {label:'Preferred markets', value: me.locationCountry || me.city || '—'},
          ].map((x, i) => (
            <div key={i}>
              <div style={{fontSize:11, color:'var(--t-ink-muted)', textTransform:'uppercase', letterSpacing:'0.06em', fontWeight:600, marginBottom:4}}>{x.label}</div>
              <div style={{fontSize:14, fontWeight:500}}>{x.value}</div>
            </div>
          ))}
        </div>
      </div>

      {/* My experience — work history captured from the resume form's
          Working experience step. Falls back to mock i18n strings (mirrored
          from the public detail page) until per-helper workExperiences exist
          on the candidate record. */}
      <div className="card-flat" style={{padding:24, marginBottom:16}}>
        <h3 style={{fontSize:15, fontWeight:700, marginBottom:14}}>My experience</h3>
        <div style={{display:'flex', flexDirection:'column', gap:8}}>
          {[
            { city: t('detail.workMock.e1City'), years: t('detail.workMock.e1Years'), role: t('detail.workMock.e1Role') },
            { city: t('detail.workMock.e2City'), years: t('detail.workMock.e2Years'), role: t('detail.workMock.e2Role') },
            { city: t('detail.workMock.e3City'), years: t('detail.workMock.e3Years'), role: t('detail.workMock.e3Role') },
          ].map((e, i) => (
            <div key={i} style={{display:'flex', gap:12, padding:'12px 14px', background:'var(--t-paper)', border:'1px solid var(--t-line)', borderRadius:'var(--t-radius-sm)', alignItems:'center'}}>
              <div style={{width:40, height:40, borderRadius:10, background:'var(--trust-bg)', color:'var(--trust)', display:'grid', placeItems:'center', flexShrink:0}}>
                <Icon name="briefcase" size={20}/>
              </div>
              <div style={{flex:1, minWidth:0}}>
                <div style={{display:'flex', justifyContent:'space-between', alignItems:'baseline', gap:12, marginBottom:2, flexWrap:'wrap'}}>
                  <div style={{fontWeight:600, fontSize:14}}>{e.role}</div>
                  <div style={{fontSize:12, color:'var(--t-ink-muted)', display:'inline-flex', alignItems:'center', gap:4}}>
                    <Icon name="calendar" size={11}/> {e.years}
                  </div>
                </div>
                <div style={{fontSize:12.5, color:'var(--t-ink-muted)', display:'inline-flex', alignItems:'center', gap:4}}>
                  <Icon name="location" size={11}/> {e.city}
                </div>
              </div>
            </div>
          ))}
        </div>
      </div>

      {/* Videos — official helpers see the 4 skill-category grid (admin-recorded);
          ALL helpers (official + self/agency) also get a self-upload slot
          beneath, so they can add their own intro clip on top of the official
          videos. */}
      {isOfficial && (
        <div className="card-flat" style={{padding:24, marginBottom:16}}>
          <div style={{display:'flex', justifyContent:'space-between', alignItems:'flex-start', marginBottom:6, gap:12, flexWrap:'wrap'}}>
            <div>
              {/* Phase 2: append <span className="chip chip-mint">HelperMatch Official</span> to the heading. */}
              <h3 style={{fontSize:15, fontWeight:700, marginBottom:4}}>Skill videos</h3>
              <p style={{fontSize:12, color:'var(--t-ink-muted)'}}>Recorded for you by our team. Reach out if anything needs to be re-recorded.</p>
            </div>
            <div style={{display:'flex', alignItems:'center', gap:8}}>
              <span className="chip chip-mint" style={{fontSize:11}}>{officialVideoCount} / 4 recorded</span>
            </div>
          </div>
          <div style={{display:'grid', gridTemplateColumns:'repeat(4, 1fr)', gap:12, marginTop:14}}>
            {(window.VIDEO_CATEGORIES || []).map(cat => {
              const v = me.videos?.[cat.id];
              return (
                <div key={cat.id} style={{border:'1px solid var(--t-line)', borderRadius:12, overflow:'hidden', background:'var(--t-paper)'}}>
                  <div style={{aspectRatio:'16/10', background: v ? `linear-gradient(135deg, ${me.color}66, ${me.color}AA), radial-gradient(circle at 60% 40%, ${window.shadeColor(me.color,30)}, ${window.shadeColor(me.color,-30)})` : 'var(--t-bg)', display:'grid', placeItems:'center', position:'relative'}}>
                    {v ? (
                      <>
                        <div style={{width:44, height:44, borderRadius:99, background:'rgba(255,255,255,0.95)', color:'var(--trust-ink)', display:'grid', placeItems:'center', boxShadow:'0 2px 10px rgba(0,0,0,0.15)'}}>
                          <Icon name="play" size={18}/>
                        </div>
                        <span style={{position:'absolute', bottom:8, left:8, padding:'2px 7px', background:'rgba(0,0,0,0.6)', color:'white', fontSize:10, fontWeight:600, borderRadius:3, display:'inline-flex', alignItems:'center', gap:3}}>
                          <Icon name="verified" size={9}/> Assessed
                        </span>
                        <span style={{position:'absolute', bottom:8, right:8, padding:'2px 6px', background:'rgba(0,0,0,0.6)', color:'white', fontSize:10, fontWeight:600, borderRadius:3}}>{v.duration}</span>
                      </>
                    ) : (
                      <div style={{textAlign:'center', color:'var(--t-ink-muted)', fontSize:11, padding:16}}>
                        <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>
                        Not recorded
                      </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}/>
                      {cat.label}
                    </div>
                    <div style={{fontSize:11, color:'var(--t-ink-muted)'}}>
                      {cat.id==='cooking' && 'Show a dish end-to-end'}
                      {cat.id==='language' && 'Intro in your languages'}
                      {cat.id==='housekeeping' && 'Clean, laundry, organize'}
                      {cat.id==='other' && 'Care, driving, specialty'}
                    </div>
                  </div>
                </div>
              );
            })}
          </div>
        </div>
      )}

      {/* Self-uploaded video — shown to ALL helpers regardless of verification.
          Officials get this in addition to their admin-recorded skill videos
          above; self/agency helpers see only this card. */}
      <div className="card-flat" style={{padding:24, marginBottom:16}}>
          <div style={{display:'flex', justifyContent:'space-between', alignItems:'flex-start', marginBottom:6, gap:12, flexWrap:'wrap'}}>
            <div>
              <h3 style={{fontSize:15, fontWeight:700, marginBottom:4}}>Self-uploaded video</h3>
              <p style={{fontSize:12, color:'var(--t-ink-muted)', marginBottom:6}}>One short clip introducing yourself. Profiles with an intro get 2.4× more employer views.</p>
              <p style={{fontSize:11, color:'var(--t-ink-muted)', display:'inline-flex', alignItems:'center', gap:6, padding:'4px 10px', background:'var(--t-bg)', border:'1px solid var(--t-line)', borderRadius:99}}>
                <Icon name="info" size={11}/>
                {(window.HM_VIDEO_HINT_FN && window.HM_VIDEO_HINT_FN()) || 'MP4 · MOV · max 150 MB · 30 sec – 3 min · 720p or higher'}
              </p>
            </div>
            <div style={{display:'flex', alignItems:'center', gap:8}}>
              <span className="chip chip-mint" style={{fontSize:11}}>{hasIntroVideo ? 'Uploaded' : 'Not yet'}</span>
            </div>
          </div>
          <div style={{display:'grid', gridTemplateColumns:'minmax(0, 360px)', gap:12, marginTop:14}}>
            <div style={{border:'1px solid var(--t-line)', borderRadius:12, overflow:'hidden', background:'var(--t-paper)'}}>
              <div style={{aspectRatio:'16/10', background: hasIntroVideo ? `linear-gradient(135deg, ${me.color}66, ${me.color}AA), radial-gradient(circle at 60% 40%, ${window.shadeColor(me.color,30)}, ${window.shadeColor(me.color,-30)})` : 'var(--t-bg)', display:'grid', placeItems:'center', position:'relative'}}>
                {hasIntroVideo ? (
                  <>
                    <div style={{width:48, height:48, borderRadius:99, background:'rgba(255,255,255,0.95)', color:'var(--trust-ink)', display:'grid', placeItems:'center', boxShadow:'0 2px 10px rgba(0,0,0,0.15)'}}>
                      <Icon name="play" size={20}/>
                    </div>
                    <span style={{position:'absolute', bottom:8, left:8, padding:'2px 7px', background:'rgba(0,0,0,0.6)', color:'white', fontSize:10, fontWeight:600, borderRadius:3, display:'inline-flex', alignItems:'center', gap:3}}>
                      <Icon name="play" size={9}/> Uploaded
                    </span>
                    <span style={{position:'absolute', bottom:8, right:8, padding:'2px 6px', background:'rgba(0,0,0,0.6)', color:'white', fontSize:10, fontWeight:600, borderRadius:3}}>{me.introVideo.duration}</span>
                  </>
                ) : (
                  <div style={{textAlign:'center', color:'var(--t-ink-muted)', fontSize:12, padding:20}}>
                    <div style={{width:44, height:44, borderRadius:99, background:'var(--t-paper)', border:'1.5px dashed var(--t-line)', display:'grid', placeItems:'center', margin:'0 auto 8px'}}>
                      <Icon name="play" size={18}/>
                    </div>
                    No intro video yet
                  </div>
                )}
              </div>
              <div style={{padding:'12px 14px 14px'}}>
                <div style={{fontSize:13, fontWeight:700, marginBottom:8}}>Self-intro</div>
                {hasIntroVideo ? (
                  <div style={{display:'flex', gap:6}}>
                    <button className="btn btn-outline btn-sm" style={{flex:1, fontSize:11, padding:'6px 8px'}}>Re-record</button>
                    <button className="btn btn-ghost btn-sm" style={{padding:'6px 8px'}} title="Delete"><Icon name="close" size={11}/></button>
                  </div>
                ) : (
                  <button className="btn btn-trust btn-sm btn-block" style={{fontSize:11, padding:'6px 8px'}}>
                    <Icon name="plus" size={11}/> Upload intro video
                  </button>
                )}
              </div>
            </div>
          </div>
          {/* Phase 2: re-enable the "Book a Surabaya assessment" promo callout once
              the verification feature ships. */}
        </div>

      {/* MVP: References management card removed — helpers no longer upload
          reference files. Resume form keeps a per-experience Yes/No flag, which
          renders on the public detail page as a single Reference: Yes/No row.
          Restore this card if helper-managed references come back into scope. */}

      {/* Verification & documents block hidden until the verification feature
          is built out. Restore the previous JSX from git history when ready. */}
    </div>
  );
};

// ===== Matches (Jobs for you) =====
const HelperMatches = ({ go, me, matchedJobs }) => {
  const withScores = matchedJobs.map((j, i) => ({
    j,
    score: 96 - i * 3,
    reasons: [
      j.reqLanguages?.includes(me.typedSkills?.languages?.[0]) && 'Language match',
      j.reqMainSkills?.find(s => me.typedSkills?.mainSkills?.includes(s)) && `${j.reqMainSkills.find(s => me.typedSkills?.mainSkills?.includes(s))} experience`,
      j.market === 'Taiwan' && 'Your target market',
      'Salary above your ask',
    ].filter(Boolean).slice(0, 3),
  }));

  return (
    <div>
      <div className="dash-header">
        <h1>Jobs for you</h1>
        <p>Families hiring now who match your profile. Ranked by how well your skills and experience fit.</p>
      </div>

      <div className="card-flat" style={{padding:18, marginBottom:20, display:'flex', alignItems:'center', gap:14, background:'var(--trust-bg)', border:'1px solid var(--trust-soft)'}}>
        <div style={{width:36, height:36, borderRadius:8, background:'var(--trust)', color:'white', display:'grid', placeItems:'center', flexShrink:0}}>
          <Icon name="sparkle" size={16}/>
        </div>
        <div style={{flex:1, minWidth:0}}>
          <div style={{fontSize:13, fontWeight:700, color:'var(--trust-ink)', marginBottom:2}}>Matched to your profile</div>
          <div style={{fontSize:12, color:'var(--t-ink-muted)'}}>Updated daily based on your skills, languages, target markets, and salary expectations.</div>
        </div>
        <button className="btn btn-outline btn-sm" onClick={()=>go('create-profile')}>
          <Icon name="edit" size={13}/> Edit preferences
        </button>
      </div>

      <div style={{display:'flex', flexDirection:'column', gap:14}}>
        {withScores.map(({j, score, reasons}) => (
          <div key={j.id} className="card" style={{padding:22, cursor:'pointer', display:'grid', gridTemplateColumns:'1fr auto', gap:20}} onClick={()=>go(`job:${j.id}`)}>
            <div style={{minWidth:0}}>
              <div style={{display:'flex', gap:8, marginBottom:8, flexWrap:'wrap'}}>
                <span className="chip chip-coral" style={{fontSize:11}}>{j.market}</span>
                <span className="chip chip-ghost" style={{fontSize:11}}>{j.jobType}</span>
                <span className="chip chip-ghost" style={{fontSize:11}}>{j.type}</span>
              </div>
              <div style={{fontSize:17, fontWeight:700, marginBottom:4, letterSpacing:'-0.01em'}}>{j.title}</div>
              <div style={{fontSize:13, color:'var(--t-ink-muted)', marginBottom:10}}>{j.city} · {j.familySize} · Posted {j.posted}</div>
              <div style={{display:'flex', flexWrap:'wrap', gap:14, paddingTop:10, borderTop:'1px solid var(--t-line)'}}>
                {reasons.map((r, i) => (
                  <div key={i} style={{fontSize:12, color:'var(--t-ink)', display:'flex', alignItems:'center', gap:6, fontWeight:500}}>
                    <Icon name="check" size={12} style={{color:'var(--trust)'}}/>
                    {r}
                  </div>
                ))}
              </div>
            </div>
            <div style={{textAlign:'right', display:'flex', flexDirection:'column', alignItems:'flex-end', gap:10, minWidth:140}}>
              <div>
                <div style={{fontSize:28, fontWeight:700, color:'var(--trust-ink)', letterSpacing:'-0.02em', lineHeight:1}}>{score}%</div>
                <div style={{fontSize:10, color:'var(--t-ink-muted)', textTransform:'uppercase', letterSpacing:'0.08em', fontWeight:700, marginTop:2}}>Match</div>
              </div>
              <div style={{fontSize:14, fontWeight:700, color:'var(--t-ink)'}}>{j.salary}</div>
              <button className="btn btn-trust btn-sm" onClick={(e)=>{e.stopPropagation(); go(`job:${j.id}`);}}>Apply</button>
            </div>
          </div>
        ))}
      </div>
    </div>
  );
};

// ===== Applications =====
// Each application links to (1) the public job post via View job, and
// (2) the relevant message thread via Message — but ONLY when the employer
// has reached out (a.threadId is set). Helpers cannot initiate threads —
// they can only reply within a thread the employer already started. This
// is the asymmetric messaging rule (see DOMAIN_MODEL.md §4.13 + §4.15).
//
// Status values are employer-driven only: 'Awaiting employer review' →
// 'Application viewed' → 'Shortlisted by employer' → 'Contacted by
// employer' (or terminal: rejected / withdrawn). No "schedule interview"
// feature in v1.
const HelperApplications = ({ go, applications }) => {
  const { jobs } = window.MOCK_DATA;
  const getJob = id => jobs.find(j => j.id === id);
  return (
    <div>
      <div className="dash-header">
        <h1>Applications</h1>
        <p>Track the status of every job you've applied to. The employer will reach out if interested.</p>
      </div>
      <div style={{display:'flex', flexDirection:'column', gap:14}}>
        {applications.map((a, i) => {
          const j = getJob(a.jobId);
          if (!j) return null;
          const badgeColor = {
            trust: { bg: 'var(--trust-bg)', fg: 'var(--trust-deep)' },
            mint:  { bg: 'var(--mint-bg, #DCF5E6)', fg: 'var(--mint-dark, #1F8A4C)' },
            sand:  { bg: 'var(--t-warm)', fg: 'var(--t-warm-ink)' },
            ghost: { bg: 'var(--t-bg)', fg: 'var(--t-ink-muted)' },
          }[a.badge] || { bg: 'var(--t-bg)', fg: 'var(--t-ink-muted)' };
          return (
            <div key={i} className="card-flat" style={{padding:20, display:'flex', gap:18, alignItems:'center', flexWrap:'wrap'}}>
              <div style={{width:44, height:44, borderRadius:10, background:'var(--trust-bg)', color:'var(--trust)', display:'grid', placeItems:'center', flexShrink:0}}>
                <Icon name="briefcase" size={18}/>
              </div>
              <div style={{flex:'1 1 220px', minWidth:0}}>
                <div style={{fontSize:15, fontWeight:600, marginBottom:4}}>{j.title}</div>
                <div style={{fontSize:12, color:'var(--t-ink-muted)', marginBottom:6}}>{j.market} · {j.city} · {j.salary}</div>
                <span style={{display:'inline-block', padding:'3px 10px', fontSize:11, fontWeight:600, borderRadius:99, background:badgeColor.bg, color:badgeColor.fg}}>
                  {a.status}
                </span>
              </div>
              <div style={{textAlign:'right', fontSize:11, color:'var(--t-ink-muted)', minWidth:80}}>{a.when}</div>
              <div style={{display:'flex', gap:8, flexShrink:0}}>
                {/* Message button only when employer has reached out (= thread exists). */}
                {a.threadId && (
                  <button className="btn btn-outline btn-sm" onClick={()=>go(`inbox:${a.threadId}`)}>
                    <Icon name="chat" size={13}/> Message
                  </button>
                )}
                <button className="btn btn-outline btn-sm" onClick={()=>go(`job:${j.id}`)}>View job</button>
              </div>
            </div>
          );
        })}
      </div>
    </div>
  );
};

// ===== Saved =====
// Horizontal card layout — JobCard's grid layout overflowed inside the helper
// dashboard's narrower main column. Mirrors the Applications card layout for
// visual consistency across the helper sections.
const HelperSaved = ({ go, jobs }) => (
  <div>
    <div className="dash-header">
      <h1>Saved jobs</h1>
      <p>{jobs.length} jobs saved for later.</p>
    </div>
    <div style={{display:'flex', flexDirection:'column', gap:14}}>
      {jobs.map(j => (
        <div key={j.id} className="card-flat" style={{padding:20, display:'flex', gap:18, alignItems:'center'}}>
          <div style={{width:44, height:44, borderRadius:10, background:'var(--coral-bg)', color:'var(--coral-dark)', display:'grid', placeItems:'center', flexShrink:0}}>
            <Icon name="heart" size={18}/>
          </div>
          <div style={{flex:1, minWidth:0}}>
            <div style={{display:'flex', gap:6, marginBottom:6, flexWrap:'wrap'}}>
              <span className="chip chip-coral" style={{fontSize:11}}>{j.market}</span>
              <span className="chip chip-ghost" style={{fontSize:11}}>{j.type}</span>
            </div>
            <div style={{fontSize:15, fontWeight:600, marginBottom:2, lineHeight:1.3}}>{window.pickLocalised(j, 'title') || j.title}</div>
            <div style={{fontSize:12, color:'var(--t-ink-muted)', display:'flex', gap:10, flexWrap:'wrap'}}>
              <span style={{display:'inline-flex', alignItems:'center', gap:4}}><Icon name="location" size={11}/> {j.city}</span>
              <span style={{display:'inline-flex', alignItems:'center', gap:4}}><Icon name="clock" size={11}/> {j.posted}</span>
            </div>
          </div>
          <div style={{textAlign:'right', minWidth:100, flexShrink:0}}>
            <div style={{fontSize:14, fontWeight:700, color:'var(--t-ink)'}}>{j.salary}</div>
          </div>
          <button className="btn btn-outline btn-sm" onClick={()=>go(`job:${j.id}`)}>View job</button>
        </div>
      ))}
    </div>
  </div>
);

// ===== Earnings (delegated to pages-helper-referral.jsx) =====
const HelperEarnings = () => {
  if (typeof window.HelperReferralWallet === 'function') return <window.HelperReferralWallet/>;
  return <div style={{padding:40, color:'var(--t-ink-muted)'}}>Loading…</div>;
};

// ===== Account =====
const HelperAccount = ({ me }) => {
  const { lang, setLang, LANG_META, t } = window.useI18n();
  const [tab, setTab] = React.useState('contact');
  const tabs = [
    {id:'contact', label:'Contact info'},
    {id:'language', label:'Language'},
    {id:'notifications', label: t('dash.account.tab.notifications')},
    {id:'security', label:'Security'},
  ];
  const [notifyPrefs, setNotifyPrefs] = React.useState({ newsletter: true });
  return (
    <div>
      <div className="dash-header">
        <h1>Account</h1>
        <p>Manage your contact info, language, and security.</p>
      </div>
      <div style={{display:'grid', gridTemplateColumns:'220px 1fr', gap:24, alignItems:'start'}}>
        <div style={{display:'flex', flexDirection:'column', gap:2, background:'var(--t-paper)', border:'1px solid var(--t-line)', borderRadius:12, padding:8}}>
          {tabs.map(t => (
            <button key={t.id} onClick={()=>setTab(t.id)} style={{
              textAlign:'left', padding:'10px 12px', border:'none', background: tab===t.id ? 'var(--trust-bg)' : 'transparent',
              color: tab===t.id ? 'var(--trust-ink)' : 'var(--t-ink)', fontWeight: tab===t.id ? 600 : 500,
              fontSize:13, borderRadius:8, cursor:'pointer', fontFamily:'inherit'
            }}>{t.label}</button>
          ))}
        </div>
        <div style={{display:'flex', flexDirection:'column', gap:16}}>
          {tab === 'contact' && (
            <div className="card-flat" style={{padding:24}}>
              <h3 style={{fontSize:15, fontWeight:700, marginBottom:4}}>Contact info</h3>
              <p style={{fontSize:12, color:'var(--t-ink-muted)', marginBottom:16}}>Only shown to employers after they subscribe and start a conversation.</p>
              <div style={{display:'grid', gridTemplateColumns:'1fr 1fr', gap:14}}>
                <div><div className="label">Full name</div><input className="input" defaultValue={me.name}/></div>
                <div><div className="label">Email</div><input className="input" defaultValue="purwanti@example.id"/></div>
                <div><div className="label">Phone (WhatsApp)</div><input className="input" defaultValue="+62 812 3456 7890"/></div>
                <div><div className="label">Current location</div><input className="input" defaultValue={`${me.city}, ${me.nationality}`}/></div>
              </div>
            </div>
          )}

          {tab === 'language' && (
            <div className="card-flat" style={{padding:24}}>
              <h3 style={{fontSize:15, fontWeight:700, marginBottom:16}}>Display language</h3>
              {/* Wires straight into the global i18n engine — picking a row
                  sets window.i18n.lang and persists it (also drives the
                  header LangSwitcher). Options stay in sync with
                  hm-i18n.js's SUPPORTED list. */}
              <div style={{display:'flex', flexDirection:'column', gap:10}}>
                {Object.values(LANG_META).map(meta => {
                  const active = lang === meta.code;
                  return (
                    <label
                      key={meta.code}
                      style={{display:'flex', alignItems:'center', gap:12, padding:'12px 14px', border:`1.5px solid ${active ? 'var(--trust)' : 'var(--t-line)'}`, borderRadius:10, cursor:'pointer', background: active ? 'var(--trust-bg)' : 'var(--t-paper)'}}
                    >
                      <input
                        type="radio"
                        name="lang"
                        checked={active}
                        onChange={() => setLang(meta.code)}
                      />
                      <span style={{fontSize:18}}>{meta.flag}</span>
                      <span style={{fontSize:14, fontWeight:500}}>{meta.label}</span>
                    </label>
                  );
                })}
              </div>
            </div>
          )}

          {tab === 'notifications' && (
            <div className="card-flat" style={{padding:24}}>
              <h3 style={{fontSize:15, fontWeight:700, marginBottom:4}}>{t('dash.account.notifications.heading')}</h3>
              <p style={{fontSize:12, color:'var(--t-ink-muted)', marginBottom:16}}>{t('dash.account.notifications.subtitle')}</p>
              <div style={{display:'grid', gridTemplateColumns:'1fr auto', alignItems:'center', padding:'14px 0', fontSize:13, gap:16}}>
                <div style={{fontWeight:500}}>{t('dash.account.notifications.row.newsletter')}</div>
                <Toggle
                  checked={notifyPrefs.newsletter}
                  onChange={(v) => setNotifyPrefs(p => ({ ...p, newsletter: v }))}
                  ariaLabel={t('dash.account.notifications.row.newsletter')}
                />
              </div>
            </div>
          )}

          {tab === 'security' && (
            <>
              <div className="card-flat" style={{padding:24}}>
                <h3 style={{fontSize:15, fontWeight:700, marginBottom:14}}>Password</h3>
                <div style={{display:'grid', gridTemplateColumns:'1fr 1fr', gap:14}}>
                  <div><div className="label">New password</div><input className="input" type="password" placeholder="••••••••"/></div>
                  <div><div className="label">Confirm new password</div><input className="input" type="password" placeholder="••••••••"/></div>
                </div>
                <button className="btn btn-outline btn-sm" style={{marginTop:14}}>Update password</button>
              </div>
              <div className="card-flat" style={{padding:24, borderColor:'var(--coral-soft, #F8D3C8)'}}>
                <h3 style={{fontSize:15, fontWeight:700, marginBottom:4, color:'var(--coral)'}}>Deactivate profile</h3>
                <p style={{fontSize:12, color:'var(--t-ink-muted)', marginBottom:14}}>Hides your profile from search while keeping your application history. You can reactivate anytime.</p>
                <button className="btn btn-outline btn-sm" style={{color:'var(--coral)', borderColor:'var(--coral)'}}>Deactivate</button>
              </div>
            </>
          )}
        </div>
      </div>
    </div>
  );
};

Object.assign(window, { HelperDashPage });
