/* eslint-disable */
// Shared components for the Seratonin prototype.

const Icon = ({ name, size = 16, stroke = 1.6 }) => {
  const s = { width: size, height: size, strokeWidth: stroke };
  const common = {
    fill: "none",
    stroke: "currentColor",
    strokeLinecap: "round",
    strokeLinejoin: "round",
    viewBox: "0 0 24 24",
    ...s,
  };
  switch (name) {
    case "check":
      return <svg {...common}><path d="M4 12.5 9 17.5 20 6" /></svg>;
    case "plus":
      return <svg {...common}><path d="M12 5v14M5 12h14" /></svg>;
    case "x":
      return <svg {...common}><path d="M6 6l12 12M18 6l-12 12" /></svg>;
    case "copy":
      return <svg {...common}><rect x="9" y="9" width="11" height="11" rx="2" /><path d="M5 15V6a2 2 0 0 1 2-2h9" /></svg>;
    case "arrow-right":
      return <svg {...common}><path d="M5 12h14M13 5l7 7-7 7" /></svg>;
    case "discord":
      return <svg viewBox="0 0 24 24" width={size} height={size} fill="currentColor"><path d="M19.27 5.33a17.66 17.66 0 0 0-4.4-1.36l-.21.41a16.4 16.4 0 0 0-4.92 0l-.21-.41a17.6 17.6 0 0 0-4.4 1.36C2.32 9.46 1.6 13.49 2 17.46a17.78 17.78 0 0 0 5.4 2.73l.43-.6a11 11 0 0 1-1.74-.84l.14-.11a12.5 12.5 0 0 0 11.54 0l.14.11a11 11 0 0 1-1.74.84l.43.6a17.78 17.78 0 0 0 5.4-2.73c.42-4.65-.62-8.65-2.73-12.13ZM8.52 15.33c-1.05 0-1.92-.97-1.92-2.16s.85-2.16 1.92-2.16 1.93.97 1.92 2.16c0 1.19-.85 2.16-1.92 2.16Zm6.96 0c-1.05 0-1.92-.97-1.92-2.16s.85-2.16 1.92-2.16 1.93.97 1.92 2.16c0 1.19-.85 2.16-1.92 2.16Z" /></svg>;
    case "google":
      return <svg viewBox="0 0 24 24" width={size} height={size}><path fill="#4285F4" d="M21.6 12.23c0-.79-.07-1.54-.2-2.27H12v4.3h5.39a4.62 4.62 0 0 1-2 3.03v2.5h3.23c1.89-1.74 2.98-4.3 2.98-7.56Z"/><path fill="#34A853" d="M12 22c2.7 0 4.96-.9 6.62-2.43l-3.23-2.5c-.9.6-2.04.95-3.39.95-2.6 0-4.8-1.76-5.59-4.12H3.07v2.59A10 10 0 0 0 12 22Z"/><path fill="#FBBC05" d="M6.41 13.9a6 6 0 0 1 0-3.81V7.5H3.07a10 10 0 0 0 0 9l3.34-2.6Z"/><path fill="#EA4335" d="M12 5.97a5.4 5.4 0 0 1 3.84 1.5l2.86-2.86A9.6 9.6 0 0 0 12 2 10 10 0 0 0 3.07 7.5l3.34 2.6C7.2 7.72 9.4 5.96 12 5.96Z"/></svg>;
    case "key":
      return <svg {...common}><circle cx="8" cy="15" r="4" /><path d="M11 14l9-9M16 9l3 3M19 6l3 3" /></svg>;
    case "shield":
      return <svg {...common}><path d="M12 3l8 3v6c0 4.5-3.4 8.5-8 9-4.6-.5-8-4.5-8-9V6l8-3Z" /></svg>;
    case "zap":
      return <svg {...common}><path d="M13 2 4 14h7l-1 8 9-12h-7l1-8Z" /></svg>;
    case "infinity":
      return <svg {...common}><path d="M18.18 8.04a4 4 0 0 0-5.66 0L12 8.5l-.52-.46a4 4 0 1 0 0 7.92l.52-.46.52.46a4 4 0 1 0 5.66-5.66" /></svg>;
    case "code":
      return <svg {...common}><path d="m8 6-6 6 6 6M16 6l6 6-6 6M14 4l-4 16" /></svg>;
    case "bolt-circle":
      return <svg {...common}><circle cx="12" cy="12" r="9" /><path d="m13 7-4 7h3l-1 4 4-7h-3l1-4Z" /></svg>;
    case "discord-fill":
      return <svg viewBox="0 0 24 24" width={size} height={size} fill="currentColor"><path d="M19.27 5.33a17.66 17.66 0 0 0-4.4-1.36l-.21.41a16.4 16.4 0 0 0-4.92 0l-.21-.41a17.6 17.6 0 0 0-4.4 1.36C2.32 9.46 1.6 13.49 2 17.46a17.78 17.78 0 0 0 5.4 2.73l.43-.6a11 11 0 0 1-1.74-.84l.14-.11a12.5 12.5 0 0 0 11.54 0l.14.11a11 11 0 0 1-1.74.84l.43.6a17.78 17.78 0 0 0 5.4-2.73c.42-4.65-.62-8.65-2.73-12.13ZM8.52 15.33c-1.05 0-1.92-.97-1.92-2.16s.85-2.16 1.92-2.16 1.93.97 1.92 2.16c0 1.19-.85 2.16-1.92 2.16Zm6.96 0c-1.05 0-1.92-.97-1.92-2.16s.85-2.16 1.92-2.16 1.93.97 1.92 2.16c0 1.19-.85 2.16-1.92 2.16Z"/></svg>;
    case "home":
      return <svg {...common}><path d="M3 11 12 3l9 8v9a1 1 0 0 1-1 1h-5v-7h-6v7H4a1 1 0 0 1-1-1Z" /></svg>;
    case "card":
      return <svg {...common}><rect x="3" y="5" width="18" height="14" rx="2" /><path d="M3 10h18" /></svg>;
    case "download":
      return <svg {...common}><path d="M12 3v13M6 12l6 6 6-6M4 21h16" /></svg>;
    case "user":
      return <svg {...common}><circle cx="12" cy="8" r="4" /><path d="M4 21a8 8 0 0 1 16 0" /></svg>;
    case "settings":
      return <svg {...common}><circle cx="12" cy="12" r="3" /><path d="M19.4 15a1.65 1.65 0 0 0 .33 1.82l.06.06a2 2 0 0 1-2.83 2.83l-.06-.06a1.65 1.65 0 0 0-1.82-.33 1.65 1.65 0 0 0-1 1.51V21a2 2 0 0 1-4 0v-.09a1.65 1.65 0 0 0-1-1.51 1.65 1.65 0 0 0-1.82.33l-.06.06a2 2 0 0 1-2.83-2.83l.06-.06a1.65 1.65 0 0 0 .33-1.82 1.65 1.65 0 0 0-1.51-1H3a2 2 0 0 1 0-4h.09a1.65 1.65 0 0 0 1.51-1 1.65 1.65 0 0 0-.33-1.82l-.06-.06a2 2 0 0 1 2.83-2.83l.06.06a1.65 1.65 0 0 0 1.82.33h0a1.65 1.65 0 0 0 1-1.51V3a2 2 0 0 1 4 0v.09a1.65 1.65 0 0 0 1 1.51 1.65 1.65 0 0 0 1.82-.33l.06-.06a2 2 0 0 1 2.83 2.83l-.06.06a1.65 1.65 0 0 0-.33 1.82v0a1.65 1.65 0 0 0 1.51 1H21a2 2 0 0 1 0 4h-.09a1.65 1.65 0 0 0-1.51 1Z" /></svg>;
    case "users":
      return <svg {...common}><path d="M16 21v-2a4 4 0 0 0-4-4H6a4 4 0 0 0-4 4v2" /><circle cx="9" cy="7" r="4" /><path d="M22 21v-2a4 4 0 0 0-3-3.87M16 3.13A4 4 0 0 1 16 11" /></svg>;
    case "activity":
      return <svg {...common}><path d="M3 12h4l3-9 4 18 3-9h4" /></svg>;
    case "chart":
      return <svg {...common}><path d="M3 3v18h18" /><rect x="7" y="13" width="3" height="6" /><rect x="13" y="9" width="3" height="10" /><rect x="19" y="5" width="3" height="14" /></svg>;
    case "alert":
      return <svg {...common}><path d="M12 9v4M12 17h.01M10.3 3.86 1.82 18a2 2 0 0 0 1.71 3h16.94a2 2 0 0 0 1.71-3L13.71 3.86a2 2 0 0 0-3.42 0Z" /></svg>;
    case "refresh":
      return <svg {...common}><path d="M21 2v6h-6M3 12a9 9 0 0 1 14.85-6.36L21 8M3 22v-6h6M21 12a9 9 0 0 1-14.85 6.36L3 16" /></svg>;
    case "search":
      return <svg {...common}><circle cx="11" cy="11" r="7" /><path d="M21 21l-4.3-4.3" /></svg>;
    case "filter":
      return <svg {...common}><path d="M3 5h18M6 12h12M10 19h4" /></svg>;
    case "more":
      return <svg {...common}><circle cx="5" cy="12" r="1" /><circle cx="12" cy="12" r="1" /><circle cx="19" cy="12" r="1" /></svg>;
    case "logout":
      return <svg {...common}><path d="M9 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h4M16 17l5-5-5-5M21 12H9" /></svg>;
    case "mail":
      return <svg {...common}><rect x="2" y="4" width="20" height="16" rx="2" /><path d="m22 6-10 7L2 6" /></svg>;
    default:
      return null;
  }
};

const NAV_SECTIONS = [
  { id: "pricing", label: "Pricing" },
  { id: "compatibility", label: "Executors" },
  { id: "faq", label: "FAQ" },
];

const TopNav = ({ onGetKey }) => {
  const [active, setActive] = React.useState(null);
  const tabsRef = React.useRef(null);
  const [indicator, setIndicator] = React.useState({ x: 0, w: 0 });

  const syncIndicator = React.useCallback(() => {
    const nav = tabsRef.current;
    if (!nav) return;
    const idx = active ? NAV_SECTIONS.findIndex((s) => s.id === active) : -1;
    const links = nav.querySelectorAll("a[href^='#']");
    const link = idx >= 0 ? links[idx] : null;
    if (!link || idx < 0) {
      setIndicator((prev) => (prev.w === 0 ? prev : { x: 0, w: 0 }));
      return;
    }
    const nr = nav.getBoundingClientRect();
    const lr = link.getBoundingClientRect();
    setIndicator({ x: lr.left - nr.left, w: lr.width });
  }, [active]);

  React.useLayoutEffect(() => {
    syncIndicator();
    window.addEventListener("resize", syncIndicator);
    return () => window.removeEventListener("resize", syncIndicator);
  }, [syncIndicator]);

  React.useEffect(() => {
    const topPad = 130;
    const run = () => {
      if (window.scrollY < 90) {
        setActive(null);
        return;
      }
      let current = NAV_SECTIONS[0].id;
      for (let i = 0; i < NAV_SECTIONS.length; i++) {
        const el = document.getElementById(NAV_SECTIONS[i].id);
        if (!el) continue;
        const t = el.getBoundingClientRect().top;
        if (t <= topPad) current = NAV_SECTIONS[i].id;
      }
      setActive(current);
    };
    run();
    window.addEventListener("scroll", run, { passive: true });
    return () => window.removeEventListener("scroll", run);
  }, []);

  React.useEffect(() => {
    const fromHash = () => {
      const h = (location.hash || "").replace(/^#/, "");
      if (NAV_SECTIONS.some((s) => s.id === h)) setActive(h);
    };
    window.addEventListener("hashchange", fromHash);
    fromHash();
    return () => window.removeEventListener("hashchange", fromHash);
  }, []);

  return (
    <header className="topnav">
      <div className="wrap topnav-inner">
        <a className="brand" href="#top">
          <span className="brand-mark" />
          <span>Seratonin</span>
          <span className="badge accent brand-ver">v3.2</span>
        </a>
        <nav
          ref={tabsRef}
          className="nav-tabs nav-tabs-rail"
          aria-label="Primary"
          data-active={active || ""}
        >
          <span className="nav-tab-indicator" style={{ left: indicator.x, width: indicator.w }} aria-hidden />
          {NAV_SECTIONS.map((s) => (
            <a
              key={s.id}
              href={`#${s.id}`}
              className={active === s.id ? "is-active" : ""}
            >
              {s.label}
            </a>
          ))}
        </nav>
        <div className="row topnav-actions">
          <a className="pill" href="#" title="Opens Discord">
            <Icon name="discord-fill" size={14} />
            <span>3,841 online</span>
          </a>
          <button type="button" className="btn accent sm" onClick={onGetKey}>Get key</button>
        </div>
      </div>
    </header>
  );
};

const PURCHASE_BLURBS = [
  { plan: "Monthly", tail: "checked out · 12m ago" },
  { plan: "Lifetime", tail: "snagged · 2h ago" },
  { plan: "Monthly", tail: "paid · 47m ago" },
  { plan: "Lifetime", tail: "purchased · yesterday evening" },
  { plan: "Monthly", tail: "just grabbed · 6m ago" },
  { plan: "Lifetime", tail: "went through · 4h ago" },
];

const PurchasePing = () => {
  const [on, setOn] = React.useState(false);
  const [line, setLine] = React.useState(() => PURCHASE_BLURBS[Math.floor(Math.random() * PURCHASE_BLURBS.length)]);

  React.useEffect(() => {
    setLine(PURCHASE_BLURBS[Math.floor(Math.random() * PURCHASE_BLURBS.length)]);
    const id = requestAnimationFrame(() => setOn(true));
    return () => cancelAnimationFrame(id);
  }, []);

  return (
    <div className={`purchase-ping ${on ? "purchase-ping--in" : ""}`} role="status" aria-live="polite">
      <span className="purchase-ping-dot" />
      <div className="purchase-ping-copy">
        <span className="purchase-ping-plan">{line.plan}</span>
        <span className="purchase-ping-meta"> {line.tail}</span>
      </div>
    </div>
  );
};

const Footer = () => (
  <footer className="footer">
    <div className="wrap spread" style={{ alignItems: "flex-start", gap: 48, flexWrap: "wrap" }}>
      <div className="col" style={{ gap: 12, maxWidth: 320 }}>
        <div className="brand"><span className="brand-mark" /><span>Seratonin</span></div>
        <p className="muted" style={{ margin: 0, fontSize: 13 }}>
          Script hub for Roblox. Fast enough to not annoy you, boring enough to actually ship.
        </p>
      </div>
      <div className="row" style={{ gap: 64, alignItems: "flex-start", flexWrap: "wrap" }}>
        <div className="col" style={{ gap: 8 }}>
          <div style={{ fontFamily: "var(--font-mono)", fontSize: 11, letterSpacing: ".14em", textTransform: "uppercase", color: "var(--fg-3)" }}>Product</div>
          <a href="#pricing">Pricing</a><a href="#compatibility">Executors</a><a href="#">Status</a><a href="#faq">FAQ</a>
        </div>
        <div className="col" style={{ gap: 8 }}>
          <div style={{ fontFamily: "var(--font-mono)", fontSize: 11, letterSpacing: ".14em", textTransform: "uppercase", color: "var(--fg-3)" }}>Resources</div>
          <a href="#">Docs</a><a href="#">Discord</a><a href="#">Contact</a>
        </div>
        <div className="col" style={{ gap: 8 }}>
          <div style={{ fontFamily: "var(--font-mono)", fontSize: 11, letterSpacing: ".14em", textTransform: "uppercase", color: "var(--fg-3)" }}>Legal</div>
          <a href="#">Terms</a><a href="#">Privacy</a><a href="#">DMCA</a>
        </div>
      </div>
    </div>
    <div className="wrap" style={{ marginTop: 48, paddingTop: 24, borderTop: "1px solid var(--line-soft)", display: "flex", justifyContent: "space-between", flexWrap: "wrap", gap: 12 }}>
      <span className="dim">© 2026 Seratonin · Independent project · Not affiliated with Roblox Corporation.</span>
      <span className="mono dim">build 3.2.4 — 2026.05.09</span>
    </div>
  </footer>
);

// Modal
const Modal = ({ open, onClose, title, children, width = 460 }) => {
  if (!open) return null;
  return (
    <div role="dialog" aria-modal="true" onClick={onClose}
         style={{
           position: "fixed", inset: 0, zIndex: 100,
           background: "rgba(8, 6, 14, 0.6)",
           backdropFilter: "blur(6px)",
           display: "grid", placeItems: "center",
         }}>
      <div onClick={(e) => e.stopPropagation()}
           style={{
             width: `min(${width}px, 92vw)`,
             background: "var(--bg-1)",
             border: "1px solid var(--line)",
             borderRadius: 18,
             boxShadow: "var(--shadow-lg)",
             padding: 28,
           }}>
        <div className="spread" style={{ marginBottom: 16 }}>
          <h3 style={{ margin: 0 }}>{title}</h3>
          <button className="btn ghost icon" onClick={onClose} aria-label="Close"><Icon name="x" /></button>
        </div>
        {children}
      </div>
    </div>
  );
};

// Toast (minimal)
const Toast = ({ msg }) => msg ? (
  <div style={{
    position: "fixed", bottom: 24, left: "50%", transform: "translateX(-50%)",
    background: "var(--bg-2)", border: "1px solid var(--line)", borderRadius: 10,
    padding: "10px 16px", fontSize: 13, color: "var(--fg)",
    boxShadow: "var(--shadow)", zIndex: 200,
  }}>
    {msg}
  </div>
) : null;

Object.assign(window, { Icon, TopNav, Footer, Modal, Toast, PurchasePing });
