// careers-app.jsx — Octant Systems careers page (careers.html).
const { useState: useStCa, useEffect: useEffCa } = React;

const CAREERS_TWEAK_DEFAULTS = /*EDITMODE-BEGIN*/{
  "rowClick": "expand",
  "motion": true,
  "scanlines": true
}/*EDITMODE-END*/;

function CaMetaLine({ job }){
  const bits = [job.meta.team, job.meta.location, job.meta.type].filter(Boolean);
  return <span className="j-meta">{bits.join('  ·  ')}</span>;
}

function CaJobSide({ job, mail }){
  const rows = [['TEAM', job.meta.team], ['LOCATION', job.meta.location], ['TYPE', job.meta.type], ['REF', job.meta.ref]].filter((r) => r[1]);
  return <div className="j-side">
    {rows.map(([k, v]) => <Read key={k} k={k} v={v} size={10.5} style={{ whiteSpace:'normal' }} />)}
    <a className="j-apply" href={careersApplyHref(job, mail)}>APPLY VIA EMAIL</a>
  </div>;
}

function CaJobContent({ job }){
  return <div>
    {job.intro.map((p, i) => <p key={i} className="body" style={{ margin:'0 0 14px', fontSize:16 }}>{p}</p>)}
    {job.sections.map((s, i) => <div key={i}>
      <span className="kicker j-sec-h">{s.h}</span>
      {s.paras.map((p, j) => <p key={j} className="body" style={{ margin:'0 0 12px', fontSize:15.5 }}>{p}</p>)}
      {s.items.length > 0 && <ul className="j-ul">
        {s.items.map((it, j) => <li key={j} className="body j-li"><span className="j-dash">—</span><span>{it}</span></li>)}
      </ul>}
    </div>)}
  </div>;
}

function CaJobRow({ job, mode, isOpen, onRow, mail }){
  const href = mode === 'apply' ? careersApplyHref(job, mail) : ('#' + job.slug);
  return <div className="j-row" id={'job-' + job.slug}>
    <a className="j-head" href={href}
      onClick={(e) => { if (mode !== 'apply'){ e.preventDefault(); onRow(job); } }}>
      <span className="j-title">{job.title}</span>
      <CaMetaLine job={job} />
      <span className="j-x">{mode === 'apply' ? '→' : (mode === 'file' ? '↗' : (isOpen ? '−' : '+'))}</span>
    </a>
    {mode === 'expand' && isOpen && <div className="j-body">
      <CaJobSide job={job} mail={mail} />
      <CaJobContent job={job} />
    </div>}
  </div>;
}

function CaPersonnelFile({ job, mail, onClose }){
  useEffCa(() => {
    const onKey = (e) => { if (e.key === 'Escape') onClose(); };
    window.addEventListener('keydown', onKey);
    const prev = document.body.style.overflow;
    document.body.style.overflow = 'hidden';
    return () => { window.removeEventListener('keydown', onKey); document.body.style.overflow = prev; };
  }, []);
  return <div className="jfile" data-screen-label="Personnel file">
    <div className="lyr dotgrid"></div>
    <div className="lyr scanlines"></div>
    <div className="jfile-in">
      <div className="jfile-top">
        <Kicker style={{ color:T.slateAcc }}>PERSONNEL FILE{job.meta.ref ? ' · ' + job.meta.ref : ''}</Kicker>
        <button className="jfile-x mono" onClick={onClose}>✕ CLOSE</button>
      </div>
      <h1 className="sec-head" style={{ fontSize:'clamp(28px,4.4vw,44px)', margin:'20px 0 12px' }}>{job.title}</h1>
      <CaMetaLine job={job} />
      <div style={{ height:34 }}></div>
      <CaJobContent job={job} />
      <a className="j-apply" href={careersApplyHref(job, mail)} style={{ marginTop:28 }}>APPLY VIA EMAIL</a>
    </div>
  </div>;
}

function CareersApp(){
  const [t, setTweak] = useTweaks(CAREERS_TWEAK_DEFAULTS);
  const prefersReduced = window.matchMedia && window.matchMedia('(prefers-reduced-motion: reduce)').matches;
  const motion = !!t.motion && !prefersReduced;
  const { copy: cc, jobs, ready } = useCareers();
  const mode = t.rowClick || 'expand';
  const [openSlug, setOpenSlug] = useStCa(() => decodeURIComponent((location.hash || '').replace(/^#\/?/, '')) || null);
  const [fileJob, setFileJob] = useStCa(null);
  useScrollVars();

  useEffCa(() => {
    document.body.classList.toggle('no-motion', !motion);
    document.body.classList.toggle('no-scan', !t.scanlines);
  }, [motion, t.scanlines]);

  // honor a #job-slug deep link once data is ready
  useEffCa(() => {
    if (!ready || !openSlug) return;
    const job = jobs.find((j) => j.slug === openSlug);
    if (!job) return;
    if (mode === 'file'){ setFileJob(job); return; }
    const el = document.getElementById('job-' + openSlug);
    if (el){ const y = el.getBoundingClientRect().top + (window.scrollY || 0) - 130; window.scrollTo(0, Math.max(0, y)); }
  }, [ready]);

  const onRow = (job) => {
    if (mode === 'file') setFileJob(job);
    else setOpenSlug(openSlug === job.slug ? null : job.slug);
    try { history.replaceState(null, '', '#' + job.slug); } catch (e){}
  };
  const mail = (cc && cc.mail) || 'jobs@octant.systems';

  return <>
    <div className="lyr" style={{ background:'radial-gradient(130% 100% at 50% 18%, oklch(0.165 0.02 260) 0%, oklch(0.118 0.012 262) 52%, oklch(0.09 0.01 264) 100%)' }}></div>
    <ParticleField active={motion} density={46} style={{ position:'fixed' }} />
    <div className="lyr scanlines" style={{ opacity:0.45 }}></div>
    <div className="lyr vignette"></div>

    <header className="ca-head">
      <a href="index.html" style={{ display:'inline-flex' }} aria-label="Octant Systems — home"><StaticLockup h={22} /></a>
      <a className="ca-ret mono" href="index.html">← RETURN</a>
    </header>

    <main className="ca-main" data-screen-label="Careers">
      <section className="ca-hero">
        <Reveal><Kicker>{(cc && cc.kicker) || 'PERSONNEL'}</Kicker></Reveal>
        <Reveal delay={90}><h1 className="hero-line" style={{ fontSize:'clamp(32px,5vw,58px)', margin:'20px 0 0' }}>{(cc && cc.headline) || ''}</h1></Reveal>
        {cc && cc.why ? <Reveal delay={180}><p className="body" style={{ fontSize:17, maxWidth:640, margin:'26px 0 0' }}>{cc.why}</p></Reveal> : null}
      </section>

      <section data-screen-label="Open positions">
        <Reveal style={{ margin:'48px 0 8px' }}>
          <Kicker style={{ color:T.faint }}>OPEN POSITIONS · {String(jobs.length).padStart(2, '0')}</Kicker>
        </Reveal>
        <div>
          {jobs.map((j) => <CaJobRow key={j.slug} job={j} mode={mode} isOpen={openSlug === j.slug} onRow={onRow} mail={mail} />)}
        </div>
        {cc && cc.note ? <p className="mono" style={{ fontSize:11, letterSpacing:'0.08em', color:T.faint, margin:'24px 2px 0', lineHeight:1.8 }}>{cc.note}</p> : null}
      </section>

      {cc && cc.benefits && cc.benefits.length ? <section data-screen-label="Provisions">
        <Reveal style={{ margin:'76px 0 30px' }}><Kicker style={{ color:T.faint }}>PROVISIONS</Kicker></Reveal>
        <div className="ben-grid">
          {cc.benefits.map((b, i) => <Reveal key={b.k} delay={i * 60} className="ben">
            <div className="mono" style={{ fontSize:11, letterSpacing:'0.14em', color:T.txt }}>{b.k}</div>
            <div className="mono" style={{ fontSize:11.5, color:T.dim, marginTop:8, lineHeight:1.6 }}>{b.v}</div>
          </Reveal>)}
        </div>
      </section> : null}

      <footer className="ca-foot">
        <a className="mono ca-mail" href={'mailto:' + mail}>TRANSMIT → {mail}</a>
        <div style={{ display:'flex', gap:18, flexWrap:'wrap' }}>
          {((window.COPY || DEFAULT_COPY).status || []).map((s, i) => <Kicker key={i} style={{ fontSize:10, color:T.faint }}>{s}</Kicker>)}
        </div>
      </footer>
    </main>

    {fileJob ? <CaPersonnelFile job={fileJob} mail={mail}
      onClose={() => { setFileJob(null); try { history.replaceState(null, '', location.pathname + location.search); } catch (e){} }} /> : null}

    <TweaksPanel title="Tweaks">
      <TweakSection label="Openings" />
      <TweakRadio label="Row click" value={mode}
        options={[
          { value:'expand', label:'Expand inline' },
          { value:'file', label:'Personnel file' },
          { value:'apply', label:'Straight to apply' },
        ]}
        onChange={(v) => setTweak('rowClick', v)} />
      <TweakSection label="Motion & feel" />
      <TweakToggle label="Motion" value={!!t.motion} onChange={(v) => setTweak('motion', v)} />
      <TweakToggle label="Scanlines" value={!!t.scanlines} onChange={(v) => setTweak('scanlines', v)} />
    </TweaksPanel>
  </>;
}

/* Load careers.md + jobs/*.md (and content.md for the shared tagline/status),
   then mount. Any failed fetch falls back to built-in copy — never a blank page. */
(function bootCareers(){
  const mount = () => ReactDOM.createRoot(document.getElementById('root')).render(<CareersApp />);
  Promise.allSettled([
    fetch('content.md', { cache:'no-cache' })
      .then((r) => r.ok ? r.text() : Promise.reject(new Error('HTTP ' + r.status)))
      .then((md) => applyContent(md))
      .catch((err) => console.warn('[octant] content.md not loaded; using built-in copy.', err)),
    loadCareersData(),
  ]).then(mount, mount);
})();
