// Personal site — Arpit Dev Mathur

const { useEffect, useRef, useState } = React;

const TWEAK_DEFAULTS = /*EDITMODE-BEGIN*/{
  "palette": "paper",
  "glass": 3,
  "imageryOpacity": 0.18,
  "imagerySaturation": 0.7,
  "leftStack": "illinois",
  "rightStack": "spaceneedle",
  "typography": "instrument",
  "motion": "parallax",
  "density": "regular"
}/*EDITMODE-END*/;

// ─────────────────────────────────────────────────────────────
// resume variant resolution
//   hostname picks the variant — ai/aipm/fde/sde.mathur.dev.
//   the apex (mathur.dev) and anything unrecognized fall back to `ai`.
//   ?role=<variant> overrides, for local dev and preview deploys.
// ─────────────────────────────────────────────────────────────
const RESUME_ROLES = ['ai', 'aipm', 'fde', 'sde'];
const DEFAULT_ROLE = 'ai';

function resolveRole() {
  const override = new URLSearchParams(window.location.search).get('role');
  if (override && RESUME_ROLES.includes(override)) return override;
  const label = (window.location.hostname.split('.')[0] || '').toLowerCase();
  if (RESUME_ROLES.includes(label)) return label;
  return DEFAULT_ROLE;
}

// Last-resort content if a content/*.jsx file fails to load or eval.
// Keeps the page rendering name, email, and a résumé link instead of
// white-screening on an undefined dereference in App().
const FALLBACK_CONTENT = {
  meta: { role: 'fallback', docTitle: 'Arpit Dev Mathur', resumePdf: 'assets/main.pdf' },
  hero: {
    eyebrow: 'Software & AI Engineer · San Francisco',
    tagline: 'Resume content failed to load — please refresh the page.'
  },
  about: { lead: '', paragraphs: [] },
  roles: [],
  skills: []
};

function resolveContent() {
  const bank = window.RESUME_CONTENT || {};
  return bank[resolveRole()] || bank[DEFAULT_ROLE] || FALLBACK_CONTENT;
}

// ─────────────────────────────────────────────────────────────
// helpers
// ─────────────────────────────────────────────────────────────
function useScrollY() {
  const [y, setY] = useState(0);
  useEffect(() => {
    let raf = null;
    const onScroll = () => {
      if (raf) return;
      raf = requestAnimationFrame(() => {
        setY(window.scrollY);
        raf = null;
      });
    };
    window.addEventListener('scroll', onScroll, { passive: true });
    return () => window.removeEventListener('scroll', onScroll);
  }, []);
  return y;
}

function applyGlassVars(level) {
  // level 0..10
  const root = document.documentElement;
  const lv = Math.max(0, Math.min(10, level));
  const blur = 3 + lv * 1.6;          // 3..19 px
  const alpha = 0.85 - lv * 0.04;     // 0.85..0.45 (lower = more see-through)
  const border = 0.30 + lv * 0.05;    // 0.30..0.80
  const shadow = 0.02 + lv * 0.012;   // 0.02..0.14
  root.style.setProperty('--glass-blur', `${blur}px`);
  root.style.setProperty('--glass-alpha', alpha.toFixed(3));
  root.style.setProperty('--glass-border', border.toFixed(3));
  root.style.setProperty('--glass-shadow', shadow.toFixed(3));
}

// ─────────────────────────────────────────────────────────────
// side imagery
// ─────────────────────────────────────────────────────────────
const IMG_SRC = {
  illinois:   'assets/illinois.png',
  nainital:   'assets/nainital.jpg',
  spaceneedle:'assets/spaceneedle.png',
  none: null
};

const IMG_FRAMING = {
  illinois:    { fit: 'contain', scale: 0.85, align: 'center', bg: '#13294b' },
  nainital:    { fit: 'cover', scale: 1.15, align: '65% center' },
  spaceneedle: { fit: 'cover', scale: 1.0, align: 'center 30%' }
};

function parseStack(s) {
  if (!s || s === 'none') return [];
  return s.split('+').filter((k) => IMG_SRC[k]);
}

function SideStack({ side, stack, scrollY, opacity, saturation, factor, floatY }) {
  if (!stack || stack.length === 0) return null;
  const ty = (scrollY * factor) + (floatY || 0);
  return (
    <div className={`side ${side}`} aria-hidden="true">
      <div
        className="stack"
        style={{
          transform: `translate3d(0, ${ty}px, 0)`,
          opacity,
          filter: `saturate(${saturation})`
        }}
      >
        {stack.map((key, i) => {
          const f = IMG_FRAMING[key] || { fit: 'cover', align: 'center', scale: 1 };
          return (
            <div
              className={`slot fit-${f.fit}`}
              key={key + i}
              style={f.bg ? { background: f.bg } : undefined}
            >
              <img
                src={IMG_SRC[key]}
                alt=""
                style={{
                  objectPosition: f.align,
                  transform: `scale(${f.scale})`
                }}
              />
            </div>
          );
        })}
      </div>
    </div>
  );
}

// ─────────────────────────────────────────────────────────────
// nav
// ─────────────────────────────────────────────────────────────
function Nav() {
  return (
    <nav className="nav" aria-label="Section navigation">
      <span className="name">Arpit</span>
      <span className="dot"></span>
      <a href="#about">About</a>
      <a href="#experience">Experience</a>
      <a href="#education">Education</a>
      <a href="#skills">Skills</a>
    </nav>
  );
}

// ─────────────────────────────────────────────────────────────
// hero
// ─────────────────────────────────────────────────────────────
function Hero({ content }) {
  return (
    <header className="hero">
      <div className="eyebrow">{content.hero.eyebrow}</div>
      <h1>
        Arpit Dev <span className="italic">Mathur</span>
      </h1>
      <p className="tagline">{content.hero.tagline}</p>
      <div className="meta-row">
        <a className="pill" href="#" onClick={(e) => {
          e.preventDefault();
          const u = ['arpitdevmathur', 'gmail.com'];
          window.location.href = `mailto:${u[0]}@${u[1]}`;
        }}>
          <svg viewBox="0 0 16 16" fill="none" stroke="currentColor" strokeWidth="1.5">
            <rect x="2" y="3.5" width="12" height="9" rx="1.5" />
            <path d="M2.5 4.5l5.5 4 5.5-4" />
          </svg>
          Email me
        </a>
        <a className="pill" href={content.meta.resumePdf} target="_blank" rel="noopener">
          <svg viewBox="0 0 16 16" fill="none" stroke="currentColor" strokeWidth="1.5">
            <path d="M9 1.7H4.6A1.6 1.6 0 0 0 3 3.3v9.4A1.6 1.6 0 0 0 4.6 14.3h6.8A1.6 1.6 0 0 0 13 12.7V5.7z" />
            <path d="M9 1.7v4h4" />
          </svg>
          Résumé
        </a>
        <span className="pill">
          <svg viewBox="0 0 16 16" fill="none" stroke="currentColor" strokeWidth="1.5">
            <circle cx="8" cy="6.5" r="2.2" />
            <path d="M8 1.5c3 0 5 2.2 5 4.8 0 3.5-5 7.7-5 7.7s-5-4.2-5-7.7c0-2.6 2-4.8 5-4.8z" />
          </svg>
          San Francisco, CA
        </span>
      </div>
    </header>
  );
}

// ─────────────────────────────────────────────────────────────
// about
// ─────────────────────────────────────────────────────────────
function About({ content }) {
  return (
    <section id="about" className="about">
      <div className="section-head">
        <span className="label">About</span>
        <span className="index">01 / 04</span>
      </div>
      <p>
        <span className="lead">{content.about.lead}</span>
      </p>
      {content.about.paragraphs.map((para, i) => <p key={i}>{para}</p>)}
      <div className="signature">— Arpit</div>
    </section>
  );
}

// ─────────────────────────────────────────────────────────────
// experience
// ─────────────────────────────────────────────────────────────
function Experience({ roles }) {
  return (
    <section id="experience">
      <div className="section-head">
        <span className="label">Experience</span>
        <span className="index">02 / 04</span>
      </div>
      {roles.map((r, i) => (
        <div className="role" key={i}>
          <div className="when">
            <div>{r.when.start}</div>
            <div>↓</div>
            <div className={r.when.now ? 'now' : ''}>{r.when.end}</div>
          </div>
          <div className="body">
            <h3>{r.title}</h3>
            <div className="company">
              {r.company}<span className="loc">{r.loc}</span>
            </div>
            <div className="projects">
              {r.projects.map((p, j) => (
                <div className="project" key={j}>
                  {p.name && (
                    <h4>
                      {p.name}
                      {p.kicker && <span className="kicker">{p.kicker}</span>}
                    </h4>
                  )}
                  <ul>
                    {p.bullets.map((b, k) => <li key={k}>{b}</li>)}
                  </ul>
                </div>
              ))}
            </div>
          </div>
        </div>
      ))}
    </section>
  );
}

// ─────────────────────────────────────────────────────────────
// education — shared shell, identical across all role variants (like
//   Nav/Footer). Intentionally not driven by content/*.jsx: schools and
//   tags are the same for every role. Parameterize only when a role needs
//   different education copy (see todo.md role-specific USF tags).
// ─────────────────────────────────────────────────────────────
function Education() {
  return (
    <section id="education">
      <div className="section-head">
        <span className="label">Education</span>
        <span className="index">03 / 04</span>
      </div>
      <div className="edu-list">
        <div className="edu">
          <div className="when">2024 — 2026</div>
          <div>
            <div className="school">University of San Francisco</div>
            <div className="degree">M.S., Data Science &amp; Artificial Intelligence</div>
          </div>
          <div className="badge">Expected May '26</div>
        </div>
        <div className="edu">
          <div className="when">2012 — 2016</div>
          <div>
            <div className="school">University of Illinois at Urbana&#8209;Champaign</div>
            <div className="degree">B.S., Computer Science</div>
          </div>
          <div className="badge">B.S. '16</div>
          <div className="achievements">
            <span className="tag">Dean's List</span>
            <span className="tag">TA — CS 242 Programming Studio</span>
            <span className="tag">TA — CS 225 Data Structures</span>
            <span className="tag">PURE Research Assistant</span>
          </div>
        </div>
      </div>
    </section>
  );
}

// ─────────────────────────────────────────────────────────────
// skills
// ─────────────────────────────────────────────────────────────
function Skills({ groups }) {
  return (
    <section id="skills">
      <div className="section-head">
        <span className="label">Skills</span>
        <span className="index">04 / 04</span>
      </div>
      {groups.map((g, i) => (
        <div className="skill-group" key={i}>
          <div className="cat">{g.cat}</div>
          <div className="items">
            {g.items.map((s, j) => (
              <span key={j} className={`skill ${s.primary ? 'primary' : ''}`}>{s.name}</span>
            ))}
          </div>
        </div>
      ))}
    </section>
  );
}

// ─────────────────────────────────────────────────────────────
// footer
// ─────────────────────────────────────────────────────────────
function Footer() {
  return (
    <footer>
      <div className="colophon">© 2026 — Arpit Dev Mathur</div>
      <div className="right">made with care, in SF</div>
    </footer>
  );
}

// ─────────────────────────────────────────────────────────────
// app
// ─────────────────────────────────────────────────────────────
const STACK_OPTIONS = [
  { value: 'illinois',              label: 'Illinois' },
  { value: 'nainital',              label: 'Nainital' },
  { value: 'spaceneedle',           label: 'Space Needle' },
  { value: 'illinois+spaceneedle',  label: 'Illinois + Space Needle' },
  { value: 'nainital+illinois',     label: 'Nainital + Illinois' },
  { value: 'nainital+spaceneedle',  label: 'Nainital + Space Needle' },
  { value: 'none',                  label: 'None' }
];

function App() {
  const content = resolveContent();
  const [t, setTweak] = useTweaks(TWEAK_DEFAULTS);
  const scrollY = useScrollY();

  useEffect(() => { applyGlassVars(t.glass); }, [t.glass]);
  useEffect(() => { document.title = content.meta.docTitle; }, [content]);

  // motion
  const motionFactor =
    t.motion === 'parallax' ? 1 :
    t.motion === 'subtle'   ? 0.4 :
    0; // off & float ignore scroll factor

  // gentle independent float for the "float" option
  const [floatT, setFloatT] = useState(0);
  useEffect(() => {
    if (t.motion !== 'float') return;
    let raf;
    const start = performance.now();
    const tick = (now) => {
      setFloatT((now - start) / 1000);
      raf = requestAnimationFrame(tick);
    };
    raf = requestAnimationFrame(tick);
    return () => cancelAnimationFrame(raf);
  }, [t.motion]);

  const leftFactor  = motionFactor * -0.12;
  const rightFactor = motionFactor * -0.20;
  const leftFloat   = t.motion === 'float' ? Math.sin(floatT * 0.6) * 14 : 0;
  const rightFloat  = t.motion === 'float' ? Math.cos(floatT * 0.5 + 1) * 18 : 0;

  return (
    <div className={`palette-${t.palette} typo-${t.typography} density-${t.density}`}>
      <SideStack
        side="left"
        stack={parseStack(t.leftStack)}
        scrollY={scrollY}
        opacity={t.imageryOpacity}
        saturation={t.imagerySaturation}
        factor={leftFactor}
        floatY={leftFloat}
      />
      <SideStack
        side="right"
        stack={parseStack(t.rightStack)}
        scrollY={scrollY}
        opacity={t.imageryOpacity}
        saturation={t.imagerySaturation}
        factor={rightFactor}
        floatY={rightFloat}
      />

      <Nav />

      <main>
        <Hero content={content} />
        <About content={content} />
        <Experience roles={content.roles} />
        <Education />
        <Skills groups={content.skills} />
        <Footer />
      </main>

      <TweaksPanel>
        <TweakSection label="Palette" />
        <TweakSelect label="Paper tone" value={t.palette}
          options={[
            { value: 'paper',    label: 'Paper · warm white' },
            { value: 'cream',    label: 'Cream · sand' },
            { value: 'bone',     label: 'Bone · cool white' },
            { value: 'graphite', label: 'Graphite · dark' }
          ]}
          onChange={(v) => setTweak('palette', v)} />

        <TweakSection label="Liquid glass" />
        <TweakSlider label="Intensity" value={t.glass} min={0} max={10} step={1}
          onChange={(v) => setTweak('glass', v)} />

        <TweakSection label="Side imagery" />
        <TweakSelect label="Left side"  value={t.leftStack}  options={STACK_OPTIONS}
          onChange={(v) => setTweak('leftStack', v)} />
        <TweakSelect label="Right side" value={t.rightStack} options={STACK_OPTIONS}
          onChange={(v) => setTweak('rightStack', v)} />
        <TweakSlider label="Opacity" value={t.imageryOpacity} min={0} max={0.6} step={0.02}
          onChange={(v) => setTweak('imageryOpacity', v)} />
        <TweakSlider label="Saturation" value={t.imagerySaturation} min={0} max={1.2} step={0.05}
          onChange={(v) => setTweak('imagerySaturation', v)} />

        <TweakSection label="Side motion" />
        <TweakRadio label="Mode" value={t.motion}
          options={[
            { value: 'off',      label: 'Off' },
            { value: 'subtle',   label: 'Subtle' },
            { value: 'parallax', label: 'Parallax' },
            { value: 'float',    label: 'Float' }
          ]}
          onChange={(v) => setTweak('motion', v)} />

        <TweakSection label="Typography" />
        <TweakRadio label="Display face" value={t.typography}
          options={[
            { value: 'instrument',  label: 'Instrument' },
            { value: 'newsreader',  label: 'Newsreader' },
            { value: 'sans',        label: 'All sans' }
          ]}
          onChange={(v) => setTweak('typography', v)} />

        <TweakSection label="Density" />
        <TweakRadio label="Layout" value={t.density}
          options={[
            { value: 'tight',   label: 'Tight' },
            { value: 'regular', label: 'Regular' },
            { value: 'airy',    label: 'Airy' }
          ]}
          onChange={(v) => setTweak('density', v)} />
      </TweaksPanel>
    </div>
  );
}

// ─────────────────────────────────────────────────────────────
// mount
// ─────────────────────────────────────────────────────────────
ReactDOM.createRoot(document.getElementById('root')).render(<App />);
