// ─────── SIMPLE / AUDIENCE VIEWS ───────

function AudienceGate({ onChoose, deps }) {
  const { AUDIENCE } = deps.constants;
  return (
    <main className="audience-gate">
      <div className="gate-card">
        <p className="gate-kicker">love.sahaj / portfolio</p>
        <h1>Pick signal, not skin.</h1>
        <p>
          Same work, two doors. Simple view reads like crisp CV. Neovim view keeps full
          Neovim playground, keyboard controls, buffers, and terminal energy.
        </p>
        <div className="gate-actions">
          <button type="button" onClick={() => onChoose(AUDIENCE.SIMPLE)}>
            <span>Simple</span>
            <small>simple résumé page</small>
          </button>
          <button type="button" onClick={() => onChoose(AUDIENCE.NEOVIM)}>
            <span>Neovim</span>
            <small>Neovim portfolio</small>
          </button>
        </div>
      </div>
    </main>
  );
}

function AnimatedMetric({ big, unit = '', label }) {
  const ref = React.useRef(null);
  const started = React.useRef(false);
  const rafs = React.useRef(new Set());
  const [shown, setShown] = React.useState(0);
  const [target, suffix] = React.useMemo(() => {
    const m = /^([\d.]+)(.*)$/.exec(big);
    if (!m) return [null, big];
    return [parseFloat(m[1]), m[2] || ''];
  }, [big]);

  React.useEffect(() => {
    if (target == null) return;
    const node = ref.current;
    if (!node) return;
    started.current = false;
    rafs.current.forEach((id) => cancelAnimationFrame(id));
    rafs.current.clear();

    const obs = new IntersectionObserver((entries) => {
      if (started.current || !entries.some((entry) => entry.isIntersecting)) return;
      started.current = true;
      obs.disconnect();
      const start = performance.now();
      const dur = 1100;
      const tick = (now) => {
        const t = Math.min(1, (now - start) / dur);
        const eased = 1 - Math.pow(1 - t, 3);
        setShown(target * eased);
        if (t < 1) {
          const id = requestAnimationFrame(tick);
          rafs.current.add(id);
        }
      };
      const id = requestAnimationFrame(tick);
      rafs.current.add(id);
    }, { threshold: 0.4 });
    obs.observe(node);
    return () => {
      obs.disconnect();
      rafs.current.forEach((id) => cancelAnimationFrame(id));
      rafs.current.clear();
    };
  }, [target]);

  const display = target == null
    ? big
    : (target >= 100 ? Math.round(shown) : shown.toFixed(target < 10 && !Number.isInteger(target) ? 1 : 0));

  return (
    <article ref={ref} className="metric-card">
      <strong>{display}{suffix}{unit}</strong>
      <span>{label}</span>
    </article>
  );
}

function ProjectCard({ project, expanded, onToggle, renderInline }) {
  const links = project.links || (project.link ? [{ label: 'repo', url: project.link }] : []);
  return (
    <article className={`project-card${expanded ? ' is-open' : ''}`}>
      <button type="button" className="project-head" onClick={onToggle} aria-expanded={expanded}>
        <span className="project-year">{project.year}</span>
        <h2>{project.name}</h2>
        <span className="project-toggle" aria-hidden="true">{expanded ? '−' : '+'}</span>
      </button>
      <p className="project-blurb">{project.blurb}</p>
      <div className="project-stack">
        {project.stack.map((s) => <b key={s}>{s}</b>)}
      </div>
      {expanded && (
        <div className="project-detail">
          <ul>
            {(project.highlights || []).map((h, i) => <li key={i}>{renderInline(h)}</li>)}
          </ul>
          {links.length > 0 && (
            <div className="project-links">
              {links.map((l, i) => (
                <a key={`${l.url}-${i}`} href={l.url} target="_blank" rel="noreferrer">{l.label} ↗</a>
              ))}
            </div>
          )}
        </div>
      )}
    </article>
  );
}

function ExperienceCard({ exp, renderInline }) {
  const [open, setOpen] = React.useState(false);
  const showAll = open || exp.bullets.length <= 2;
  const visible = showAll ? exp.bullets : exp.bullets.slice(0, 2);
  return (
    <article className={`exp-card${open ? ' is-open' : ''}`}>
      <div className="exp-meta">
        <strong>{exp.dates}</strong>
        <span>{exp.loc}</span>
      </div>
      <div className="exp-body">
        <h2>{exp.role}</h2>
        <p>{exp.org}</p>
        <ul>{visible.map((b, i) => <li key={i}>{renderInline(b)}</li>)}</ul>
        {exp.bullets.length > 2 && (
          <button type="button" className="exp-more" onClick={() => setOpen((v) => !v)}>
            {open ? 'Show less' : `Show ${exp.bullets.length - 2} more`}
          </button>
        )}
      </div>
    </article>
  );
}

function SimplePortfolio({ onSwitch, deps }) {
  const { data, posts, routing, utils } = deps;
  const { SIMPLE_SECTIONS } = deps.constants;
  const [activeSection, setActiveSection] = React.useState('about');
  const [openProject, setOpenProject] = React.useState(null);
  const [copied, setCopied] = React.useState(false);
  const [selectedPost, setSelectedPost] = React.useState(null);

  const parsePostHash = () => {
    return routing.parseWritingSlug();
  };

  const openPost = (slug) => {
    const post = posts.find((p) => p.slug === slug);
    if (!post) return;
    setSelectedPost(post);
    if (parsePostHash() !== slug) {
      history.pushState(null, '', routing.hashForBuffer('writing', slug));
    }
    try { window.scrollTo({ top: 0, behavior: 'auto' }); } catch {}
  };

  const closePost = () => {
    setSelectedPost(null);
    if (parsePostHash()) {
      history.pushState(null, '', '#r-writing');
    }
    setTimeout(() => {
      const el = document.getElementById('r-writing');
      if (el) el.scrollIntoView({ behavior: 'auto', block: 'start' });
    }, 0);
  };

  // open post from initial URL on mount
  React.useEffect(() => {
    const slug = parsePostHash();
    if (!slug) return;
    const post = posts.find((p) => p.slug === slug);
    if (post) setSelectedPost(post);
  }, [posts]);

  // react to back/forward navigation
  React.useEffect(() => {
    const onHash = () => {
      const slug = parsePostHash();
      if (slug) {
        const post = posts.find((p) => p.slug === slug);
        setSelectedPost(post || null);
      } else {
        setSelectedPost(null);
      }
    };
    window.addEventListener('hashchange', onHash);
    return () => window.removeEventListener('hashchange', onHash);
  }, [posts]);

  React.useEffect(() => {
    if (!selectedPost) return;
    const handler = (e) => {
      if (e.key === 'Escape') closePost();
    };
    window.addEventListener('keydown', handler);
    return () => window.removeEventListener('keydown', handler);
  }, [selectedPost]);

  React.useEffect(() => {
    const sections = SIMPLE_SECTIONS
      .map((s) => document.getElementById(`r-${s.id}`))
      .filter(Boolean);
    if (!sections.length) return;
    const obs = new IntersectionObserver((entries) => {
      const visible = entries
        .filter((e) => e.isIntersecting)
        .sort((a, b) => b.intersectionRatio - a.intersectionRatio);
      if (visible[0]) setActiveSection(visible[0].target.id.replace('r-', ''));
    }, { rootMargin: '-35% 0px -55% 0px', threshold: [0, 0.2, 0.5, 1] });
    sections.forEach((s) => obs.observe(s));
    return () => obs.disconnect();
  }, []);

  const copyEmail = async () => {
    try {
      await navigator.clipboard.writeText(data.email);
      setCopied(true);
      setTimeout(() => setCopied(false), 1800);
    } catch {}
  };

  if (selectedPost) {
    return (
      <main className="simple-page simple-reader">
        <header className="simple-topbar reader-topbar">
          <button type="button" className="reader-back" onClick={closePost}>
            ← back to writing
          </button>
          <div className="simple-topbar-actions">
            <button type="button" className="view-switch" onClick={() => onSwitch('writing', selectedPost.slug)}>
              open in neovim →
            </button>
          </div>
        </header>
        <article className="reader-article">
          <header className="reader-head">
            <div className="reader-meta">
              <span>{utils.formatPostDate(selectedPost.date)}</span>
              {(selectedPost.tags || []).map((t) => (
                <span key={t} className="reader-tag">#{t}</span>
              ))}
            </div>
            <h1>{selectedPost.title}</h1>
            {selectedPost.excerpt && <p className="reader-excerpt">{selectedPost.excerpt}</p>}
          </header>
          <div
            className="reader-body"
            dangerouslySetInnerHTML={{ __html: selectedPost.html }}
          />
          <div className="reader-foot">
            <button type="button" className="reader-back" onClick={closePost}>← back to writing</button>
          </div>
        </article>
      </main>
    );
  }

  return (
    <main className="simple-page">
      <header className="simple-topbar">
        <div className="brand">
          <span className="brand-mark">●</span>
          <span>{data.handle}</span>
        </div>
        <nav className="simple-anchors">
          {SIMPLE_SECTIONS.map((s) => (
            <a key={s.id} href={`#r-${s.id}`} className={activeSection === s.id ? 'is-active' : ''}>
              {s.label}
            </a>
          ))}
        </nav>
        <div className="simple-topbar-actions">
          <button type="button" className="view-switch" onClick={() => onSwitch()}>neovim view →</button>
        </div>
      </header>

      <section id="r-about" className="simple-hero">
        <p className="gate-kicker">ML infrastructure · backend · distributed systems</p>
        <h1>{data.name}</h1>
        <p className="hero-tagline">{data.tagline}</p>
        <p>{data.summary}</p>
        <div className="simple-cta">
          <button type="button" className="cta-primary" onClick={copyEmail}>
            {copied ? '✓ Copied' : `Copy ${data.email}`}
          </button>
          <a href={`https://${data.linkedin}`} target="_blank" rel="noreferrer">LinkedIn</a>
          <a href={`https://${data.github}`} target="_blank" rel="noreferrer">GitHub</a>
        </div>
      </section>

      <section className="simple-metrics" aria-label="Impact metrics">
        {data.metrics.map((m) => (
          <AnimatedMetric key={`${m.big}-${m.label}`} big={m.big} unit={m.unit} label={m.label} />
        ))}
      </section>

      <section id="r-now" className="simple-section">
        <div className="section-label">Right now</div>
        <div className="now-grid">
          {data.now.map((n) => (
            <article key={n.tag} className="now-card">
              <span className="now-tag">{n.tag}</span>
              <h3>{n.title}</h3>
              <p>{n.body}</p>
            </article>
          ))}
        </div>
      </section>

      <section id="r-projects" className="simple-section">
        <div className="section-label">Projects</div>
        <div className="simple-projects">
          {data.projects.map((p) => (
            <ProjectCard
              key={p.id}
              project={p}
              expanded={openProject === p.id}
              onToggle={() => setOpenProject(openProject === p.id ? null : p.id)}
              renderInline={utils.renderInline}
            />
          ))}
        </div>
      </section>

      <section id="r-experience" className="simple-section">
        <div className="section-label">Experience</div>
        <div className="simple-timeline">
          {data.experience.map((e) => (
            <ExperienceCard
              key={`${e.role}-${e.org}-${e.dates}`}
              exp={e}
              renderInline={utils.renderInline}
            />
          ))}
        </div>
      </section>

      {posts.length > 0 && (
        <section id="r-writing" className="simple-section">
          <div className="section-label">Writing</div>
          <div className="writing-list-r">
            {posts.map((post) => (
              <button key={post.slug} type="button" className="writing-card-r" onClick={() => openPost(post.slug)}>
                <div className="writing-meta-r">
                  <span>{post.date}</span>
                  {post.tags && post.tags.length > 0 && (
                    <span className="writing-tags-r">{post.tags.slice(0, 3).map((t) => `#${t}`).join(' ')}</span>
                  )}
                </div>
                <h3>{post.title}</h3>
                {post.excerpt && <p>{post.excerpt}</p>}
                <span className="writing-cta-r">Read post →</span>
              </button>
            ))}
          </div>
        </section>
      )}

      <section id="r-education" className="simple-section">
        <div className="section-label">Education</div>
        <div className="edu-list">
          {data.education.map((ed) => (
            <article key={ed.school} className="edu-card">
              <div><strong>{ed.dates}</strong></div>
              <div>
                <h3>{ed.school}</h3>
                <p>{ed.degree}</p>
                {ed.extra && <small>{ed.extra}</small>}
              </div>
            </article>
          ))}
        </div>
      </section>

      <section id="r-skills" className="simple-section simple-skills">
        <div className="section-label">Skills</div>
        <div className="skill-groups">
          {data.skills.map((group) => (
            <div key={group.k} className="skill-group">
              <h3>{group.k}</h3>
              <div className="skill-chips">
                {group.v.map((s, i) => {
                  const hot = Array.isArray(group.hot) ? group.hot.includes(i) : group.hot === i;
                  return <span key={s} className={`skill-chip${hot ? ' is-hot' : ''}`}>{s}</span>;
                })}
              </div>
            </div>
          ))}
        </div>
      </section>

      <footer className="simple-footer">
        <div>
          <p className="gate-kicker">Let's talk</p>
          <button type="button" className="footer-email" onClick={copyEmail}>
            {copied ? '✓ Copied' : data.email}
          </button>
        </div>
      </footer>
    </main>
  );
}
