// Section components for the portfolio
//
// Pulls TECH/TIMELINE/PROJECTS from window (portfolio-data.jsx)
// and the bits/hooks from portfolio-bits.jsx.

const { useEffect: _useEffect, useState: _useState, useRef: _useRef } = React;

/* ───────────────────────────────────────────────────────────
   Nav
   ─────────────────────────────────────────────────────────── */
function Nav({ name }) {
  const [scrolled, setScrolled] = _useState(false);
  _useEffect(() => {
    const f = () => setScrolled(window.scrollY > 16);
    f();
    window.addEventListener("scroll", f, { passive: true });
    return () => window.removeEventListener("scroll", f);
  }, []);
  const initials = (name || "").split(" ").map(w => w[0]).slice(0,2).join("");
  return (
    <nav className={"nav " + (scrolled ? "scrolled" : "")}>
      <div className="brand">
        <div className="brand-mark" aria-hidden="true" />
        <span>{name}</span>
      </div>
      <div className="nav-links">
        <a href="#work">Work</a>
        <a href="#timeline">Experience</a>
        <a href="#stack">Stack</a>
        <a href="#testimonials">Praise</a>
        <a href="#contact">Contact</a>
      </div>
      <a className="nav-cta" href="#contact">
        Let's talk
        <svg width="12" height="12" viewBox="0 0 12 12" fill="none">
          <path d="M3 9l6-6M5 3h4v4" stroke="currentColor" strokeWidth="1.4" strokeLinecap="round" strokeLinejoin="round"/>
        </svg>
      </a>
    </nav>
  );
}

/* ───────────────────────────────────────────────────────────
   Hero
   ─────────────────────────────────────────────────────────── */
function Hero({ name, role, tagline }) {
  const y = useScrollY();
  // The hero 3D object: rotates with scroll
  const rotX = -18 + y * 0.18;
  const rotY = 24 + y * 0.32;
  const rotZ = y * 0.06;
  const floatY = Math.sin(y * 0.004) * 8;

  // Name split for accent style — last word gets gradient accent.
  const parts = (name || "").trim().split(/\s+/).filter(Boolean);
  const accentWord = parts.length > 1 ? parts.pop() : (parts[0] || "");
  const leading = parts.length > 1 ? parts.join(" ") : "";

  return (
    <section className="hero" id="top">
      <div className="container hero-grid">
        <div>
          <div className="reveal" style={{ transitionDelay: "60ms" }}>
            <span className="hero-status">
              <span className="dot"></span>
              Available for new work · 2026
            </span>
          </div>
          <h1 className="reveal" style={{ transitionDelay: "160ms" }}>
            {leading && <>{leading}{" "}</>}
            <span className="accent">{accentWord}.</span>
            <span className="role">{role}</span>
          </h1>
          <p className="hero-tagline reveal" style={{ transitionDelay: "260ms" }}>
            {tagline}
          </p>
          <div className="cta-row reveal" style={{ transitionDelay: "340ms" }}>
            <a href="#work" className="btn btn-primary">
              View Projects
              <svg className="arrow" width="14" height="14" viewBox="0 0 14 14" fill="none">
                <path d="M3 11L11 3M5 3h6v6" stroke="currentColor" strokeWidth="1.6" strokeLinecap="round" strokeLinejoin="round"/>
              </svg>
            </a>
            <a href="#contact" className="btn btn-ghost">
              Contact Me
              <svg width="14" height="14" viewBox="0 0 14 14" fill="none">
                <path d="M2 3.5l5 4 5-4M2 3h10v8H2z" stroke="currentColor" strokeWidth="1.4" strokeLinecap="round" strokeLinejoin="round"/>
              </svg>
            </a>
          </div>

          <dl className="hero-meta reveal" style={{ marginTop: 56, transitionDelay: "420ms" }}>
            <div><dt>Based in</dt><dd>Gelderland, NL</dd></div>
            <div><dt>Currently</dt><dd>Kema Labs</dd></div>
            <div><dt>Focus</dt><dd>Java · Data · Backend</dd></div>
            <div><dt>Projects</dt><dd>10+ advanced systems</dd></div>
          </dl>
        </div>

        {/* Scroll-driven 3D object */}
        <div
          className="hero-3d reveal"
          style={{
            transitionDelay: "200ms",
            width: 360, height: 360,
            display: "grid", placeItems: "center",
            position: "relative",
          }}
        >
          <div
            className="scene"
            style={{
              width: "100%", height: "100%",
              display: "grid", placeItems: "center",
              transform: `translateY(${floatY}px)`,
            }}
          >
            <Cube size={220} rotateX={rotX} rotateY={rotY} rotateZ={rotZ} />
          </div>
          <div style={{
            position: "absolute", inset: -20, borderRadius: "50%",
            background: "radial-gradient(50% 50% at 50% 50%, color-mix(in oklab, var(--accent) 22%, transparent), transparent 70%)",
            zIndex: -1, filter: "blur(8px)",
          }}/>
        </div>
      </div>

      <div className="scroll-hint" aria-hidden="true">
        <span>Scroll</span>
        <span className="line"></span>
      </div>
    </section>
  );
}

/* ───────────────────────────────────────────────────────────
   Skills marquee
   ─────────────────────────────────────────────────────────── */
function SkillsBar({ speed }) {
  const tech = window.TECH;
  // duplicate so the loop is seamless
  const doubled = [...tech, ...tech];
  return (
    <section className="skills" id="stack">
      <div className="container">
        <div className="skills-label">// the toolbox</div>
      </div>
      <div className="marquee" style={{ "--marquee-duration": (60 - speed) + "s" }}>
        <div className="marquee-track">
          {doubled.map((t, i) => (
            <div key={i} className="chip" title={t.name}>
              <span className="glow" style={{ color: t.color, display: "inline-flex" }}>
                {t.icon}
              </span>
              <span>{t.name}</span>
            </div>
          ))}
        </div>
      </div>
    </section>
  );
}

/* ───────────────────────────────────────────────────────────
   Timeline
   ─────────────────────────────────────────────────────────── */
function Timeline() {
  const tl = window.TIMELINE;
  const ref = _useRef(null);
  const [progress, setProgress] = _useState(0);

  _useEffect(() => {
    const onScroll = () => {
      const el = ref.current;
      if (!el) return;
      const rect = el.getBoundingClientRect();
      const vh = window.innerHeight;
      // Progress: 0 when timeline-top hits middle of viewport, 1 when bottom-top.
      const start = vh * 0.6;
      const end = -rect.height + vh * 0.4;
      const raw = (start - rect.top) / (start - end);
      setProgress(Math.max(0, Math.min(1, raw)));
    };
    onScroll();
    window.addEventListener("scroll", onScroll, { passive: true });
    window.addEventListener("resize", onScroll);
    return () => {
      window.removeEventListener("scroll", onScroll);
      window.removeEventListener("resize", onScroll);
    };
  }, []);

  return (
    <section id="timeline">
      <div className="container">
        <div className="reveal">
          <div className="eyebrow">02 / Career</div>
          <h2 className="section-title">A path through the stack — from CS dorm to staff-level.</h2>
          <p className="section-sub">Six years across consumer products, dev tooling, and B2B platforms. Each stop pushed the envelope on either system design, motion, or developer experience.</p>
        </div>

        <div
          className="timeline"
          ref={ref}
          style={{ "--progress": (progress * 100).toFixed(2) + "%" }}
        >
          {tl.map((item, i) => (
            <TimelineRow key={i} item={item} index={i} />
          ))}
        </div>
      </div>
    </section>
  );
}

function TimelineRow({ item, index }) {
  const ref = _useRef(null);
  const [inView, setInView] = _useState(false);
  _useEffect(() => {
    const el = ref.current;
    if (!el) return;
    const io = new IntersectionObserver(
      ([e]) => {
        if (e.isIntersecting) {
          setInView(true);
          io.unobserve(el);
        }
      },
      { threshold: 0.25 }
    );
    io.observe(el);
    return () => io.disconnect();
  }, []);

  const side = index % 2 === 0 ? "reveal-r" : "reveal-l";

  return (
    <div ref={ref} className={"tl-row " + (inView ? "in" : "")}>
      <div className="tl-dot"></div>
      <div className={"tl-card reveal " + side + " " + (inView ? "in" : "")} style={{ transitionDelay: "120ms" }}>
        <div className="tl-date">{item.date}</div>
        <div className="tl-title">{item.title}</div>
        <div className="tl-company">{item.company}</div>
        <p className="tl-desc">{item.desc}</p>
        <div className="tl-tags">
          {item.tags.map((t) => <span key={t} className="tag">{t}</span>)}
        </div>
      </div>
    </div>
  );
}

/* ───────────────────────────────────────────────────────────
   Projects
   ─────────────────────────────────────────────────────────── */
function Projects() {
  const items = window.PROJECTS;
  return (
    <section id="work">
      <div className="container">
        <div className="reveal" style={{ display: "flex", justifyContent: "space-between", alignItems: "flex-end", flexWrap: "wrap", gap: 24, marginBottom: 40 }}>
          <div>
            <div className="eyebrow">03 / Selected work</div>
            <h2 className="section-title">Things I've shipped, broken, and learned from.</h2>
          </div>
          <p style={{ color: "var(--text-dim)", maxWidth: "38ch", margin: 0 }}>
            A small set of recent projects. Reach out if you'd like a deeper walkthrough of any of them.
          </p>
        </div>

        <div className="proj-grid">
          {items.map((p, i) => (
            <ProjectCard key={p.title} p={p} index={i} />
          ))}
        </div>
      </div>
    </section>
  );
}

function ProjectCard({ p, index }) {
  const ref = _useRef(null);

  const onMove = (e) => {
    const el = ref.current;
    if (!el) return;
    const r = el.getBoundingClientRect();
    const x = (e.clientX - r.left) / r.width - 0.5;
    const y = (e.clientY - r.top) / r.height - 0.5;
    el.style.transform = `perspective(900px) rotateY(${x * 6}deg) rotateX(${-y * 6}deg) translateY(-4px)`;
  };
  const onLeave = () => {
    const el = ref.current;
    if (el) el.style.transform = "";
  };

  return (
    <article
      ref={ref}
      className="proj reveal"
      style={{ transitionDelay: (index * 100) + "ms" }}
      onMouseMove={onMove}
      onMouseLeave={onLeave}
    >
      <div className="proj-media">
        <div className="ph">
          <span className="label">{p.label}</span>
        </div>
      </div>
      <div className="proj-body">
        <div className="proj-num">PROJECT — {p.n}</div>
        <h3 className="proj-title">{p.title}</h3>
        <p className="proj-desc">{p.desc}</p>
        <div className="proj-tags">
          {p.tags.map((t) => <span key={t} className="tag">{t}</span>)}
        </div>
        <div className="proj-actions">
          <button className="btn-sm">
            <svg viewBox="0 0 16 16" fill="none">
              <path d="M8 1.5a6.5 6.5 0 0 0-2 12.7c.3 0 .4-.15.4-.3v-1.1c-1.8.4-2.2-.8-2.2-.8-.3-.7-.7-.9-.7-.9-.6-.4 0-.4 0-.4.6 0 1 .7 1 .7.6 1 1.5.7 1.9.6 0-.4.2-.7.4-.9-1.4-.2-2.9-.7-2.9-3.2 0-.7.3-1.3.7-1.7-.1-.2-.3-.9.1-1.8 0 0 .6-.2 1.8.7.5-.1 1-.2 1.5-.2s1 0 1.5.2c1.2-.9 1.8-.7 1.8-.7.4.9.1 1.6.1 1.8.4.4.7 1 .7 1.7 0 2.5-1.5 3-2.9 3.2.2.2.4.6.4 1.3v1.8c0 .2.1.3.4.3A6.5 6.5 0 0 0 8 1.5z" fill="currentColor"/>
            </svg>
            Code
          </button>
          <button className="btn-sm primary">
            Live demo
            <svg viewBox="0 0 16 16" fill="none">
              <path d="M4 12L12 4M6 4h6v6" stroke="currentColor" strokeWidth="1.6" strokeLinecap="round" strokeLinejoin="round"/>
            </svg>
          </button>
        </div>
      </div>
    </article>
  );
}

/* ───────────────────────────────────────────────────────────
   Testimonials
   ─────────────────────────────────────────────────────────── */
function Testimonials() {
  const items = window.TESTIMONIALS || [];
  const featured = items.find(t => t.featured) || items[0];
  const rest = items.filter(t => t !== featured);

  return (
    <section id="testimonials">
      <div className="container">
        <div className="reveal" style={{ marginBottom: 40 }}>
          <div className="eyebrow">04 / Kind words</div>
          <h2 className="section-title">What the people I've shipped alongside say.</h2>
          <p className="section-sub">A handful of notes from the engineers, founders, and managers I've worked with most closely.</p>
        </div>

        {featured && (
          <div className="testi-featured reveal">
            <div className="qmark" aria-hidden="true">"</div>
            <p className="testi-quote">{featured.quote}</p>
            <div className="testi-author">
              <span className="testi-avatar">{featured.initials}</span>
              <div className="testi-meta">
                <span className="testi-name">{featured.name}</span>
                <span className="testi-role">
                  {featured.role}<span className="sep">·</span>{featured.company}
                </span>
              </div>
            </div>
          </div>
        )}

        <div className="testi-grid">
          {rest.map((t, i) => (
            <article key={i} className="testi-card reveal" style={{ transitionDelay: (i * 90) + "ms" }}>
              <p className="body">"{t.quote}"</p>
              <div className="testi-author">
                <span className="testi-avatar">{t.initials}</span>
                <div className="testi-meta">
                  <span className="testi-name">{t.name}</span>
                  <span className="testi-role">
                    {t.role}<span className="sep">·</span>{t.company}
                  </span>
                </div>
              </div>
            </article>
          ))}
        </div>
      </div>
    </section>
  );
}

/* ───────────────────────────────────────────────────────────
   Contact
   ─────────────────────────────────────────────────────────── */
function Contact() {
  const [form, setForm] = _useState({ name: "", email: "", message: "" });
  const [err, setErr] = _useState({});
  const [status, setStatus] = _useState("");
  const [sent, setSent] = _useState(false);

  const submit = (e) => {
    e.preventDefault();
    const next = {};
    if (!form.name.trim()) next.name = "What should I call you?";
    if (!/^\S+@\S+\.\S+$/.test(form.email)) next.email = "That email looks off.";
    if (form.message.trim().length < 8) next.message = "A few more words, please.";
    setErr(next);
    if (Object.keys(next).length) {
      setStatus("Check the highlighted fields.");
      return;
    }
    setStatus("Sending…");
    setTimeout(() => {
      setSent(true);
      setStatus("Sent — I'll reply within a day or two.");
    }, 700);
  };

  return (
    <section id="contact">
      <div className="container">
        <div className="reveal" style={{ marginBottom: 40 }}>
          <div className="eyebrow">05 / Get in touch</div>
        </div>

        <div className="contact-wrap reveal">
          <div className="contact-blob b1"></div>
          <div className="contact-blob b2"></div>

          <div className="contact-info">
            <h2>Let's build something worth shipping.</h2>
            <p>I'm taking on a small number of new collaborations in 2026 — product engineering, design-engineering, or technical advising for early-stage teams.</p>

            <div className="contact-detail">
              <span className="k">Email</span>
              <span>aarav@example.dev</span>
            </div>
            <div className="contact-detail">
              <span className="k">Calendar</span>
              <span>cal.com/aarav (30-min intro)</span>
            </div>
            <div className="contact-detail">
              <span className="k">Response</span>
              <span>~24 hours, weekdays</span>
            </div>

            <div className="socials">
              <a href="#" aria-label="GitHub"><svg viewBox="0 0 16 16" fill="none"><path d="M8 1.5a6.5 6.5 0 0 0-2 12.7c.3 0 .4-.15.4-.3v-1.1c-1.8.4-2.2-.8-2.2-.8-.3-.7-.7-.9-.7-.9-.6-.4 0-.4 0-.4.6 0 1 .7 1 .7.6 1 1.5.7 1.9.6 0-.4.2-.7.4-.9-1.4-.2-2.9-.7-2.9-3.2 0-.7.3-1.3.7-1.7-.1-.2-.3-.9.1-1.8 0 0 .6-.2 1.8.7.5-.1 1-.2 1.5-.2s1 0 1.5.2c1.2-.9 1.8-.7 1.8-.7.4.9.1 1.6.1 1.8.4.4.7 1 .7 1.7 0 2.5-1.5 3-2.9 3.2.2.2.4.6.4 1.3v1.8c0 .2.1.3.4.3A6.5 6.5 0 0 0 8 1.5z" fill="currentColor"/></svg></a>
              <a href="#" aria-label="LinkedIn"><svg viewBox="0 0 16 16" fill="none"><rect x="2" y="2" width="12" height="12" rx="2" stroke="currentColor" strokeWidth="1.4"/><circle cx="5" cy="6" r=".8" fill="currentColor"/><path d="M5 8.5v3.5M8 8.5v3.5M8 10c0-1.5 3-1.5 3 0v2" stroke="currentColor" strokeWidth="1.4" strokeLinecap="round"/></svg></a>
              <a href="#" aria-label="X / Twitter"><svg viewBox="0 0 16 16" fill="none"><path d="M3 3l4.5 5.5L3 13M13 3L8.5 8.5 13 13M3 3h3l7 10h-3L3 3z" stroke="currentColor" strokeWidth="1.4" strokeLinejoin="round"/></svg></a>
              <a href="#" aria-label="Dribbble"><svg viewBox="0 0 16 16" fill="none"><circle cx="8" cy="8" r="6.5" stroke="currentColor" strokeWidth="1.4"/><path d="M2 9c4-.5 8 0 11 2M3 4c4 1 7 4 9 9M11 2c-1 4-3 8-7 11" stroke="currentColor" strokeWidth="1.3" strokeLinecap="round"/></svg></a>
              <a href="#" aria-label="Read.cv"><svg viewBox="0 0 16 16" fill="none"><rect x="3" y="2" width="10" height="12" rx="1.5" stroke="currentColor" strokeWidth="1.4"/><path d="M5 5h6M5 8h6M5 11h4" stroke="currentColor" strokeWidth="1.4" strokeLinecap="round"/></svg></a>
            </div>
          </div>

          <form className="form" onSubmit={submit} noValidate>
            <div className="form-row">
              <div className={"field " + (err.name ? "err" : "")}>
                <label htmlFor="f-name">Name</label>
                <input id="f-name" type="text" placeholder="Your name"
                  value={form.name}
                  onChange={(e) => setForm({...form, name: e.target.value})}/>
                {err.name && <div className="field-err">{err.name}</div>}
              </div>
              <div className={"field " + (err.email ? "err" : "")}>
                <label htmlFor="f-email">Email</label>
                <input id="f-email" type="email" placeholder="you@team.com"
                  value={form.email}
                  onChange={(e) => setForm({...form, email: e.target.value})}/>
                {err.email && <div className="field-err">{err.email}</div>}
              </div>
            </div>
            <div className={"field " + (err.message ? "err" : "")}>
              <label htmlFor="f-msg">Message</label>
              <textarea id="f-msg" placeholder="What are you working on?"
                value={form.message}
                onChange={(e) => setForm({...form, message: e.target.value})}/>
              {err.message && <div className="field-err">{err.message}</div>}
            </div>
            <button type="submit" className={"send-btn " + (sent ? "sent" : "")} disabled={sent}>
              {sent ? (
                <>
                  Sent
                  <svg width="14" height="14" viewBox="0 0 14 14" fill="none">
                    <path d="M3 7l3 3 5-6" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round"/>
                  </svg>
                </>
              ) : (
                <>
                  Send message
                  <svg width="14" height="14" viewBox="0 0 14 14" fill="none">
                    <path d="M2 7h10M8 3l4 4-4 4" stroke="currentColor" strokeWidth="1.6" strokeLinecap="round" strokeLinejoin="round"/>
                  </svg>
                </>
              )}
            </button>
            <div className="form-status">{status}</div>
          </form>
        </div>
      </div>
    </section>
  );
}

/* ───────────────────────────────────────────────────────────
   Footer
   ─────────────────────────────────────────────────────────── */
function Footer({ name }) {
  return (
    <footer className="footer">
      <div className="container footer-row">
        <div style={{ display: "flex", alignItems: "center", gap: 12 }}>
          <div className="brand-mark" aria-hidden="true" />
          <div>
            <div style={{ fontFamily: "var(--display)", fontWeight: 600, fontSize: 14 }}>{name}</div>
            <div className="footer-mini">© 2026 — Built with care</div>
          </div>
        </div>
        <div className="footer-mini">v2.6.1 · last shipped 2 days ago</div>
      </div>
    </footer>
  );
}

Object.assign(window, { Nav, Hero, SkillsBar, Timeline, Projects, Testimonials, Contact, Footer });
