/* Shared components: Navbar, Footer, Blob, PhoneMockup, DesktopMockup, Reveal, Tag, etc. */

const { useState, useEffect, useRef, useMemo } = React;

/* ---------- Reveal-on-scroll wrapper ---------- */
function Reveal({ children, delay = 0, as: As = "div", className = "" }) {
  const ref = useRef(null);
  useEffect(() => {
    const el = ref.current;
    if (!el) return;
    let done = false;
    let io = null, raf = 0, frames = 0, tHard = 0;
    const cleanup = () => {
      if (io) io.disconnect();
      cancelAnimationFrame(raf);
      clearTimeout(tHard);
      window.removeEventListener("scroll", onScroll, true);
      window.removeEventListener("resize", onScroll);
    };
    const reveal = () => {
      if (done) return;
      done = true;
      cleanup();
      setTimeout(() => el.classList.add("in"), delay);
    };
    const inView = () => {
      const r = el.getBoundingClientRect();
      const vh = window.innerHeight || document.documentElement.clientHeight;
      return r.bottom > 0 && r.top < vh * 0.92;
    };
    const check = () => { if (!done && inView()) reveal(); };
    const onScroll = () => check();
    // 1) IntersectionObserver — scroll-into-view + below-fold.
    if ("IntersectionObserver" in window) {
      io = new IntersectionObserver((entries) => {
        if (entries.some((e) => e.isIntersecting)) reveal();
      }, { rootMargin: "0px 0px -8% 0px", threshold: 0.01 });
      io.observe(el);
    }
    // 2) scroll/resize listeners (capture phase, in case a scroll container).
    window.addEventListener("scroll", onScroll, true);
    window.addEventListener("resize", onScroll);
    // 3) rAF poll (~1.5s) for first-paint / route transitions.
    const poll = () => {
      if (done) return;
      if (inView()) { reveal(); return; }
      if (frames++ < 90) raf = requestAnimationFrame(poll);
    };
    raf = requestAnimationFrame(poll);
    // 4) setTimeout safety — fires even when rAF/IO are throttled (background
    //    iframe). Only reveals if actually in view, so below-fold keeps its
    //    scroll animation; guarantees above-the-fold never stays blank.
    tHard = setTimeout(check, delay + 650);
    return cleanup;
  }, [delay]);
  return <As ref={ref} className={`reveal ${className}`}>{children}</As>;
}

/* ---------- Navbar ---------- */
function Navbar({ route, param, navigate }) {
  const [scrolled, setScrolled] = useState(false);
  const [hidden, setHidden] = useState(false);
  const [homeBg, setHomeBg] = useState(null);   // per-section colour while on the home page
  // On case pages the navbar wears the hero surface full-time.
  const maroon = route === "case" && param === "stablex";
  const morparaNav = route === "case" && param === "morpara";
  const algoraNav = route === "case" && param === "algora";
  const aboutBar = route === "about";
  const caseBg = maroon ? "#331110" : morparaNav ? "#2B1243" : algoraNav ? "#002E1F" : aboutBar ? "#FFFFFF" : (route === "home" ? homeBg : null);
  useEffect(() => {
    let lastY = window.scrollY;
    const onScroll = () => {
      const y = window.scrollY;
      setScrolled(y > 80);
      if (y > lastY + 4 && y > 120) setHidden(true);      // scrolling down → hide
      else if (y < lastY - 4 || y <= 80) setHidden(false); // scrolling up (or near top) → reveal
      lastY = y;
      // home: tint the bar with the active project's identity colour
      if (route === "home") {
        const closing = document.getElementById("contact");
        const inClosing = closing && closing.getBoundingClientRect().top < window.innerHeight * 0.6;
        let bg = null;
        if (inClosing) bg = null;
        else if (y >= 4220) bg = "#FFFFFF";        // Algora — white section
        else if (y >= 2540) bg = "#0a0a0a";        // Morpara — black section
        else if (y >= 1020) bg = "#FFFFFF";        // Stablex — white section
        setHomeBg(bg);
      } else {
        setHomeBg(null);
      }
    };
    onScroll();
    window.addEventListener("scroll", onScroll, { passive: true });
    return () => window.removeEventListener("scroll", onScroll);
  }, [route]);

  const lightBar = caseBg === "#FFFFFF";
  const barText = lightBar ? "rgba(15,15,18,0.78)" : "rgba(255,255,255,0.85)";

  const link = (label, target, isAnchor = false) => {
    const onClick = (e) => {
      e.preventDefault();
      if (isAnchor && route === "home") {
        document.querySelector(target)?.scrollIntoView({ behavior: "smooth", block: "start" });
      } else if (isAnchor) {
        navigate("home");
        setTimeout(() => document.querySelector(target)?.scrollIntoView({ behavior: "smooth" }), 60);
      } else {
        navigate(target);
        window.scrollTo({ top: 0, behavior: "instant" });
      }
    };
    return (
      <a href="#" onClick={onClick} className="text-sm tracking-tight link-underline" style={{ color: barText }}>
        {label}
      </a>
    );
  };

  return (
    <header
      className={`fixed top-0 left-0 right-0 z-50 ${scrolled && !caseBg ? "nav-scrolled" : ""}`}
      style={{
        transform: hidden ? "translateY(-100%)" : "translateY(0)",
        opacity: hidden ? 0 : 1,
        transition: "transform .55s cubic-bezier(0.16,1,0.3,1), opacity .55s cubic-bezier(0.16,1,0.3,1), background .3s ease",
        ...(caseBg ? { background: caseBg, borderBottom: `1px solid ${lightBar ? "rgba(0,0,0,.08)" : "rgba(255,255,255,.08)"}` } : {}),
      }}
    >
      <div className="max-w-[1240px] mx-auto px-6 md:px-10 h-16 flex items-center justify-between">
        <a
          href="#"
          onClick={(e) => { e.preventDefault(); navigate("home"); window.scrollTo({ top: 0 }); }}
          className="font-display text-xl font-semibold tracking-tight"
          style={{ color: barText }}
        >
          Tuna<span className="text-accent">.</span>
        </a>
        <nav className="flex items-center gap-7">
          {link("About", "about")}
          <a href="mailto:tunaaldemir@gmail.com" className="text-sm tracking-tight link-underline" style={{ color: barText }}>
            Contact
          </a>
        </nav>
      </div>
    </header>
  );
}

/* ---------- Footer ---------- */
function Footer() {
  return (
    <footer className="border-t border-line">
      <div className="max-w-[1240px] mx-auto px-6 md:px-10 h-16 flex items-center justify-between text-xs text-muted">
        <span className="font-display text-white">Tuna<span className="text-accent">.</span></span>
        <span>©All rights reserved · Built from scratch, with intent. This is not a template</span>
      </div>
    </footer>
  );
}

/* ---------- Blob ----------
   Layered: outer glow halo (blurred, pulsing) + morphing inner shape with
   conic-gradient fill + slow inner spin. Pure CSS, no SVG paths needed. */
function Blob({ size = 400 }) {
  return (
    <div className="relative" style={{ width: size, height: size }} aria-hidden="true">
      {/* outer glow */}
      <div
        className="absolute inset-[-25%] rounded-full"
        style={{
          background:
            "radial-gradient(closest-side, rgba(21,217,151,.85), rgba(21,217,151,.25) 55%, transparent 75%)",
          animation: "blobPulse 5.5s ease-in-out infinite",
        }}
      />
      {/* float wrapper */}
      <div className="absolute inset-0" style={{ animation: "blobFloat 7s ease-in-out infinite" }}>
        {/* morphing shape */}
        <div
          className="absolute inset-0 overflow-hidden"
          style={{
            animation: "blobMorph 12s ease-in-out infinite",
            background:
              "conic-gradient(from 180deg at 50% 50%, #3FE3AC, #15D997, #12B87F, #7CF0C8, #3FE3AC)",
            boxShadow:
              "inset 0 0 80px rgba(255,255,255,.18), 0 30px 120px -20px rgba(21,217,151,.55)",
          }}
        >
          {/* inner counter-spin highlight */}
          <div
            className="absolute inset-0"
            style={{
              background:
                "radial-gradient(circle at 30% 30%, rgba(255,255,255,.55), rgba(255,255,255,0) 45%)",
              animation: "blobInnerSpin 18s linear infinite",
            }}
          />
          {/* dark vignette */}
          <div
            className="absolute inset-0"
            style={{
              background:
                "radial-gradient(circle at 70% 75%, rgba(10,10,30,.45), rgba(10,10,30,0) 55%)",
            }}
          />
        </div>
      </div>
    </div>
  );
}

/* ---------- Tag pill ---------- */
function Tag({ children }) {
  return (
    <span className="inline-flex items-center gap-2 rounded-btn border border-line bg-surface px-3 py-1 text-xs tracking-tight text-white/85">
      <span className="size-1.5 rounded-full bg-accent" />
      {children}
    </span>
  );
}

/* ---------- Phone mockup (with parallax inner screens) ----------
   `progress` is 0..1 of how far into the sticky section we are.
   The inner reel translates upward as progress increases. */
function PhoneMockup({ progress = 0, accentHue = 162, label = "01" }) {
  // The reel is taller than the screen — translate it up over time.
  const screens = useMemo(() => buildPhoneScreens(label, accentHue), [label, accentHue]);
  const reelHeight = screens.length * 100; // % of screen height each
  const ty = -progress * (reelHeight - 100); // %

  return (
    <div className="relative mx-auto" style={{ width: 300 }}>
      {/* soft floor shadow */}
      <div
        className="absolute left-1/2 -translate-x-1/2 -bottom-10 w-[260px] h-12 rounded-full"
        style={{ background: "radial-gradient(closest-side, rgba(21,217,151,.35), transparent 75%)", filter: "blur(20px)" }}
      />
      <div
        className="relative rounded-[44px] border border-line bg-[#050505] p-3 shadow-[0_40px_120px_-30px_rgba(0,0,0,.9)]"
        style={{ height: 620 }}
      >
        {/* notch */}
        <div className="absolute top-3 left-1/2 -translate-x-1/2 z-10 h-7 w-28 rounded-b-2xl bg-black" />
        {/* screen */}
        <div className="relative overflow-hidden rounded-[34px] h-full bg-[#0d0d0f]">
          <div
            className="absolute inset-x-0 top-0 will-change-transform"
            style={{
              height: `${reelHeight}%`,
              transform: `translate3d(0, ${ty}%, 0)`,
              transition: "transform .05s linear",
            }}
          >
            {screens.map((s, i) => (
              <div key={i} className="h-[100%]" style={{ height: `${100 / screens.length * screens.length}%` }}>
                {s}
              </div>
            ))}
          </div>
        </div>
      </div>
    </div>
  );
}

/* Reusable inner screen pieces (placeholder app states) */
function buildPhoneScreens(label, hue) {
  const accent = `oklch(0.62 0.18 ${hue})`;
  const wrap = (children, bg = "#0d0d0f") => (
    <div className="h-full w-full p-5 flex flex-col gap-4" style={{ background: bg }}>
      {children}
    </div>
  );

  // Screen 1: dashboard
  const s1 = wrap(
    <>
      <div className="flex items-center justify-between text-[10px] text-white/50 pt-2">
        <span>9:41</span>
        <span>{label}</span>
      </div>
      <div>
        <div className="text-[12px] text-white/50">Good morning</div>
        <div className="font-display text-[22px] leading-tight mt-1">Here's where you stand today</div>
      </div>
      <div className="rounded-2xl p-4" style={{ background: "#15151a" }}>
        <div className="text-[10px] text-white/50 uppercase tracking-wider">Balance</div>
        <div className="font-display text-3xl mt-1">$ 24,860<span className="text-white/40 text-xl">.40</span></div>
        <div className="mt-3 h-16 relative">
          <svg viewBox="0 0 200 60" className="w-full h-full">
            <path d="M0,45 C20,30 40,50 60,38 C80,26 100,42 120,28 C140,14 160,32 200,18" stroke={accent} strokeWidth="2" fill="none" />
            <path d="M0,45 C20,30 40,50 60,38 C80,26 100,42 120,28 C140,14 160,32 200,18 L200,60 L0,60 Z" fill={accent} opacity="0.15" />
          </svg>
        </div>
      </div>
      <div className="grid grid-cols-3 gap-2">
        {["Send","Request","Top-up"].map(t => (
          <div key={t} className="rounded-xl py-3 text-[12px] text-center" style={{ background:"#15151a" }}>{t}</div>
        ))}
      </div>
      <div className="text-[10px] text-white/50 uppercase tracking-wider mt-2">Recent</div>
      {[1,2,3].map(i => (
        <div key={i} className="flex items-center gap-3">
          <div className="size-8 rounded-full" style={{ background:"#1c1c22" }} />
          <div className="flex-1">
            <div className="text-[12px]">Transfer · {i === 1 ? "Atlas" : i === 2 ? "Porter" : "Harbor"}</div>
            <div className="text-[9px] text-white/40">Today · 09:1{i}</div>
          </div>
          <div className="text-[12px]" style={{ color: i===2 ? accent : "#fff" }}>{i===2?"+":"−"} $ {120+i*47}.00</div>
        </div>
      ))}
    </>
  );

  // Screen 2: detail
  const s2 = wrap(
    <>
      <div className="flex items-center justify-between text-[10px] text-white/50 pt-2">
        <span>9:42</span>
        <span>{label}</span>
      </div>
      <div className="text-[12px] text-white/50">Project</div>
      <div className="font-display text-[26px] leading-[1.05]">Northcap quarterly review</div>
      <div className="flex gap-2">
        <span className="text-[10px] rounded-full border border-white/15 px-2 py-1">In review</span>
        <span className="text-[10px] rounded-full px-2 py-1" style={{ background: accent, color:"#0a0a0a" }}>Due Fri</span>
      </div>
      <div className="rounded-2xl p-4 flex flex-col gap-2" style={{ background:"#15151a" }}>
        {["Discovery interviews", "Stakeholder map", "Decision memo v3", "Outcome readout"].map((t, i) => (
          <div key={t} className="flex items-center gap-3 text-[12px]">
            <span className={`size-4 rounded-full border ${i<2 ? "" : "border-white/20"}`}
                  style={ i<2 ? { background: accent, borderColor: accent } : {} } />
            <span className={i<2 ? "line-through text-white/40" : ""}>{t}</span>
          </div>
        ))}
      </div>
      <div className="text-[10px] text-white/50 uppercase tracking-wider mt-2">Notes</div>
      <div className="rounded-2xl p-4 text-[12px] leading-relaxed text-white/70" style={{ background:"#15151a" }}>
        Pulled the three flows into a single review track. Sent the decision memo for sign-off on Thursday and unblocked the design system migration in the same pass.
      </div>
    </>
  );

  // Screen 3: list / chart
  const s3 = wrap(
    <>
      <div className="flex items-center justify-between text-[10px] text-white/50 pt-2">
        <span>9:43</span>
        <span>{label}</span>
      </div>
      <div className="font-display text-[22px]">This week</div>
      <div className="rounded-2xl p-4" style={{ background:"#15151a" }}>
        <div className="flex items-end gap-2 h-24">
          {[40,62,48,80,55,72,90].map((h, i) => (
            <div key={i} className="flex-1 rounded-t-md"
                 style={{ height: `${h}%`, background: i===6 ? accent : "#2a2a35" }} />
          ))}
        </div>
        <div className="flex justify-between text-[9px] text-white/40 mt-2">
          {["M","T","W","T","F","S","S"].map((d,i) => <span key={i}>{d}</span>)}
        </div>
      </div>
      {[
        ["Active sessions","1,284","+12%"],
        ["Avg. response","42s","−8%"],
        ["Pending review","9","steady"],
      ].map(([k,v,d]) => (
        <div key={k} className="flex items-center justify-between rounded-2xl px-4 py-3" style={{ background:"#15151a" }}>
          <div>
            <div className="text-[10px] text-white/50 uppercase tracking-wider">{k}</div>
            <div className="font-display text-xl mt-0.5">{v}</div>
          </div>
          <div className="text-[10px]" style={{ color: d.startsWith("+") ? accent : d.startsWith("−") ? "#ff9090" : "#888" }}>{d}</div>
        </div>
      ))}
    </>
  );

  return [s1, s2, s3];
}

/* ---------- Desktop / Browser mockup (with parallax) ---------- */
function DesktopMockup({ progress = 0, accentHue = 162, label = "04" }) {
  const accent = `oklch(0.62 0.18 ${accentHue})`;
  const reelHeight = 220; // %
  const ty = -progress * (reelHeight - 100);

  return (
    <div className="relative w-full max-w-[640px] mx-auto">
      <div className="absolute -bottom-10 left-1/2 -translate-x-1/2 w-[80%] h-12 rounded-full"
           style={{ background: "radial-gradient(closest-side, rgba(21,217,151,.3), transparent 75%)", filter: "blur(20px)" }} />
      <div className="relative rounded-2xl border border-line bg-[#050505] shadow-[0_40px_120px_-30px_rgba(0,0,0,.9)] overflow-hidden">
        {/* window chrome */}
        <div className="flex items-center gap-2 px-4 h-9 border-b border-line bg-[#0c0c0e]">
          <span className="size-2.5 rounded-full bg-[#333]" />
          <span className="size-2.5 rounded-full bg-[#333]" />
          <span className="size-2.5 rounded-full bg-[#333]" />
          <div className="ml-4 text-[10px] text-white/40">atlas.app / {label === "04" ? "dashboards" : "components"}</div>
        </div>
        {/* viewport */}
        <div className="relative overflow-hidden bg-[#0d0d0f]" style={{ aspectRatio: "16 / 10" }}>
          <div className="absolute inset-x-0 top-0 will-change-transform"
               style={{ height: `${reelHeight}%`, transform: `translate3d(0, ${ty}%, 0)`, transition: "transform .05s linear" }}>
            {label === "04" ? <DesktopAtlas accent={accent} /> : <DesktopPorter accent={accent} />}
          </div>
        </div>
      </div>
    </div>
  );
}

function DesktopAtlas({ accent }) {
  return (
    <div className="h-full w-full grid grid-cols-[180px_1fr] text-[12px]">
      <aside className="border-r border-line p-4 flex flex-col gap-3 bg-[#0a0a0c]">
        <div className="font-display text-base">Atlas</div>
        {["Overview","Dashboards","Explore","Alerts","Sources","Team"].map((t,i)=>(
          <div key={t} className={`flex items-center gap-2 ${i===1?"text-white":"text-white/55"}`}>
            <span className="size-1.5 rounded-full" style={{ background: i===1 ? accent : "#444" }} />
            {t}
          </div>
        ))}
        <div className="mt-auto rounded-xl p-3 border border-line">
          <div className="text-white/55">Storage</div>
          <div className="h-1.5 rounded-full bg-[#1c1c22] mt-2 overflow-hidden">
            <div className="h-full" style={{ width:"62%", background: accent }} />
          </div>
        </div>
      </aside>
      <main className="p-5 flex flex-col gap-4">
        <div className="flex items-center justify-between">
          <div>
            <div className="text-white/50">Q2 — North America</div>
            <div className="font-display text-2xl">Retention by cohort</div>
          </div>
          <div className="flex gap-2">
            {["Day","Week","Month"].map((t,i)=>(
              <span key={t} className={`px-3 py-1 rounded-btn border ${i===1?"border-white text-white":"border-line text-white/55"}`}>{t}</span>
            ))}
          </div>
        </div>
        <div className="grid grid-cols-3 gap-3">
          {[
            ["Active users","48,210","+12.4%"],
            ["Avg. session","6m 12s","+0.8%"],
            ["Churn","2.1%","−0.4%"],
          ].map(([k,v,d])=>(
            <div key={k} className="rounded-xl border border-line p-3">
              <div className="text-white/50">{k}</div>
              <div className="font-display text-xl mt-1">{v}</div>
              <div className="text-[10px] mt-1" style={{ color: d.startsWith("+") ? accent : "#ff9090" }}>{d}</div>
            </div>
          ))}
        </div>
        <div className="rounded-xl border border-line p-4">
          <svg viewBox="0 0 400 120" className="w-full h-32">
            {[0,1,2,3,4].map(i => (
              <line key={i} x1="0" x2="400" y1={i*30} y2={i*30} stroke="#1c1c22" />
            ))}
            <path d="M0,90 C40,70 80,80 120,55 C160,35 200,60 240,40 C280,22 320,45 400,18" stroke={accent} strokeWidth="2" fill="none" />
            <path d="M0,90 C40,70 80,80 120,55 C160,35 200,60 240,40 C280,22 320,45 400,18 L400,120 L0,120 Z" fill={accent} opacity="0.12" />
            <path d="M0,100 C40,95 80,90 120,82 C160,78 200,80 240,72 C280,66 320,68 400,55" stroke="#555" strokeWidth="1.5" fill="none" strokeDasharray="3 3" />
          </svg>
        </div>
        <div className="grid grid-cols-2 gap-3">
          {[1,2].map(i => (
            <div key={i} className="rounded-xl border border-line p-4">
              <div className="text-white/50">Segment {i}</div>
              <div className="flex items-end gap-1 h-16 mt-2">
                {[35,52,40,68,55,72,80,62,75].map((h,j)=>(
                  <div key={j} className="flex-1 rounded-t" style={{ height:`${h}%`, background: j>5 ? accent : "#2a2a35" }} />
                ))}
              </div>
            </div>
          ))}
        </div>
        {/* second viewport — fades into view via parallax */}
        <div className="rounded-xl border border-line p-4">
          <div className="font-display text-xl">Cohort heatmap</div>
          <div className="grid grid-cols-12 gap-1 mt-3">
            {Array.from({length: 60}).map((_,i)=>{
              const v = Math.abs(Math.sin(i*0.6))*0.9 + 0.1;
              return <div key={i} className="aspect-square rounded-sm" style={{ background: accent, opacity: v*0.9 }} />;
            })}
          </div>
        </div>
      </main>
    </div>
  );
}

function DesktopPorter({ accent }) {
  return (
    <div className="h-full w-full grid grid-cols-[200px_1fr_220px] text-[12px]">
      <aside className="border-r border-line p-4 flex flex-col gap-2 bg-[#0a0a0c]">
        <div className="font-display text-base">Porter</div>
        {["Pages","Components","Tokens","Templates","Releases"].map((t,i)=>(
          <div key={t} className={`flex items-center gap-2 ${i===1?"text-white":"text-white/55"}`}>
            <span className="size-1.5 rounded-full" style={{ background: i===1 ? accent : "#444" }} />
            {t}
          </div>
        ))}
      </aside>
      <main className="p-5 flex flex-col gap-3">
        <div className="flex items-center justify-between">
          <div className="font-display text-2xl">Components</div>
          <span className="px-3 py-1 rounded-btn text-[10px]" style={{ background: accent, color:"#0a0a0a" }}>Publish</span>
        </div>
        <div className="grid grid-cols-3 gap-3">
          {["Button","Field","Card","Badge","Modal","Tabs","Table","Avatar","Toast"].map((t,i)=>(
            <div key={t} className="rounded-xl border border-line p-3 flex flex-col gap-2">
              <div className="h-12 rounded-md stripe-placeholder flex items-center justify-center">
                <span className="text-[10px] text-white/50">{t}</span>
              </div>
              <div className="flex items-center justify-between">
                <span>{t}</span>
                <span className="text-[9px] text-white/40">v2.{i}</span>
              </div>
            </div>
          ))}
        </div>
        {/* second section — tokens */}
        <div className="font-display text-xl mt-2">Tokens</div>
        <div className="grid grid-cols-6 gap-2">
          {["#0a0a0a","#111111","#222222","#15D997","#7CF0C8","#FFFFFF"].map(c => (
            <div key={c} className="rounded-md aspect-square border border-line" style={{ background:c }} />
          ))}
        </div>
      </main>
      <aside className="border-l border-line p-4 flex flex-col gap-3 bg-[#0a0a0c]">
        <div className="text-white/50">Inspector</div>
        {[
          ["Radius","8px"],
          ["Padding","12 / 16"],
          ["Border","1px · line"],
          ["Hover","scale 1.02"],
          ["Theme","Dark"],
        ].map(([k,v])=>(
          <div key={k} className="flex items-center justify-between">
            <span className="text-white/55">{k}</span>
            <span>{v}</span>
          </div>
        ))}
      </aside>
    </div>
  );
}

/* ---------- Section heading ---------- */
function SectionEyebrow({ children, center = false, noDot = false }) {
  return (
    <div className={`flex items-center gap-3 text-xs uppercase tracking-[0.18em] text-muted ${center ? "justify-center" : ""}`}>
      {!noDot && <span className="size-1.5 rounded-full bg-accent" />}
      {children}
    </div>
  );
}

/* expose */
Object.assign(window, {
  Reveal, Navbar, Footer, Blob, Tag,
  PhoneMockup, DesktopMockup, buildPhoneScreens,
  SectionEyebrow,
});
