/* Main portfolio composition.
   Layout: topbar, hero with schematic canvas, projects, experience, skills, footer.
   Tweaks panel controls: theme (light/dark/invert), scroller (filmstrip/cards/peek),
   resume (panel/inline/accordion). */

const { PROFILE, SKILLS, AWARDS } = window.PORTFOLIO_DATA;
const { ProjectsSection, ProjectOverlay, ExperienceSection, HERO_VARIANTS } = window;

const TWEAK_DEFAULTS = /*EDITMODE-BEGIN*/{
  "theme": "light",
  "railSocial": true,
  "statusBadge": false,
  "shortcuts": true,
  "progressRail": true
} /*EDITMODE-END*/;

const HERO_CHOICE = 'index';
const SCROLLER_CHOICE = 'cards';
const RESUME_CHOICE = 'panel';

const Topbar = ({ theme, setTheme }) =>
<div className="topbar">
    <div className="page topbar-inner">
      <div style={{ display: 'flex', gap: 20, alignItems: 'center' }}>
        <span className="mono" style={{ fontWeight: 600, color: 'var(--ink)', letterSpacing: '.02em' }}>
          XL · {PROFILE.name}
        </span>
        <span className="mono" style={{ color: 'var(--ink-mute)', fontSize: 10, textTransform: 'uppercase', letterSpacing: '.14em' }}>
          Portfolio / 2026
        </span>
      </div>
      <div className="mid">
        <span className="status-dot mono up">Upcoming work term · Jan — Aug 2027</span>
      </div>
      <div className="right">
        <a href="#work" className="mono up" style={{ fontSize: 11 }}>Work</a>
        <a href="#experience" className="mono up" style={{ fontSize: 11 }}>Experience</a>
        <a href="#skills" className="mono up" style={{ fontSize: 11 }}>Skills</a>
        <a href="#contact" className="mono up" style={{ fontSize: 11 }}>Contact</a>
        <div className="theme-switch">
          {['light', 'dark', 'invert'].map((t) =>
        <button key={t} className={theme === t ? 'active' : ''} onClick={() => setTheme(t)}>
              {t === 'invert' ? 'ink' : t}
            </button>
        )}
        </div>
      </div>
    </div>
  </div>;


const Hero = ({ variant }) => {
  const V = HERO_VARIANTS[variant] || HERO_VARIANTS.editorial;
  return <V />;
};

const SkillsSection = () =>
<section className="section" id="skills" data-screen-label="Skills">
    <div className="page">
      <div className="section-head">
        <div className="section-title">Tool<em>kit</em></div>
        <div className="section-meta">Section 04 · Competencies</div>
      </div>
      <p className="section-lede">Day-to-day stack across optics, fabrication, and software.


    </p>
      <div className="skills-grid">
        {SKILLS.map((s, gi) =>
      <div key={s.group} className="skills-cell">
            <div className="sk-head">
              <span className="sk-code mono">{s.code}</span>
              <span className="sk-num mono">0{gi + 1}</span>
            </div>
            <h5 className="sk-group">{s.group}</h5>
            <p className="sk-blurb">{s.blurb}</p>
            <ul className="sk-list">
              {s.items.map((x, i) =>
          <li key={i}>
                  <span className="sk-bullet mono" aria-hidden="true">→</span>
                  <span className="sk-name">{x}</span>
                </li>
          )}
            </ul>
          </div>
      )}
      </div>

      {AWARDS && AWARDS.length > 0 &&
    <div className="awards-block">
          <div className="awards-head mono up">— Awards & Recognition</div>
          <ul className="awards-list">
            {AWARDS.map((a, i) =>
        <li key={i}>
                <span className="aw-y mono">{a.y}</span>
                <span className="aw-k serif">{a.k}</span>
                <span className="aw-s">{a.s}</span>
              </li>
        )}
          </ul>
        </div>
    }
    </div>
  </section>;


const ReferencesPanel = ({ onClose, onOpenJob }) => {
  const refs = (window.EXPERIENCE_DATA || []).filter((e) => e.quotes && e.quotes.length > 0);

  React.useEffect(() => {
    const onKey = (ev) => {if (ev.key === 'Escape') onClose();};
    window.addEventListener('keydown', onKey);
    document.body.style.overflow = 'hidden';
    return () => {
      window.removeEventListener('keydown', onKey);
      document.body.style.overflow = '';
    };
  }, [onClose]);

  return (
    <>
      <div className="side-panel-back" onClick={onClose} />
      <aside className="side-panel refs-panel" role="dialog" aria-label="References">
        <button className="side-panel-close" onClick={onClose}>close ×</button>
        <header>
          <div className="idx">References · {String(refs.length).padStart(2, '0')}</div>
          <h3>Employer<br /><em>references.</em></h3>
          <div className="meta">
            <span>From University of Waterloo co-op evaluations and direct correspondence.</span>
          </div>
        </header>
        <div className="body">
          <div className="refs-list">
            {refs.map((e) =>
            <article key={e.id} className="refs-card">
                <div className="refs-card-head">
                  <div className="refs-card-meta mono up">
                    <span>{e.type}</span>
                    {e.rating && <span className="refs-rating">★ {e.rating}</span>}
                  </div>
                  <h4 className="refs-card-co">{e.company}</h4>
                  <div className="refs-card-role">{e.role} · <span className="mono">{e.dates}</span></div>
                </div>
                {e.quotes.map((q, qi) =>
              <figure key={qi} className="refs-quote">
                    <blockquote>"{q.text}"</blockquote>
                    <figcaption>
                      <span className="refs-quote-name">{q.name}</span>
                      <span className="refs-quote-title">{q.title}</span>
                    </figcaption>
                  </figure>
              )}
                <button
                type="button"
                className="refs-open mono up"
                onClick={() => onOpenJob(e)}>
                
                  View role brief →
                </button>
              </article>
            )}
          </div>
        </div>
      </aside>
    </>);

};

const Footer = () =>
<footer className="section foot" id="contact" data-screen-label="Contact">
    <div className="page foot-grid">
      <div>
        <div className="status-pill mono up">
          <span className="dot" />
          Upcoming work term · Jan 2027 — Aug 2027
        </div>
        <h2 style={{ marginTop: 24 }}>Get in<br /><em>touch.</em></h2>
      </div>
      <div className="foot-col">
        <h5>— Direct</h5>
        <ul>
          {PROFILE.links.slice(0, 3).map((l) =>
        <li key={l.label}><a href={l.href}>{l.value}</a></li>
        )}
        </ul>
      </div>
      <div className="foot-col">
        <h5>— Elsewhere</h5>
        <ul>
          {PROFILE.links.slice(3).map((l) =>
        <li key={l.label}><a href={l.href}>{l.value}</a></li>
        )}
        </ul>
      </div>
      <div className="foot-bottom">
        <span>© {PROFILE.name} · {new Date().getFullYear()}</span>
        <span>Waterloo, ON → Boston, MA</span>
        <span>v 2026.04</span>
      </div>
    </div>
  </footer>;


const TweaksPanel = ({ state, set, visible }) => {
  const [collapsed, setCollapsed] = React.useState(false);
  if (!visible) return null;
  const toggle = (k) =>
  <div className="opts" style={{ gridTemplateColumns: 'repeat(2, 1fr)' }}>
      <button className={state[k] ? 'active' : ''} onClick={() => set({ [k]: true })}>on</button>
      <button className={!state[k] ? 'active' : ''} onClick={() => set({ [k]: false })}>off</button>
    </div>;

  return (
    <div className="tweaks-panel">
      <header>
        <span>◉ Tweaks</span>
        <button className="tw-collapse" onClick={() => setCollapsed(!collapsed)}>
          {collapsed ? '+' : '−'}
        </button>
      </header>
      {!collapsed &&
      <div className="body">
          <div className="field">
            <div className="label">
              Social rail
              <span className="help">Fixed left sidebar with GH / LI / RG / email.</span>
            </div>
            {toggle('railSocial')}
          </div>
          <div className="field">
            <div className="label">
              Status badge
              <span className="help">Floating chip with co-op term + location.</span>
            </div>
            {toggle('statusBadge')}
          </div>
          <div className="field">
            <div className="label">
              Keyboard shortcuts
              <span className="help">Press 1–4 to jump between sections.</span>
            </div>
            {toggle('shortcuts')}
          </div>
          <div className="field">
            <div className="label">
              Section progress
              <span className="help">Right-edge rail with tick marks for each section.</span>
            </div>
            {toggle('progressRail')}
          </div>
        </div>
      }
    </div>);

};

/* ---------- Module: Social rail ---------- */
const SocialRail = () => {
  const items = [
  { label: 'GH', href: 'https://github.com/xlinzel', title: 'GitHub' },
  { label: 'LI', href: 'https://www.linkedin.com/in/xander-linzel', title: 'LinkedIn' },
  { label: 'RG', href: 'https://www.researchgate.net/profile/Xander-Linzel', title: 'ResearchGate' },
  { label: '@', href: 'mailto:xlinzel@uwaterloo.ca', title: 'Email' }];

  return (
    <aside className="social-rail" aria-label="Social links">
      <div className="rail-spine" />
      <ul>
        {items.map((i) =>
        <li key={i.label}>
            <a href={i.href} target={i.href.startsWith('http') ? '_blank' : undefined}
          rel="noreferrer" title={i.title}>
              <span className="rail-icon mono">{i.label}</span>
              <span className="rail-full mono">{i.title}</span>
            </a>
          </li>
        )}
      </ul>
      <div className="rail-foot mono up">
        <span className="rail-vertical">XL · 2026</span>
      </div>
    </aside>);

};

/* ---------- Module: Status badge ---------- */
const StatusBadge = () => {
  const [hidden, setHidden] = React.useState(false);
  const [hovered, setHovered] = React.useState(false);
  if (hidden) return null;
  return (
    <div
      className={`status-badge ${hovered ? 'expanded' : ''}`}
      onMouseEnter={() => setHovered(true)}
      onMouseLeave={() => setHovered(false)}>
      
      <span className="sb-pulse" />
      <div className="sb-lines">
        <div className="sb-row-1 mono up">
          <span>Upcoming work term · Jan — Aug 2027</span>
          <button className="sb-close" onClick={(e) => {e.stopPropagation();setHidden(true);}}>×</button>
        </div>
        <div className="sb-row-2 mono up">
          Waterloo, ON &nbsp;·&nbsp; referrals welcome &nbsp;·&nbsp;
          <a href="mailto:xlinzel@uwaterloo.ca">xlinzel@uwaterloo.ca</a>
        </div>
      </div>
    </div>);

};

/* ---------- Module: Keyboard shortcuts ---------- */
const Shortcuts = () => {
  const SECTIONS = [
  { k: '1', id: 'work', label: 'Work' },
  { k: '2', id: 'experience', label: 'Experience' },
  { k: '3', id: 'skills', label: 'Skills' },
  { k: '4', id: 'contact', label: 'Contact' }];

  const [flash, setFlash] = React.useState(null);
  const [open, setOpen] = React.useState(false);

  React.useEffect(() => {
    const onKey = (e) => {
      if (e.metaKey || e.ctrlKey || e.altKey) return;
      if (e.target?.matches('input, textarea, [contenteditable]')) return;
      if (e.key === '?') {setOpen((v) => !v);return;}
      const hit = SECTIONS.find((s) => s.k === e.key);
      if (hit) {
        const el = document.getElementById(hit.id);
        if (el) {
          window.scrollTo({ top: el.getBoundingClientRect().top + window.scrollY - 24, behavior: 'smooth' });
          setFlash(hit.k);
          setTimeout(() => setFlash(null), 800);
        }
      }
    };
    window.addEventListener('keydown', onKey);
    return () => window.removeEventListener('keydown', onKey);
  }, []);

  return (
    <>
      <button
        className="kbd-toggle mono up"
        onClick={() => setOpen((v) => !v)}
        aria-label="Keyboard shortcuts"
        title="Press ? to toggle">
        
        <span>?</span>
      </button>
      {open &&
      <div className="kbd-panel">
          <div className="kbd-head mono up">Shortcuts</div>
          <ul>
            {SECTIONS.map((s) =>
          <li key={s.k}>
                <kbd>{s.k}</kbd>
                <span>jump to {s.label}</span>
              </li>
          )}
            <li><kbd>?</kbd><span>toggle this panel</span></li>
          </ul>
        </div>
      }
      {flash && <div className="kbd-flash mono up">→ {SECTIONS.find((s) => s.k === flash).label}</div>}
    </>);

};

/* ---------- Module: Section progress rail ---------- */
const ProgressRail = () => {
  const SECTIONS = React.useMemo(() => [
  { id: 'work', label: 'Work' },
  { id: 'experience', label: 'Experience' },
  { id: 'skills', label: 'Skills' },
  { id: 'contact', label: 'Contact' }],
  []);
  const [pct, setPct] = React.useState(0);
  const [active, setAc] = React.useState(-1);
  React.useEffect(() => {
    const tick = () => {
      const h = document.documentElement;
      const max = h.scrollHeight - h.clientHeight;
      setPct(max > 0 ? h.scrollTop / max : 0);
      let cur = -1;
      SECTIONS.forEach((s, i) => {
        const el = document.getElementById(s.id);
        if (!el) return;
        const r = el.getBoundingClientRect();
        if (r.top < h.clientHeight * 0.4) cur = i;
      });
      setAc(cur);
    };
    tick();
    window.addEventListener('scroll', tick, { passive: true });
    window.addEventListener('resize', tick);
    return () => {window.removeEventListener('scroll', tick);window.removeEventListener('resize', tick);};
  }, [SECTIONS]);

  const go = (id) => {
    const el = document.getElementById(id);
    if (el) window.scrollTo({ top: el.getBoundingClientRect().top + window.scrollY - 24, behavior: 'smooth' });
  };

  return (
    <aside className="progress-rail" aria-label="Page progress">
      <div className="pr-track">
        <div className="pr-fill" style={{ height: `${pct * 100}%` }} />
      </div>
      <ul>
        {SECTIONS.map((s, i) =>
        <li key={s.id} className={i === active ? 'on' : ''} style={{ top: `${(i + 1) / (SECTIONS.length + 1) * 100}%` }}>
            <button onClick={() => go(s.id)} aria-label={`jump to ${s.label}`}>
              <span className="pr-dot" />
              <span className="pr-label mono up">{s.label}</span>
            </button>
          </li>
        )}
      </ul>
    </aside>);

};

const App = () => {
  const [state, setState] = React.useState(TWEAK_DEFAULTS);
  const [openProject, setOpenProject] = React.useState(null);
  const [editMode, setEditMode] = React.useState(false);
  const [refsOpen, setRefsOpen] = React.useState(false);
  const [expPanel, setExpPanel] = React.useState(null);

  React.useEffect(() => {
    const onOpenRefs = () => setRefsOpen(true);
    window.addEventListener('open-references', onOpenRefs);
    return () => window.removeEventListener('open-references', onOpenRefs);
  }, []);

  React.useEffect(() => {
    document.documentElement.dataset.theme = state.theme;
  }, [state.theme]);

  const updateState = (patch) => {
    const next = { ...state, ...patch };
    setState(next);
    if (window.parent) {
      window.parent.postMessage({ type: '__edit_mode_set_keys', edits: patch }, '*');
    }
  };

  const setTheme = (t) => updateState({ theme: t });

  React.useEffect(() => {
    const onMsg = (ev) => {
      if (ev.data?.type === '__activate_edit_mode') setEditMode(true);
      if (ev.data?.type === '__deactivate_edit_mode') setEditMode(false);
    };
    window.addEventListener('message', onMsg);
    window.parent?.postMessage({ type: '__edit_mode_available' }, '*');
    return () => window.removeEventListener('message', onMsg);
  }, []);

  return (
    <>
      {state.railSocial && <SocialRail />}
      <div className={['app-shell', state.railSocial ? 'with-rail' : ''].join(' ')}>
        <Topbar theme={state.theme} setTheme={setTheme} />
        <main>
          <Hero variant={HERO_CHOICE} />
          <ProjectsSection style={SCROLLER_CHOICE} onOpen={setOpenProject} />
          <ExperienceSection controlledPanel={expPanel} onPanelChange={setExpPanel} />
          <SkillsSection />
          <Footer />
        </main>
      </div>
      {openProject && <ProjectOverlay p={openProject} onClose={() => setOpenProject(null)} />}
      {refsOpen &&
      <ReferencesPanel
        onClose={() => setRefsOpen(false)}
        onOpenJob={(e) => {setRefsOpen(false);setExpPanel(e);}} />

      }
      {state.statusBadge && <StatusBadge />}
      {state.shortcuts && <Shortcuts />}
      {state.progressRail && <ProgressRail />}
    </>);

};

const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(<App />);