/* Shared atomic components */
const { useState, useEffect, useRef, useMemo, useCallback } = React;

/* ---------- Logo ---------- */
function GimsLogo({ size = 44, glow = false }) {
  return (
    <img
      src="assets/gims-logo.png"
      alt="GIMS"
      width={size}
      height={size}
      style={{
        width: size, height: size, display: "block",
        filter: glow
          ? "drop-shadow(0 0 24px rgba(212,164,68,0.55)) drop-shadow(0 0 4px rgba(255,180,60,0.4))"
          : "drop-shadow(0 4px 12px rgba(0,0,0,0.5))",
      }}
    />
  );
}

/* ---------- Buttons ---------- */
function PillButton({ children, variant = "dark", onClick, glow, style, type, disabled }) {
  const base = {
    display: "inline-flex", alignItems: "center", gap: 10, padding: "12px 22px",
    borderRadius: 999, fontSize: 12.5, fontWeight: 600, letterSpacing: "0.14em",
    textTransform: "uppercase", fontFamily: "'JetBrains Mono', monospace",
    border: "1px solid transparent", cursor: disabled ? "not-allowed" : "pointer",
    opacity: disabled ? 0.5 : 1,
  };
  const variants = {
    dark: {
      background: "rgba(255,255,255,0.04)", color: "var(--ink)",
      border: "1px solid var(--line-strong)",
    },
    blue: {
      background: "linear-gradient(180deg, #4c7bff 0%, #2a52e6 100%)",
      color: "white", boxShadow: glow ? "0 0 32px rgba(58,109,255,0.55), 0 1px 0 rgba(255,255,255,0.3) inset" : "0 1px 0 rgba(255,255,255,0.3) inset",
    },
    white: {
      background: "white", color: "#0a0f1e",
      boxShadow: "0 12px 40px rgba(255,255,255,0.08)",
    },
    ghost: {
      background: "transparent", color: "var(--ink-2)",
      border: "1px solid var(--line)",
    },
    gold: {
      background: "linear-gradient(180deg, #e0b556 0%, #b58532 100%)",
      color: "#1a1208", boxShadow: "0 0 24px rgba(212,164,68,0.3), 0 1px 0 rgba(255,255,255,0.3) inset",
    },
  };
  return (
    <button onClick={onClick} type={type} disabled={disabled} className="btn-press" style={{ ...base, ...variants[variant], ...style }}>
      {children}
    </button>
  );
}

/* ---------- Status Badge ---------- */
function GoldBadge({ children, style, accent = "gold" }) {
  const colors = {
    gold: { ring: "rgba(212,164,68,0.35)", grad: "linear-gradient(180deg, rgba(212,164,68,0.18), rgba(212,164,68,0.06))", text: "var(--gold)", dot: "var(--gold)" },
    blue: { ring: "rgba(58,109,255,0.4)", grad: "linear-gradient(180deg, rgba(58,109,255,0.18), rgba(58,109,255,0.06))", text: "var(--blue-bright)", dot: "var(--blue-bright)" },
  };
  const c = colors[accent];
  return (
    <div style={{
      display: "inline-flex", alignItems: "center", gap: 10,
      padding: "9px 20px", borderRadius: 999,
      background: c.grad, border: `1px solid ${c.ring}`,
      color: c.text, fontFamily: "'JetBrains Mono', monospace",
      fontSize: 11, letterSpacing: "0.22em", fontWeight: 500,
      ...style,
    }}>
      <span style={{
        width: 6, height: 6, borderRadius: 999, background: c.dot,
        boxShadow: `0 0 8px ${c.dot}`, animation: "pulse-dot 2s ease-in-out infinite",
      }}></span>
      {children}
    </div>
  );
}

/* ---------- Nav ---------- */
function Nav({ openNavModal, scrollToId }) {
  const [scrolled, setScrolled] = useState(false);
  useEffect(() => {
    const onScroll = () => setScrolled(window.scrollY > 8);
    window.addEventListener("scroll", onScroll);
    return () => window.removeEventListener("scroll", onScroll);
  }, []);

  const links = [
    { id: "ecosystem", label: "The Ecosystem", accent: "blue" },
    { id: "protocol", label: "Four-Protocol", accent: "gold" },
    { id: "foundation", label: "The Foundation", accent: "purple" },
  ];

  return (
    <header className="app-topbar" style={{
      position: "fixed", top: 0, left: 0, right: 0, zIndex: 50,
      transition: "background 240ms ease, border-color 240ms ease, backdrop-filter 240ms ease",
      background: scrolled ? "rgba(5,7,15,0.7)" : "transparent",
      backdropFilter: scrolled ? "blur(14px)" : "none",
      WebkitBackdropFilter: scrolled ? "blur(14px)" : "none",
      borderBottom: scrolled ? "1px solid var(--line)" : "1px solid transparent",
    }}>
      <div className="container" style={{ display: "flex", alignItems: "center", justifyContent: "space-between", padding: "18px 20px", gap: 24 }}>
        {/* Logo */}
        <a href="#top" onClick={(e) => { e.preventDefault(); window.scrollTo({ top: 0, behavior: "smooth" }); }} style={{ display: "flex", alignItems: "center", gap: 14 }}>
          <GimsLogo size={42} />
          <div className="brand-meta" style={{ display: "flex", flexDirection: "column", lineHeight: 1 }}>
            <span style={{ fontFamily: "'Inter'", fontStyle: "italic", fontWeight: 800, fontSize: 18, letterSpacing: "-0.01em" }}>GIMS</span>
            <span style={{ fontFamily: "'JetBrains Mono', monospace", fontSize: 9.5, letterSpacing: "0.28em", color: "var(--blue-bright)", marginTop: 4 }}>GLOBAL NODE</span>
          </div>
        </a>

        {/* Center nav (desktop only) */}
        <nav style={{ gap: 44, alignItems: "center" }} className="hide-mobile">
          {links.map((l) => (
            <button
              key={l.id}
              onClick={() => openNavModal(l.id)}
              className={"nav-link"}
              style={{
                fontFamily: "'JetBrains Mono', monospace",
                fontSize: 11.5, letterSpacing: "0.2em", fontWeight: 500,
                textTransform: "uppercase",
                color: "var(--ink-3)",
                background: "transparent", border: "none", padding: 0, cursor: "pointer",
              }}
            >
              {l.label}
            </button>
          ))}
        </nav>

        {/* Desktop CTAs */}
        <div className="desktop-cta-row" style={{ display: "flex", gap: 12, alignItems: "center" }}>
          <PillButton variant="dark" onClick={() => { window.location.href = "https://app.gimsprotocol.com/sign-in"; }}>
            <TerminalIcon /> Terminal Access
          </PillButton>
          <PillButton variant="blue" glow onClick={() => scrollToId("registry")}>
            Request Node →
          </PillButton>
        </div>

        {/* Mobile icon-only Sign In */}
        <button
          className="mobile-topbar-cta"
          aria-label="Sign in"
          onClick={() => { window.location.href = "https://app.gimsprotocol.com/sign-in"; }}
        >
          <SignInIcon />
        </button>
      </div>
    </header>
  );
}

function SignInIcon() {
  return (
    <svg width="16" height="16" viewBox="0 0 24 24" fill="none">
      <path d="M10 17l5-5-5-5" stroke="currentColor" strokeWidth="1.7" strokeLinecap="round" strokeLinejoin="round" />
      <path d="M15 12H4" stroke="currentColor" strokeWidth="1.7" strokeLinecap="round" />
      <path d="M20 5v14" stroke="currentColor" strokeWidth="1.7" strokeLinecap="round" />
    </svg>
  );
}

function TerminalIcon() {
  return (
    <svg width="13" height="13" viewBox="0 0 16 16" fill="none">
      <path d="M2 4l3 3-3 3" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round" />
      <path d="M8 11h6" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round" />
    </svg>
  );
}

/* ---------- Hero ---------- */
function Hero({ scrollToId }) {
  return (
    <section id="top" style={{
      position: "relative", minHeight: "100vh", display: "flex", alignItems: "center", justifyContent: "center",
      padding: "140px 0 120px",
    }}>
      <Constellation />
      <div className="container" style={{ position: "relative", display: "flex", flexDirection: "column", alignItems: "center", textAlign: "center", gap: 36 }}>
        <GoldBadge>Global Information Management System</GoldBadge>

        <h1 className="display hero-title" style={{
          margin: 0,
          /* Cap at a size where the widest word (ADMINISTRATIVE, 14 chars)
             always fits inside maxWidth — no mid-word breaking anywhere. */
          fontSize: "clamp(32px, 7vw, 124px)",
          maxWidth: "min(1400px, 96vw)",
          width: "100%",
          paddingLeft: "clamp(8px, 2vw, 32px)",
          paddingRight: "clamp(8px, 2vw, 32px)",
          overflowWrap: "normal",
          wordBreak: "keep-all",
          hyphens: "none",
        }}>
          <span style={{ display: "inline-block", whiteSpace: "nowrap" }}>ADMINISTRATIVE</span>
          <br />
          <span style={{
            display: "inline-block",
            whiteSpace: "nowrap",
            backgroundImage: "var(--grad-text)",
            WebkitBackgroundClip: "text", backgroundClip: "text",
            color: "transparent",
          }}>EXECUTION.</span>
        </h1>

        <p style={{
          margin: 0, maxWidth: 720, fontSize: 19, lineHeight: 1.5, color: "var(--ink-2)",
        }}>
          The system that stabilizes identity, defines jurisdiction, and{" "}
          <em className="serif-i" style={{ color: "var(--ink)", fontSize: 22 }}>
            reconciles obligations across institutions.
          </em>
        </p>

        <div className="hero-cta-row" style={{ display: "flex", gap: 14, alignItems: "center", marginTop: 6, flexWrap: "wrap", justifyContent: "center" }}>
          <PillButton variant="white" onClick={() => scrollToId("registry")} style={{ padding: "16px 32px", fontSize: 12.5 }}>
            Join the Registry →
          </PillButton>
          <PillButton variant="ghost" onClick={() => scrollToId("ecosystem")} style={{ padding: "16px 26px" }}>
            See the framework
          </PillButton>
        </div>
      </div>
    </section>
  );
}

/* ---------- Constellation backdrop ---------- */
function Constellation() {
  const ref = useRef(null);
  useEffect(() => {
    const canvas = ref.current;
    if (!canvas) return;
    const ctx = canvas.getContext("2d");
    let raf, w, h;
    const dpr = Math.min(window.devicePixelRatio || 1, 2);
    const nodes = [];
    function resize() {
      w = canvas.clientWidth; h = canvas.clientHeight;
      canvas.width = w * dpr; canvas.height = h * dpr;
      ctx.setTransform(dpr, 0, 0, dpr, 0, 0);
    }
    function init() {
      nodes.length = 0;
      const count = Math.floor((w * h) / 24000);
      for (let i = 0; i < count; i++) {
        nodes.push({
          x: Math.random() * w, y: Math.random() * h,
          vx: (Math.random() - 0.5) * 0.18, vy: (Math.random() - 0.5) * 0.18,
          r: Math.random() * 1.2 + 0.4,
        });
      }
    }
    function tick() {
      ctx.clearRect(0, 0, w, h);
      for (const n of nodes) {
        n.x += n.vx; n.y += n.vy;
        if (n.x < 0 || n.x > w) n.vx *= -1;
        if (n.y < 0 || n.y > h) n.vy *= -1;
        ctx.fillStyle = "rgba(150,180,255,0.32)";
        ctx.beginPath(); ctx.arc(n.x, n.y, n.r, 0, Math.PI * 2); ctx.fill();
      }
      for (let i = 0; i < nodes.length; i++) {
        for (let j = i + 1; j < nodes.length; j++) {
          const dx = nodes[i].x - nodes[j].x, dy = nodes[i].y - nodes[j].y;
          const d2 = dx * dx + dy * dy;
          if (d2 < 140 * 140) {
            const a = 1 - d2 / (140 * 140);
            ctx.strokeStyle = `rgba(110,140,220,${a * 0.10})`;
            ctx.lineWidth = 0.6;
            ctx.beginPath(); ctx.moveTo(nodes[i].x, nodes[i].y); ctx.lineTo(nodes[j].x, nodes[j].y); ctx.stroke();
          }
        }
      }
      raf = requestAnimationFrame(tick);
    }
    resize(); init(); tick();
    const onR = () => { resize(); init(); };
    window.addEventListener("resize", onR);
    return () => { cancelAnimationFrame(raf); window.removeEventListener("resize", onR); };
  }, []);
  return (
    <canvas ref={ref} style={{
      position: "absolute", inset: 0, width: "100%", height: "100%", pointerEvents: "none", opacity: 0.5,
    }} />
  );
}

/* ---------- Big Globe (for Unified Ecosystem) ---------- */
function BigGlobe() {
  return (
    <div style={{ position: "relative", width: "100%", maxWidth: 480, aspectRatio: "1 / 1", margin: "0 auto" }}>
      {/* ambient glow */}
      <div style={{
        position: "absolute", inset: "-12%", borderRadius: "50%",
        background: "radial-gradient(circle, rgba(212,164,68,0.18) 0%, rgba(212,164,68,0.05) 40%, transparent 70%)",
        pointerEvents: "none", filter: "blur(20px)",
      }} />
      {/* concentric rings */}
      <svg viewBox="0 0 400 400" style={{ position: "absolute", inset: 0, width: "100%", height: "100%", pointerEvents: "none" }}>
        {[180, 150, 120].map((r, i) => (
          <circle key={i} cx="200" cy="200" r={r}
            fill="none" stroke="rgba(212,164,68,0.10)" strokeWidth="1" strokeDasharray={i === 1 ? "3 6" : "0"} />
        ))}
      </svg>

      {/* logo */}
      <img
        src="assets/gims-logo.png"
        alt="GIMS"
        style={{
          position: "relative", width: "82%", height: "82%", margin: "9% auto", display: "block",
          filter: "drop-shadow(0 30px 80px rgba(0,0,0,0.7)) drop-shadow(0 0 60px rgba(212,164,68,0.25))",
        }}
      />

    </div>
  );
}

/* ---------- Mobile bottom tab bar ----------
   Visible only at ≤ 760px (CSS-controlled). Active tab tracks the section
   currently in view via IntersectionObserver. Tap → smooth-scroll to that
   section. The fifth slot is "Sign In" which navigates to the external app. */
function MobileTabBar({ scrollToId }) {
  const tabs = [
    { id: "top",       label: "Home",     icon: "home" },
    { id: "ecosystem", label: "Eco",      icon: "globe" },
    { id: "protocol",  label: "Protocol", icon: "matrix" },
    { id: "registry",  label: "Access",   icon: "key" },
    { id: "__signin",  label: "Sign In",  icon: "signin" },
  ];
  const [active, setActive] = useState("top");

  useEffect(() => {
    const ids = ["top", "ecosystem", "protocol", "foundation", "registry"];
    const els = ids.map((id) => document.getElementById(id)).filter(Boolean);
    if (!els.length) return;

    // Track the section whose top is closest to ~30% from the viewport top.
    const io = new IntersectionObserver(
      (entries) => {
        // Pick the entry most "in view" near the top portion.
        let best = null;
        for (const e of entries) {
          if (!e.isIntersecting) continue;
          if (!best || e.intersectionRatio > best.intersectionRatio) best = e;
        }
        if (best) {
          let id = best.target.id;
          // Map "foundation" (literacy section) onto the "protocol" tab — it
          // doesn't have its own tab, so don't desync the highlight.
          if (id === "foundation") id = "protocol";
          setActive(id);
        }
      },
      { rootMargin: "-30% 0px -55% 0px", threshold: [0, 0.25, 0.5, 0.75, 1] }
    );
    els.forEach((el) => io.observe(el));
    return () => io.disconnect();
  }, []);

  const onTap = (t) => {
    if (t.id === "__signin") {
      window.location.href = "https://app.gimsprotocol.com/sign-in";
      return;
    }
    setActive(t.id);
    scrollToId(t.id);
  };

  return (
    <nav className="mobile-tabbar" aria-label="Primary">
      {tabs.map((t) => (
        <button
          key={t.id}
          className={"tab" + (active === t.id ? " active" : "")}
          onClick={() => onTap(t)}
          aria-current={active === t.id ? "page" : undefined}
        >
          <span className="tab-glyph"><TabIcon name={t.icon} /></span>
          <span>{t.label}</span>
        </button>
      ))}
    </nav>
  );
}

function TabIcon({ name }) {
  switch (name) {
    case "home":
      return (
        <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.6" strokeLinecap="round" strokeLinejoin="round">
          <path d="M3 11l9-8 9 8" />
          <path d="M5 10v10h14V10" />
          <path d="M10 20v-6h4v6" />
        </svg>
      );
    case "globe":
      return (
        <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.6" strokeLinecap="round" strokeLinejoin="round">
          <circle cx="12" cy="12" r="9" />
          <path d="M3 12h18" />
          <path d="M12 3c3 3.5 3 14 0 18" />
          <path d="M12 3c-3 3.5-3 14 0 18" />
        </svg>
      );
    case "matrix":
      return (
        <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.6" strokeLinecap="round" strokeLinejoin="round">
          <rect x="4" y="4" width="7" height="7" />
          <rect x="13" y="4" width="7" height="7" />
          <rect x="4" y="13" width="7" height="7" />
          <rect x="13" y="13" width="7" height="7" />
        </svg>
      );
    case "key":
      return (
        <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.6" strokeLinecap="round" strokeLinejoin="round">
          <circle cx="8" cy="15" r="4" />
          <path d="M11 12l9-9" />
          <path d="M16 7l3 3" />
          <path d="M18 5l3 3" />
        </svg>
      );
    case "signin":
      return (
        <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.6" strokeLinecap="round" strokeLinejoin="round">
          <path d="M10 17l5-5-5-5" />
          <path d="M15 12H4" />
          <path d="M20 5v14" />
        </svg>
      );
    default:
      return null;
  }
}

/* Expose to global */
Object.assign(window, {
  GimsLogo, PillButton, GoldBadge, Nav, Hero, TerminalIcon, Constellation, BigGlobe, MobileTabBar,
});
