// Dashboard + Inbox pages

const DashSectionPicker = ({ section, setSection, items }) => {
  const { t } = window.useI18n();
  const [open, setOpen] = React.useState(false);
  const ref = React.useRef(null);
  React.useEffect(() => {
    const onDown = (e) => { if (ref.current && !ref.current.contains(e.target)) setOpen(false); };
    document.addEventListener('pointerdown', onDown);
    return () => document.removeEventListener('pointerdown', onDown);
  }, []);
  const current = items.find(n => n.id === section) || items[0];
  return (
    <div className="dash-section-picker" ref={ref}>
      <button
        className="dash-section-picker-trigger"
        aria-expanded={open}
        aria-haspopup="listbox"
        onClick={() => setOpen(o => !o)}
      >
        <div style={{display:'flex', alignItems:'center', gap:10, minWidth:0, flex:1}}>
          <div className="dash-section-picker-icon"><Icon name={current.icon} size={16}/></div>
          <div style={{display:'flex', flexDirection:'column', alignItems:'flex-start', minWidth:0, flex:1, overflow:'hidden'}}>
            <div style={{fontSize:10, color:'var(--t-ink-muted)', fontWeight:600, textTransform:'uppercase', letterSpacing:'0.08em', lineHeight:1.2, whiteSpace:'nowrap'}}>{t('dash.sectionLabel')}</div>
            <div style={{fontSize:15, fontWeight:700, lineHeight:1.2, whiteSpace:'nowrap', overflow:'hidden', textOverflow:'ellipsis', maxWidth:'100%'}}>{current.label}</div>
          </div>
        </div>
        <div style={{display:'flex', alignItems:'center', gap:8}}>
          {current.count != null && <span className="badge-count">{current.count}</span>}
          <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" style={{transition:'transform .2s', transform: open ? 'rotate(180deg)' : 'none', opacity:0.6}}>
            <polyline points="6 9 12 15 18 9"/>
          </svg>
        </div>
      </button>
      {open && (
        <div className="dash-section-picker-menu" role="listbox">
          {items.map(n => (
            <button
              key={n.id}
              role="option"
              aria-selected={section === n.id}
              className={`dash-section-picker-item ${section === n.id ? 'active' : ''}`}
              onClick={() => { setSection(n.id); setOpen(false); }}
            >
              <Icon name={n.icon} size={16}/>
              <span style={{flex:1, textAlign:'left'}}>{n.label}</span>
              {n.count != null && <span className="badge-count">{n.count}</span>}
              {section === n.id && <Icon name="check" size={14} style={{color:'var(--trust)'}}/>}
            </button>
          ))}
        </div>
      )}
    </div>
  );
};

const DashPage = ({ go, favs, subscription, logout, me }) => {
  const { t } = window.useI18n();
  const [section, setSection] = React.useState('overview');
  const { candidates, jobs } = window.MOCK_DATA;
  const shortlisted = candidates.filter(c => favs.includes(c.id));
  const myJobs = jobs.slice(0, 2);
  const userName = getUserDisplayName(me);
  const userFirstName = userName.split(/\s+/)[0] || userName;
  const userInitials = getUserInitials(me);

  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}} className="dash-profile-card">
          <div style={{width:40, height:40, borderRadius:99, background:'linear-gradient(135deg, #E8856A, #C0634B)', color:'white', display:'grid', placeItems:'center', fontWeight:700, fontSize:14}}>{userInitials}</div>
          <div style={{minWidth:0}}>
            <div style={{fontSize:13, fontWeight:600}}>{userName}</div>
            <div style={{fontSize:11, color:'var(--t-ink-muted)', display:'flex', alignItems:'center', gap:4}}>
              <Icon name="shield" size={11}/>
              {subscription === 'premium' ? t('dash.memberLevel.premium') : subscription === 'standard' ? t('dash.memberLevel.standard') : t('dash.memberLevel.free')}
            </div>
          </div>
        </div>
        <div className="dash-nav">
          {[
            {id:'overview', label: t('dash.nav.overview'), icon:'home'},
            {id:'matches',  label: t('dash.nav.matches'), icon:'sparkle'},
            {id:'shortlist',label: t('dash.nav.shortlist'), icon:'heart', count:shortlisted.length},
            {id:'jobs',     label: t('dash.nav.myJobs'), icon:'briefcase', count:myJobs.length},
            {id:'settings', label: t('dash.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>

        {/* Mobile: section picker dropdown (replaces sidebar nav) */}
        <DashSectionPicker
          section={section}
          setSection={setSection}
          items={[
            {id:'overview', label:'Overview', icon:'home'},
            {id:'matches', label:'Matches', icon:'sparkle'},
            {id:'shortlist', label:'Shortlist', icon:'heart', count:shortlisted.length},
            {id:'jobs', label:'My job posts', icon:'briefcase', count:myJobs.length},
            {id:'settings', label:'Account', icon:'settings'},
          ]}
        />
        <div style={{marginTop:20, padding:16, background:'var(--trust-bg)', border:'1px solid var(--trust-soft)', borderRadius:12}} className="dash-agencies-card">
          <div style={{fontSize:12, fontWeight:700, color:'var(--trust-ink)', marginBottom:6, display:'flex', alignItems:'center', gap:6}}>
            <Icon name="shield" size={12}/> {t('dash.agencies.title')}
          </div>
          <div style={{fontSize:12, color:'var(--t-ink-muted)', lineHeight:1.5, marginBottom:10}}>
            {t('dash.agencies.body')}
          </div>
          <button className="btn btn-outline btn-sm btn-block" style={{fontSize:12}} onClick={()=>go('agencies')}>{t('dash.agencies.cta')}</button>
        </div>
        {logout && (
          <button
            onClick={logout}
            className="dash-nav-item dash-sign-out"
            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 === 'overview' && <OverviewSection go={go} shortlisted={shortlisted} myJobs={myJobs} setSection={setSection} userFirstName={userFirstName}/>}
        {section === 'matches' && <MatchesSection go={go} subscription={subscription} myJobs={myJobs}/>}
        {section === 'shortlist' && <ShortlistSection go={go} shortlisted={shortlisted} subscription={subscription}/>}
        {section === 'jobs' && <MyJobsSection go={go} myJobs={myJobs}/>}
        {section === 'settings' && <AccountSection subscription={subscription} me={me} userName={userName}/>}
      </div>
    </div>
  );
};

const OverviewSection = ({ go, shortlisted, myJobs, setSection, userFirstName }) => {
  const { t } = window.useI18n();
  const todos = [
    {id:1, title:'Complete household information form', sub:'Helps us match you with the right helpers', cta:'Continue', action:()=>setSection('settings'), urgent:false},
    {id:2, title:'Upload your employer ID', sub:'Required before you can sign a contract', cta:'Upload', action:()=>setSection('settings'), urgent:false},
  ];
  return (
    <div>
      <div className="dash-header">
        <h1>{t('dash.header.welcomeBack', {name: userFirstName || 'Wei-Chen'})}</h1>
        <p>{t('dash.header.unreadAndTodo', {unread: 0, todo: todos.length})}</p>
      </div>

      {/* Stats */}
      <div className="stat-grid">
        <div className="stat-tile trust-accent">
          <div className="stat-label">{t('dash.stat.shortlisted.label')}</div>
          <div className="stat-value">{shortlisted.length}</div>
          <div className="stat-sub">{t('dash.stat.shortlisted.sub')}</div>
        </div>
        <div className="stat-tile">
          <div className="stat-label">{t('dash.stat.activeJobs.label')}</div>
          <div className="stat-value">{myJobs.length}</div>
          <div className="stat-sub">{t('dash.stat.activeJobs.sub')}</div>
        </div>
        <div className="stat-tile">
          <div className="stat-label">{t('dash.stat.newMatches.label')}</div>
          <div className="stat-value">0</div>
          <div className="stat-sub">{t('dash.stat.newMatches.sub')}</div>
        </div>
        <div className="stat-tile">
          <div className="stat-label">{t('dash.stat.unread.label')}</div>
          <div className="stat-value" style={{color:'var(--coral)'}}>0</div>
          <div className="stat-sub">{t('dash.stat.unread.sub')}</div>
        </div>
      </div>

      {/* Things To-Do */}
      <div className="card-flat" style={{padding:24, marginBottom:24}}>
        <div style={{display:'flex', justifyContent:'space-between', alignItems:'baseline', marginBottom:16}}>
          <div>
            <div style={{fontSize:12, color:'var(--trust-ink)', fontWeight:700, textTransform:'uppercase', letterSpacing:'0.08em', marginBottom:4}}>{t('dash.todo.eyebrow')}</div>
            <h3 style={{fontSize:20, fontWeight:600, letterSpacing:'-0.01em'}}>{t('dash.todo.heading', {n: todos.length})}</h3>
          </div>
        </div>
        <div style={{display:'flex', flexDirection:'column'}}>
          {todos.map((t, i) => (
            <div key={t.id} style={{display:'flex', gap:14, alignItems:'center', padding:'14px 0', borderBottom: i < todos.length-1 ? '1px solid var(--t-line)' : 'none'}}>
              <div style={{width:32, height:32, borderRadius:8, background: t.urgent ? 'var(--coral-soft, #FDECE7)' : 'var(--trust-bg)', color: t.urgent ? 'var(--coral)' : 'var(--trust)', display:'grid', placeItems:'center', flexShrink:0}}>
                <Icon name={t.urgent ? 'bell' : 'check'} size={15}/>
              </div>
              <div style={{flex:1, minWidth:0}}>
                <div style={{fontSize:14, fontWeight:600, marginBottom:2}}>{t.title}</div>
                <div style={{fontSize:12, color:'var(--t-ink-muted)'}}>{t.sub}</div>
              </div>
              <button className={`btn ${t.urgent ? 'btn-trust' : 'btn-outline'} btn-sm`} onClick={t.action}>{t.cta}</button>
            </div>
          ))}
        </div>
      </div>

      {/* Two-column: Recent activity + Upcoming */}
      <div className="dash-two-col" style={{display:'grid', gridTemplateColumns:'1.4fr 1fr', gap:24, marginBottom:24}}>
        <div className="card-flat" style={{padding:24}}>
          <div style={{display:'flex', justifyContent:'space-between', alignItems:'center', marginBottom:16}}>
            <h3 style={{fontSize:16, fontWeight:700}}>{t('dash.recentActivity')}</h3>
            <button className="btn btn-ghost btn-sm" onClick={()=>go('inbox')}>{t('dash.openInbox')} <Icon name="arrow" size={13}/></button>
          </div>
          <div style={{display:'flex', flexDirection:'column', gap:12}}>
            <div style={{fontSize:13, color:'var(--t-ink-muted)', padding:'18px 0'}}>No candidate activity yet.</div>
          </div>
        </div>

        <div className="card-flat" style={{padding:24}}>
          <div style={{display:'flex', justifyContent:'space-between', alignItems:'baseline', marginBottom:16}}>
            <h3 style={{fontSize:16, fontWeight:700}}>{t('dash.topMatches')}</h3>
            <button className="btn btn-ghost btn-sm" onClick={()=>setSection('matches')}>{t('dash.seeAll')} <Icon name="arrow" size={13}/></button>
          </div>
          <div style={{display:'flex', flexDirection:'column', gap:14}}>
            <div style={{fontSize:13, color:'var(--t-ink-muted)', padding:'18px 0'}}>No candidate matches yet.</div>
          </div>
        </div>
      </div>

      {/* Shortlist preview */}
      {shortlisted.length > 0 && (
        <div style={{marginTop:8}}>
          <div style={{display:'flex', justifyContent:'space-between', alignItems:'baseline', marginBottom:16}}>
            <h3 style={{fontSize:18, fontWeight:700}}>{t('dash.yourShortlist')}</h3>
            <button className="btn btn-ghost btn-sm" onClick={()=>go('candidates')}>{t('dash.browseMore')} <Icon name="arrow" size={13}/></button>
          </div>
          <div style={{display:'grid', gridTemplateColumns:'repeat(auto-fill, minmax(260px, 1fr))', gap:16}}>
            {shortlisted.slice(0, 4).map(c => (
              <div key={c.id} className="card" onClick={()=>go(`candidate:${c.id}`)} style={{cursor:'pointer', padding:16, display:'flex', gap:12, alignItems:'center'}}>
                <Avatar person={c} size={52}/>
                <div style={{flex:1, minWidth:0}}>
                  <div style={{fontWeight:600, fontSize:14}}>{c.name}</div>
                  <div style={{fontSize:12, color:'var(--t-ink-muted)'}}>{c.jobTypes[0]} · {c.flag}</div>
                </div>
                <TierBadge tier={c.tier}/>
              </div>
            ))}
          </div>
        </div>
      )}
    </div>
  );
};

// ===== Matches =====
// Match list is recomputed against whichever job is currently selected. When
// the employer has more than one job post, a "change job" outline button +
// modal lets them switch between posts. The Run-search primary button hands
// off to the candidates list (production: would push the job's criteria into
// the list filters; prototype just navigates).
const MatchesSection = ({ go, subscription, myJobs }) => {
  const { t } = window.useI18n();
  const { candidates } = window.MOCK_DATA;
  const [selectedJobId, setSelectedJobId] = React.useState(myJobs[0]?.id);
  const [showJobPicker, setShowJobPicker] = React.useState(false);
  const selectedJob = myJobs.find(j => j.id === selectedJobId) || myJobs[0];
  const matches = candidates.slice(0, 9).map((c, i) => ({
    c,
    score: 96 - i * 3,
    reasons: [
      i === 0 ? 'All 3 required skills · 15 yrs experience' : null,
      i === 1 ? 'Mandarin + English · Elder care certified' : null,
      i === 2 ? 'Newborn specialist · Works with pets' : null,
      c.skills?.[0] && `${c.skills[0]} experience`,
      c.languages?.includes?.('Mandarin') && 'Mandarin speaker',
      c.tier === 'A' && 'Top-tier assessment',
    ].filter(Boolean).slice(0, 2),
  }));

  return (
    <div>
      <div className="dash-header">
        <h1>{t('dash.matches.title')}</h1>
        <p>{t('dash.matches.sub')}</p>
      </div>

      <div className="card-flat" style={{padding:18, marginBottom:24, display:'flex', alignItems:'center', gap:14, background:'var(--trust-bg)', border:'1px solid var(--trust-soft)', flexWrap:'wrap'}}>
        <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:200}}>
          <div style={{fontSize:13, fontWeight:700, color:'var(--trust-ink)', marginBottom:2}}>{t('dash.matches.matchedTo', {title: window.pickLocalised(selectedJob, 'title') || selectedJob.title})}</div>
          <div style={{fontSize:12, color:'var(--t-ink-muted)'}}>{t('dash.matches.matchedSub')}</div>
        </div>
        <div style={{display:'flex', gap:8, flexShrink:0}}>
          {myJobs.length > 1 && (
            <button className="btn btn-outline btn-sm" onClick={()=>setShowJobPicker(true)}>
              <Icon name="edit" size={13}/> {t('dash.matches.changeJob')}
            </button>
          )}
          <button className="btn btn-primary btn-sm" onClick={()=>go('candidates')}>{t('dash.matches.runSearch')}</button>
        </div>
      </div>

      <div style={{display:'grid', gridTemplateColumns:'repeat(auto-fill, minmax(320px, 1fr))', gap:16}}>
        {matches.map(({c, score, reasons}) => (
          <div key={c.id} className="card" style={{padding:20, cursor:'pointer'}} onClick={()=>go(`candidate:${c.id}`)}>
            <div style={{display:'flex', gap:12, alignItems:'center', marginBottom:14}}>
              <Avatar person={c} size={52}/>
              <div style={{flex:1, minWidth:0}}>
                <div style={{fontSize:15, fontWeight:700, display:'flex', alignItems:'center', gap:6}}>
                  {c.name}
                  <Icon name="verified" size={13} style={{color:'var(--trust)'}}/>
                </div>
                <div style={{fontSize:12, color:'var(--t-ink-muted)'}}>{c.age} · {c.flag} {c.nationality}</div>
              </div>
              <div style={{textAlign:'right'}}>
                <div style={{fontSize:22, 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:600, marginTop:2}}>{t('dash.matches.matchPercent')}</div>
              </div>
            </div>
            <div style={{display:'flex', flexDirection:'column', gap:6, paddingTop:14, 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}}>
                  <Icon name="check" size={12} style={{color:'var(--trust)'}}/>
                  {r}
                </div>
              ))}
            </div>
          </div>
        ))}
      </div>
      {matches.length === 0 && (
        <div className="card-flat" style={{padding:40, textAlign:'center', color:'var(--t-ink-muted)'}}>
          No candidate matches yet.
        </div>
      )}

      {showJobPicker && (
        <div onClick={()=>setShowJobPicker(false)} 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:520, width:'100%', padding:32, background:'var(--t-paper)', borderRadius:16, boxShadow:'0 24px 60px rgba(0,0,0,0.3)'}}>
            <h2 className="display" style={{fontSize:22, marginBottom:6}}>{t('dash.matches.pickJob.title')}</h2>
            <p style={{color:'var(--t-ink-soft)', fontSize:13.5, lineHeight:1.55, marginBottom:20}}>{t('dash.matches.pickJob.sub')}</p>
            <div style={{display:'flex', flexDirection:'column', gap:8, marginBottom:20}}>
              {myJobs.map(j => {
                const active = j.id === selectedJobId;
                return (
                  <button
                    key={j.id}
                    onClick={() => { setSelectedJobId(j.id); setShowJobPicker(false); }}
                    style={{
                      textAlign:'left', padding:'14px 16px',
                      border:`1.5px solid ${active ? 'var(--trust)' : 'var(--t-line)'}`,
                      borderRadius:10, background: active ? 'var(--trust-bg)' : 'var(--t-paper)',
                      cursor:'pointer', display:'flex', alignItems:'center', gap:12,
                    }}
                  >
                    <div style={{flex:1, minWidth:0}}>
                      <div style={{fontWeight:600, fontSize:14.5, marginBottom:3}}>{window.pickLocalised(j, 'title') || j.title}</div>
                      <div style={{fontSize:12, color:'var(--t-ink-muted)'}}>{j.city}, {j.market} · {j.salary}</div>
                    </div>
                    {active && <Icon name="check" size={16} style={{color:'var(--trust)', flexShrink:0}}/>}
                  </button>
                );
              })}
            </div>
            <div style={{display:'flex', justifyContent:'flex-end'}}>
              <button className="btn btn-ghost" onClick={()=>setShowJobPicker(false)}>{t('dash.matches.pickJob.cancel')}</button>
            </div>
          </div>
        </div>
      )}
    </div>
  );
};

const ShortlistSection = ({ go, shortlisted, subscription }) => {
  const { t } = window.useI18n();
  return (
  <div>
    <div className="dash-header">
      <h1>{t('dash.shortlist.title')}</h1>
      <p>{t('dash.shortlist.sub', {n: shortlisted.length})}</p>
    </div>
    {shortlisted.length === 0 ? (
      <div className="card-flat" style={{padding:48, textAlign:'center'}}>
        <div style={{fontSize:16, fontWeight:600, marginBottom:6}}>{t('dash.shortlist.emptyTitle')}</div>
        <div style={{fontSize:14, color:'var(--t-ink-muted)', marginBottom:20}}>{t('dash.shortlist.emptyBody')}</div>
        <button className="btn btn-primary" onClick={()=>go('candidates')}>{t('dash.shortlist.emptyCta')}</button>
      </div>
    ) : (
      <div style={{display:'grid', gridTemplateColumns:'repeat(auto-fill, minmax(300px, 1fr))', gap:20}}>
        {shortlisted.map(c => (
          <CandidateCard key={c.id} candidate={c} go={go} onFav={()=>{}} isFav={true} subscription={subscription}/>
        ))}
      </div>
    )}
  </div>
  );
};

// ===== My Jobs =====
// Per-card actions: View post (existing), Publish/Unpublish toggle, Edit,
// Delete (with confirmation modal). Local state holds publish + delete results
// since MOCK_DATA isn't mutated — production would call backend APIs and
// re-fetch.
const MyJobsSection = ({ go, myJobs }) => {
  const { t } = window.useI18n();
  const [unpublishedIds, setUnpublishedIds] = React.useState(() => new Set());
  const [deletedIds, setDeletedIds] = React.useState(() => new Set());
  const [confirmDeleteId, setConfirmDeleteId] = React.useState(null);
  const visible = myJobs.filter(j => !deletedIds.has(j.id));
  const togglePublish = (id) => setUnpublishedIds(prev => {
    const next = new Set(prev);
    if (next.has(id)) next.delete(id); else next.add(id);
    return next;
  });
  const confirmDelete = () => {
    setDeletedIds(prev => new Set(prev).add(confirmDeleteId));
    setConfirmDeleteId(null);
  };
  const confirmJob = visible.find(j => j.id === confirmDeleteId) || myJobs.find(j => j.id === confirmDeleteId);
  return (
  <div>
    <div style={{display:'flex', justifyContent:'space-between', alignItems:'center', marginBottom:24}}>
      <div>
        <h1 style={{fontSize:32, fontWeight:700, letterSpacing:'-0.02em', marginBottom:4}}>{t('dash.myJobs.title')}</h1>
        <p style={{color:'var(--t-ink-muted)', fontSize:15}}>{t('dash.myJobs.sub', {active: visible.filter(j=>!unpublishedIds.has(j.id)).length, applicants: visible.reduce((s,j)=>s+j.applicants,0)})}</p>
      </div>
      <button className="btn btn-primary" onClick={() => go('post-job')}><Icon name="briefcase" size={15}/> {t('dash.myJobs.postNew')}</button>
    </div>
    <div style={{display:'flex', flexDirection:'column', gap:16}}>
      {visible.map(j => {
        const isPublished = !unpublishedIds.has(j.id);
        return (
        <div key={j.id} className="card-flat" style={{padding:24}}>
          <div style={{display:'flex', justifyContent:'space-between', gap:16, marginBottom:14, flexWrap:'wrap'}}>
            <div style={{flex:1, minWidth:200}}>
              <div style={{display:'flex', gap:8, marginBottom:8}}>
                <span className={isPublished ? 'chip chip-mint' : 'chip chip-ghost'} style={{fontSize:11}}>
                  {isPublished ? t('dash.myJobs.live') : t('dash.myJobs.unpublished')}
                </span>
                <span className="chip chip-ghost" style={{fontSize:11}}>{j.market}</span>
              </div>
              <div style={{fontWeight:600, fontSize:18, marginBottom:4}}>{window.pickLocalised(j, 'title') || j.title}</div>
              <div style={{fontSize:13, color:'var(--t-ink-muted)'}}>{t('dash.myJobs.postedAt', {posted: j.posted, salary: j.salary})}</div>
            </div>
            <div style={{display:'flex', gap:8, flexWrap:'wrap', alignItems:'flex-start'}}>
              <button className="btn btn-outline btn-sm" onClick={()=>togglePublish(j.id)}>
                {isPublished ? t('dash.myJobs.unpublish') : t('dash.myJobs.publish')}
              </button>
              <button className="btn btn-outline btn-sm" onClick={()=>go('post-job')} aria-label={t('dash.myJobs.edit')}>
                <Icon name="edit" size={13}/> {t('dash.myJobs.edit')}
              </button>
              <button
                className="btn btn-outline btn-sm"
                onClick={()=>setConfirmDeleteId(j.id)}
                aria-label={t('dash.myJobs.delete')}
                style={{color:'var(--coral-dark)', borderColor:'var(--coral-light)'}}
              >
                <Icon name="trash" size={13}/> {t('dash.myJobs.delete')}
              </button>
              <button className="btn btn-outline btn-sm" onClick={()=>go(`job:${j.id}`)}>{t('dash.myJobs.viewPost')}</button>
              <button className="btn btn-trust btn-sm" onClick={()=>go(`candidates:applicants/${j.id}`)}>
                <Icon name="user" size={13}/> {t('dash.myJobs.viewApplicants')}
              </button>
            </div>
          </div>
          <div style={{display:'grid', gridTemplateColumns:'repeat(4, 1fr)', gap:16, paddingTop:16, borderTop:'1px solid var(--t-line)'}}>
            <div><div style={{fontSize:11, color:'var(--t-ink-muted)', textTransform:'uppercase', letterSpacing:'0.08em', fontWeight:600, marginBottom:4}}>{t('dash.myJobs.col.applicants')}</div><div style={{fontSize:20, fontWeight:700}}>{j.applicants}</div></div>
            <div><div style={{fontSize:11, color:'var(--t-ink-muted)', textTransform:'uppercase', letterSpacing:'0.08em', fontWeight:600, marginBottom:4}}>{t('dash.myJobs.col.shortlisted')}</div><div style={{fontSize:20, fontWeight:700}}>3</div></div>
            <div><div style={{fontSize:11, color:'var(--t-ink-muted)', textTransform:'uppercase', letterSpacing:'0.08em', fontWeight:600, marginBottom:4}}>{t('dash.myJobs.col.interviews')}</div><div style={{fontSize:20, fontWeight:700}}>2</div></div>
            <div><div style={{fontSize:11, color:'var(--t-ink-muted)', textTransform:'uppercase', letterSpacing:'0.08em', fontWeight:600, marginBottom:4}}>{t('dash.myJobs.col.views')}</div><div style={{fontSize:20, fontWeight:700}}>{j.applicants * 7}</div></div>
          </div>
        </div>
        );
      })}
    </div>

    {confirmDeleteId != null && confirmJob && (
      <div onClick={()=>setConfirmDeleteId(null)} 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:460, width:'100%', padding:32, background:'var(--t-paper)', borderRadius:16, boxShadow:'0 24px 60px rgba(0,0,0,0.3)'}}>
          <div style={{width:48, height:48, borderRadius:99, background:'var(--coral-bg)', color:'var(--coral-dark)', display:'grid', placeItems:'center', marginBottom:16}}>
            <Icon name="trash" size={20}/>
          </div>
          <h2 className="display" style={{fontSize:22, marginBottom:8}}>{t('dash.myJobs.deleteConfirm.title')}</h2>
          <p style={{color:'var(--t-ink-soft)', fontSize:14, lineHeight:1.6, marginBottom:6}}>
            <strong>{window.pickLocalised(confirmJob, 'title') || confirmJob.title}</strong>
          </p>
          <p style={{color:'var(--t-ink-soft)', fontSize:14, lineHeight:1.6, marginBottom:24}}>
            {t('dash.myJobs.deleteConfirm.body')}
          </p>
          <div style={{display:'flex', gap:10, justifyContent:'flex-end'}}>
            <button className="btn btn-ghost" onClick={()=>setConfirmDeleteId(null)}>{t('dash.myJobs.deleteConfirm.cancel')}</button>
            <button
              className="btn btn-sm"
              onClick={confirmDelete}
              style={{background:'var(--coral-dark)', color:'white', borderColor:'var(--coral-dark)', padding:'10px 18px', fontSize:14, fontWeight:600, borderRadius:8}}
            >
              {t('dash.myJobs.deleteConfirm.confirm')}
            </button>
          </div>
        </div>
      </div>
    )}
  </div>
  );
};

const InterviewsSection = null;
const DocumentsSection = null;

// Employer notification preferences. Defaults all-on per product call —
// employer can opt out individually. Push removed (no app yet); Email is the
// only channel. Marketing row "newsletter" is opt-OUT (default on).
const EmployerNotifications = () => {
  const { t } = window.useI18n();
  const [prefs, setPrefs] = React.useState({
    newMessages: true,
    newApplicants: true,
    newsletter: true,
  });
  const set = (key) => (val) => setPrefs(p => ({ ...p, [key]: val }));
  const rows = [
    { key: 'newMessages',   label: t('dash.account.notifications.row.newMessages') },
    { key: 'newApplicants', label: t('dash.account.notifications.row.newApplicants') },
    { key: 'newsletter',    label: t('dash.account.notifications.row.newsletter') },
  ];
  return (
    <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:'flex', flexDirection:'column'}}>
        {rows.map((row, i) => (
          <div key={row.key} style={{display:'grid', gridTemplateColumns:'1fr auto', alignItems:'center', padding:'14px 0', borderBottom: i < rows.length - 1 ? '1px solid var(--t-line)' : 'none', fontSize:13, gap:16}}>
            <div style={{fontWeight:500}}>{row.label}</div>
            <Toggle checked={prefs[row.key]} onChange={set(row.key)} ariaLabel={row.label}/>
          </div>
        ))}
      </div>
    </div>
  );
};

const AccountSection = ({ subscription, me, userName }) => {
  const { t } = window.useI18n();
  const [tab, setTab] = React.useState('profile');
  const email = me?.email || (() => {
    try { return localStorage.getItem('hm_registered_email') || 'weichen@example.tw'; }
    catch { return 'weichen@example.tw'; }
  })();
  const tabs = [
    {id:'profile', label: t('dash.account.tab.profile')},
    {id:'plan', label: t('dash.account.tab.plan')},
    {id:'notifications', label: t('dash.account.tab.notifications')},
    {id:'security', label: t('dash.account.tab.security')},
  ];
  // Profile contact form — local state, save button writes back to backend
  // (PATCH /me once available). Until the backend lands the Save button is
  // a no-op stub that flashes "Saved" feedback. Email is read-only here
  // (managed via the auth verification flow).
  const [profileFullName, setProfileFullName] = React.useState(userName || getUserDisplayName(me) || 'Wei-Chen Lin');
  const [profilePhoneCC, setProfilePhoneCC] = React.useState('+886');
  const [profilePhone, setProfilePhone] = React.useState('912 345 678');
  const [profileLang, setProfileLang] = React.useState('en');
  const [profileSaved, setProfileSaved] = React.useState(false);
  const dialCodes = typeof DIAL_CODES !== 'undefined' ? DIAL_CODES : [];
  const saveProfile = () => {
    // TODO: PATCH /me with { full_name, phone_cc, phone, locale } once the
    // .NET API exposes the matching endpoint.
    setProfileSaved(true);
    setTimeout(() => setProfileSaved(false), 2000);
  };

  return (
    <div>
      <div className="dash-header">
        <h1>{t('dash.account.title')}</h1>
        <p>{t('dash.account.sub')}</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 === 'profile' && (
            <div className="card-flat" style={{padding:24}}>
              <h3 style={{fontSize:15, fontWeight:700, marginBottom:4}}>Your details</h3>
              <p style={{fontSize:12, color:'var(--t-ink-muted)', marginBottom:16}}>Name and contact info visible to helpers you message.</p>
              <div style={{display:'grid', gridTemplateColumns:'1fr 1fr', gap:14}}>
                <div>
                  <div className="label">Full name</div>
                  <input className="input" value={profileFullName} onChange={e => setProfileFullName(e.target.value)}/>
                </div>
                <div>
                  <div className="label">Email</div>
                  <input
                    className="input" type="email" value={email}
                    readOnly
                    style={{background:'var(--t-bg)', color:'var(--t-ink-muted)', cursor:'not-allowed'}}
                  />
                </div>
                <div style={{gridColumn:'1/-1'}}>
                  <div className="label">Phone</div>
                  <div style={{display:'grid', gridTemplateColumns:'200px 1fr', gap:8}}>
                    <select className="input" value={profilePhoneCC} onChange={e => setProfilePhoneCC(e.target.value)}>
                      {dialCodes.map(d => (
                        <option key={d.cc + d.name} value={d.cc}>{d.flag} {d.cc} {d.name}</option>
                      ))}
                    </select>
                    <input className="input" value={profilePhone} onChange={e => setProfilePhone(e.target.value)} placeholder="912 345 678"/>
                  </div>
                </div>
                <div style={{gridColumn:'1/-1'}}>
                  <div className="label">Preferred language</div>
                  <select className="input" value={profileLang} onChange={e => setProfileLang(e.target.value)}>
                    <option value="en">English</option>
                    <option value="zh-TW">繁體中文</option>
                    <option value="id">Bahasa Indonesia</option>
                  </select>
                </div>
              </div>
              <div style={{display:'flex', alignItems:'center', gap:12, marginTop:18}}>
                <button className="btn btn-primary btn-sm" onClick={saveProfile}>Save changes</button>
                {profileSaved && (
                  <span style={{fontSize:12, color:'var(--trust)', fontWeight:600, display:'inline-flex', alignItems:'center', gap:4}}>
                    <Icon name="check" size={12}/> Saved
                  </span>
                )}
              </div>
            </div>
          )}

          {tab === 'plan' && (
            <>
              <div className="card-flat" style={{padding:24}}>
                <h3 style={{fontSize:15, fontWeight:700, marginBottom:14}}>Current plan</h3>
                <div style={{display:'flex', justifyContent:'space-between', alignItems:'center'}}>
                  <div>
                    <div style={{fontSize:22, fontWeight:700, letterSpacing:'-0.01em', marginBottom:4}}>
                      {subscription === 'premium' ? 'Premium' : subscription === 'standard' ? 'Standard' : 'Basic (Free)'}
                    </div>
                    <div style={{fontSize:13, color:'var(--t-ink-muted)'}}>
                      {subscription === 'premium' ? 'Renews May 19 · NT$1,490/month' : subscription === 'standard' ? '3 days left · NT$990 for 7 days' : 'Upgrade to contact helpers directly and watch assessment videos'}
                    </div>
                  </div>
                  <button className="btn btn-outline btn-sm">Manage plan</button>
                </div>
              </div>
              <div className="card-flat" style={{padding:24}}>
                <h3 style={{fontSize:15, fontWeight:700, marginBottom:14}}>Payment method</h3>
                <div style={{display:'flex', alignItems:'center', gap:14}}>
                  <div style={{width:44, height:30, background:'var(--t-ink)', borderRadius:6}}/>
                  <div style={{flex:1}}>
                    <div style={{fontSize:13, fontWeight:600}}>Visa ending in 4242</div>
                    <div style={{fontSize:12, color:'var(--t-ink-muted)'}}>Expires 08/2028</div>
                  </div>
                  <button className="btn btn-ghost btn-sm">Update</button>
                </div>
              </div>
            </>
          )}

          {tab === 'notifications' && <EmployerNotifications/>}

          {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}}>
                <h3 style={{fontSize:15, fontWeight:700, marginBottom:4}}>Two-factor authentication</h3>
                <p style={{fontSize:12, color:'var(--t-ink-muted)', marginBottom:14}}>Add an extra layer of security when signing in.</p>
                <button className="btn btn-trust btn-sm">Enable 2FA</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)'}}>Danger zone</h3>
                <p style={{fontSize:12, color:'var(--t-ink-muted)', marginBottom:14}}>Deleting your account is permanent. Active conversations will be closed.</p>
                <button className="btn btn-outline btn-sm" style={{color:'var(--coral)', borderColor:'var(--coral)'}}>Delete account</button>
              </div>
            </>
          )}
        </div>
      </div>
    </div>
  );
};

// ===== Inbox =====
const InboxPage = ({ go, subscription = 'premium', initialId }) => {
  const { t } = window.useI18n();
  const { candidates } = window.MOCK_DATA;
  const [activeId, setActiveId] = React.useState(null);
  const [draft, setDraft] = React.useState('');
  const [sent, setSent] = React.useState([]);
  const isFree = subscription === 'free';

  const conversations = [];

  const activeCand = candidates.find(c => c.id === activeId);
  const activeConv = conversations.find(c => c.id === activeId);

  const threads = {};

  const currentThread = [...(threads[activeId] || []), ...sent.filter(s => s.convId === activeId).map(s => ({me:true, text:s.text, time:'Now'}))];

  const send = () => {
    if (!draft.trim()) return;
    setSent([...sent, {convId: activeId, text: draft.trim()}]);
    setDraft('');
  };

  return (
    <div className={`inbox-shell ${activeId ? 'mobile-has-thread' : ''}`}>
      {/* Conversations list */}
      <div className="inbox-side">
        <div className="inbox-search">
          <div style={{position:'relative'}}>
            <input className="input" placeholder={t('dash.inbox.searchPlaceholder')} style={{paddingLeft:38}}/>
            <div style={{position:'absolute', left:14, top:'50%', transform:'translateY(-50%)', color:'var(--t-ink-muted)', pointerEvents:'none'}}>
              <Icon name="search" size={15}/>
            </div>
          </div>
        </div>
        {conversations.map(conv => {
          const c = candidates.find(x => x.id === conv.id);
          if (!c) return null;
          return (
            <div
              key={conv.id}
              className={`inbox-item ${activeId===conv.id?'active':''} ${conv.unread?'unread':''}`}
              onClick={() => setActiveId(conv.id)}
            >
              <Avatar person={c} size={44}/>
              <div className="inbox-item-body">
                <div className="inbox-item-top">
                  <span className="inbox-item-name">{c.name}</span>
                  <span className="inbox-item-time">{conv.time}</span>
                </div>
                <div style={{fontSize:11, color:'var(--trust-ink)', fontWeight:600, marginTop:2, marginBottom:2, display:'flex', alignItems:'center', gap:4}}>
                  <Icon name="verified" size={10}/> {t('dash.inbox.verifiedRe', {title: conv.jobTitle})}
                </div>
                <div className="inbox-item-preview">{conv.lastMsg}</div>
              </div>
              {conv.unread && <div className="inbox-unread-dot"/>}
            </div>
          );
        })}
      </div>

      {/* Thread */}
      <div className="thread">
        {activeCand ? (<>
        <div className="thread-header">
          <button onClick={()=>setActiveId(null)} className="btn btn-ghost btn-sm inbox-mobile-back" style={{padding:6}}><Icon name="arrowLeft" size={16}/></button>
          <Avatar person={activeCand} size={44}/>
          <div style={{flex:1, minWidth:0}}>
            <div style={{fontSize:15, fontWeight:700, display:'flex', alignItems:'center', gap:6}}>
              {activeCand.name}
              <Icon name="verified" size={14} style={{color:'var(--trust)'}}/>
            </div>
            <div style={{fontSize:12, color:'var(--t-ink-muted)'}}>
              {activeCand.age} · {activeCand.flag} {activeCand.nationality} · Active {activeCand.active}
            </div>
          </div>
          <button className="btn btn-outline btn-sm" onClick={()=>go(`candidate:${activeCand.id}`)}>{t('dash.inbox.viewProfile')}</button>
          <button className="btn btn-ghost btn-sm" style={{padding:6}}><Icon name="dots" size={16}/></button>
        </div>

        <div className="thread-body">
          {/* Job context */}
          {activeConv?.jobId && (
            <div style={{display:'flex', gap:12, padding:'12px 16px', background:'var(--t-paper)', border:'1px solid var(--t-line)', borderRadius:10, marginBottom:6, alignItems:'center'}}>
              <div style={{width:32, height:32, borderRadius:8, background:'var(--trust-bg)', color:'var(--trust)', display:'grid', placeItems:'center', flexShrink:0}}>
                <Icon name="briefcase" size={14}/>
              </div>
              <div style={{flex:1, minWidth:0}}>
                <div style={{fontSize:11, color:'var(--t-ink-muted)', textTransform:'uppercase', letterSpacing:'0.08em', fontWeight:600}}>{t('dash.inbox.conversationAboutJob')}</div>
                <div style={{fontSize:13, fontWeight:600, marginTop:2}}>{activeConv.jobTitle}</div>
              </div>
              <button className="btn btn-ghost btn-sm" onClick={()=>go(`job:${activeConv.jobId}`)}>{t('dash.myJobs.viewPost')} <Icon name="arrow" size={13}/></button>
            </div>
          )}

          <div className="thread-context">
            <div style={{width:36, height:36, borderRadius:99, background:'var(--trust)', color:'white', display:'grid', placeItems:'center', flexShrink:0}}>
              <Icon name="shield" size={15}/>
            </div>
            <div style={{flex:1, fontSize:13, color:'var(--t-ink)'}}>
              <div style={{fontWeight:700, color:'var(--trust-ink)', marginBottom:2}}>{t('dash.inbox.safe.title')}</div>
              <div style={{color:'var(--t-ink-muted)'}}>{t('dash.inbox.safe.body')}</div>
            </div>
          </div>

          {currentThread.map((m, i) => {
            if (m.day) return <div key={i} className="msg-day">{m.day}</div>;
            return (
              <div key={i} className={`msg ${m.me?'me':'them'}`}>
                {!m.me && <Avatar person={activeCand} size={32}/>}
                <div>
                  <div className="msg-bubble">{m.text}</div>
                  <div className="msg-meta" style={{textAlign: m.me?'right':'left'}}>{m.time}</div>
                </div>
              </div>
            );
          })}
        </div>

        <div className="thread-composer" style={isFree ? {position:'relative'} : null}>
          {isFree && (
            <div style={{position:'absolute', inset:0, background:'rgba(255,255,255,0.82)', backdropFilter:'blur(2px)', zIndex:2, display:'flex', alignItems:'center', justifyContent:'center', gap:12, padding:16, borderRadius:12}}>
              <div style={{width:32, height:32, borderRadius:99, background:'var(--trust)', color:'white', display:'grid', placeItems:'center', flexShrink:0}}>
                <Icon name="shield" size={14}/>
              </div>
              <div style={{flex:1, minWidth:0}}>
                <div style={{fontSize:13, fontWeight:700, color:'var(--trust-ink)'}}>Upgrade to reply directly</div>
                <div style={{fontSize:12, color:'var(--t-ink-muted)'}}>Free accounts can read messages but can't send replies or attachments.</div>
              </div>
              <button className="btn btn-trust btn-sm" onClick={()=>go('pricing')}>See plans</button>
            </div>
          )}
          <button className="btn btn-ghost btn-sm" style={{padding:8}} title="Attach" disabled={isFree}><Icon name="paperclip" size={18}/></button>
          <textarea
            placeholder={`Message ${activeCand.name}...`}
            value={draft}
            onChange={e=>setDraft(e.target.value)}
            onKeyDown={e=>{if (e.key==='Enter' && !e.shiftKey) { e.preventDefault(); send(); }}}
            disabled={isFree}
          />
          <button className="btn btn-trust" onClick={send} disabled={!draft.trim() || isFree}>
            <Icon name="send" size={15}/> Send
          </button>
        </div>
        </>) : (
          <div style={{display:'grid', placeItems:'center', height:'100%', padding:40, textAlign:'center', color:'var(--t-ink-muted)'}}>
            <div>
              <div style={{fontSize:42, marginBottom:12, opacity:0.5}}>💬</div>
              <div style={{fontSize:15, fontWeight:600, color:'var(--t-ink)', marginBottom:4}}>Select a conversation</div>
              <div style={{fontSize:13}}>Choose a thread from the list to start chatting.</div>
            </div>
          </div>
        )}
      </div>
    </div>
  );
};

Object.assign(window, { DashPage, InboxPage });
