/* Techonymous — shared React components (Navbar, Footer, Cursor, Aurora, etc.)
   Babel-transpiled; components exported to window so other scripts can use them. */

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

/* ---------- Tiny inline icon set (Lucide-style strokes) ---------- */
const Icon = ({ name, size = 20, strokeWidth = 1.7, className = "" }) => {
  const props = {
    width: size, height: size,
    viewBox: "0 0 24 24",
    fill: "none",
    stroke: "currentColor",
    strokeWidth, strokeLinecap: "round", strokeLinejoin: "round",
    className,
  };
  switch (name) {
    case "arrow-right":   return <svg {...props}><path d="M5 12h14M13 5l7 7-7 7"/></svg>;
    case "arrow-up-right":return <svg {...props}><path d="M7 17 17 7M8 7h9v9"/></svg>;
    case "check":         return <svg {...props}><path d="M20 6 9 17l-5-5"/></svg>;
    case "plus":          return <svg {...props}><path d="M12 5v14M5 12h14"/></svg>;
    case "menu":          return <svg {...props}><path d="M4 7h16M4 17h16"/></svg>;
    case "x":             return <svg {...props}><path d="M18 6 6 18M6 6l12 12"/></svg>;
    case "code":          return <svg {...props}><polyline points="16 18 22 12 16 6"/><polyline points="8 6 2 12 8 18"/></svg>;
    case "search":        return <svg {...props}><circle cx="11" cy="11" r="7"/><path d="m21 21-4.3-4.3"/></svg>;
    case "trending-up":   return <svg {...props}><polyline points="22 7 13.5 15.5 8.5 10.5 2 17"/><polyline points="16 7 22 7 22 13"/></svg>;
    case "target":        return <svg {...props}><circle cx="12" cy="12" r="10"/><circle cx="12" cy="12" r="6"/><circle cx="12" cy="12" r="2"/></svg>;
    case "sparkles":      return <svg {...props}><path d="M12 3v3M12 18v3M3 12h3M18 12h3M5.6 5.6l2.1 2.1M16.3 16.3l2.1 2.1M5.6 18.4l2.1-2.1M16.3 7.7l2.1-2.1"/></svg>;
    case "wand":          return <svg {...props}><path d="M15 4V2M15 16v-2M8 9h2M20 9h2M17.8 11.8 19 13M15 9h0M17.8 6.2 19 5M3 21l9-9M12.2 6.2 11 5"/></svg>;
    case "layers":        return <svg {...props}><path d="m12 2 9 5-9 5-9-5 9-5z"/><path d="m3 17 9 5 9-5"/><path d="m3 12 9 5 9-5"/></svg>;
    case "zap":           return <svg {...props}><path d="M13 2 3 14h9l-1 8 10-12h-9l1-8z"/></svg>;
    case "shield-check":  return <svg {...props}><path d="M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10z"/><path d="m9 12 2 2 4-4"/></svg>;
    case "users":         return <svg {...props}><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 0 7.75"/></svg>;
    case "bar-chart":     return <svg {...props}><line x1="12" y1="20" x2="12" y2="10"/><line x1="18" y1="20" x2="18" y2="4"/><line x1="6"  y1="20" x2="6"  y2="14"/><line x1="3" y1="20" x2="21" y2="20"/></svg>;
    case "compass":       return <svg {...props}><circle cx="12" cy="12" r="10"/><polygon points="16.24 7.76 14.12 14.12 7.76 16.24 9.88 9.88 16.24 7.76"/></svg>;
    case "rocket":        return <svg {...props}><path d="M4.5 16.5c-1.5 1.26-2 5-2 5s3.74-.5 5-2c.71-.84.7-2.13-.09-2.91a2.18 2.18 0 0 0-2.91-.09z"/><path d="m12 15-3-3a22 22 0 0 1 2-3.95A12.88 12.88 0 0 1 22 2c0 2.72-.78 7.5-6 11a22.35 22.35 0 0 1-4 2z"/><path d="M9 12H4s.55-3.03 2-4c1.62-1.08 5 0 5 0"/><path d="M12 15v5s3.03-.55 4-2c1.08-1.62 0-5 0-5"/></svg>;
    case "globe":         return <svg {...props}><circle cx="12" cy="12" r="10"/><line x1="2" y1="12" x2="22" y2="12"/><path d="M12 2a15.3 15.3 0 0 1 4 10 15.3 15.3 0 0 1-4 10 15.3 15.3 0 0 1-4-10 15.3 15.3 0 0 1 4-10z"/></svg>;
    case "play":          return <svg {...props}><polygon points="6 4 20 12 6 20 6 4"/></svg>;
    case "twitter":       return <svg {...props} viewBox="0 0 24 24"><path d="M18 4h3l-7.5 8.6L22 22h-6.8l-5.3-6.9L3.7 22H1l8-9.2L1.5 4h6.9l4.8 6.4L18 4z" fill="currentColor" stroke="none"/></svg>;
    case "linkedin":      return <svg {...props}><path d="M16 8a6 6 0 0 1 6 6v7h-4v-7a2 2 0 1 0-4 0v7h-4v-7a6 6 0 0 1 6-6z"/><rect x="2" y="9" width="4" height="12"/><circle cx="4" cy="4" r="2"/></svg>;
    case "instagram":     return <svg {...props}><rect x="3" y="3" width="18" height="18" rx="5"/><path d="M16 11.4A4 4 0 1 1 12.6 8 4 4 0 0 1 16 11.4z"/><line x1="17.5" y1="6.5" x2="17.5" y2="6.5"/></svg>;
    case "youtube":       return <svg {...props}><path d="M22 12s0-4-.5-5.8a3 3 0 0 0-2.1-2.1C17.5 3.5 12 3.5 12 3.5s-5.5 0-7.4.6A3 3 0 0 0 2.5 6.2C2 8 2 12 2 12s0 4 .5 5.8A3 3 0 0 0 4.6 19.9c1.9.6 7.4.6 7.4.6s5.5 0 7.4-.6a3 3 0 0 0 2.1-2.1C22 16 22 12 22 12z"/><polygon points="10 8 16 12 10 16 10 8"/></svg>;
    case "star":          return <svg {...props}><polygon points="12 2 15.1 8.4 22 9.3 17 14.1 18.2 21 12 17.8 5.8 21 7 14.1 2 9.3 8.9 8.4 12 2"/></svg>;
    default: return null;
  }
};

/* ---------- Custom cursor ---------- */
function Cursor() {
  useEffect(() => {
    const orb = document.createElement("div");
    orb.className = "cursor-orb";
    orb.innerHTML = '<div class="cursor-orb__core"></div>';
    document.body.appendChild(orb);

    let x = window.innerWidth/2, y = window.innerHeight/2;
    let tx = x, ty = y;
    const onMove = (e) => { tx = e.clientX; ty = e.clientY; };
    window.addEventListener("mousemove", onMove);

    let raf;
    const tick = () => {
      x += (tx - x) * 0.22;
      y += (ty - y) * 0.22;
      orb.style.transform = `translate(${x}px, ${y}px) translate(-50%, -50%)`;
      raf = requestAnimationFrame(tick);
    };
    tick();

    const matchHover = (el) => el && (el.closest('a, button, .btn, .nav__link, .case-card, .case-filter, .faq-q, .bento__card, [data-cursor="hover"]'));
    const onOver = (e) => { if (matchHover(e.target)) orb.classList.add("is-hover"); };
    const onOut  = (e) => { if (matchHover(e.target)) orb.classList.remove("is-hover"); };
    document.addEventListener("mouseover", onOver);
    document.addEventListener("mouseout", onOut);

    return () => {
      cancelAnimationFrame(raf);
      window.removeEventListener("mousemove", onMove);
      document.removeEventListener("mouseover", onOver);
      document.removeEventListener("mouseout", onOut);
      orb.remove();
    };
  }, []);
  return null;
}

/* ---------- Aurora background (animated blobs + noise + grid) ---------- */
function Aurora({ variant = "default" }) {
  return (
    <>
      <div className="aurora" aria-hidden="true">
        <div className="aurora__blob aurora__blob--1"></div>
        <div className="aurora__blob aurora__blob--2"></div>
        <div className="aurora__blob aurora__blob--3"></div>
      </div>
      <div className="grid-lines" aria-hidden="true"></div>
      <div className="noise" aria-hidden="true"></div>
    </>
  );
}

/* ---------- Logo mark ---------- */
function Logo({ size = 45 }) {
  return (
    <a href={(window.__base||"")+"index.html"} className="nav__logo" aria-label="Techonymous">
      <img src="../assets/logo-full.png" alt="Techonymous" style={{ height: size, width: "auto", display: "block" }} />
    </a>
  );
}

/* Icon-only mark — for tight spots or favicons */
function LogoMark({ size = 32 }) {
  return (
    <img src="assets/logo-icon.png" alt="" aria-hidden="true" style={{ width: size, height: size, display: "block" }} />
  );
}

/* ---------- Navbar ---------- */
function Navbar({ active = "home" }) {
  const [scrolled, setScrolled] = useState(false);
  const [mobileOpen, setMobileOpen] = useState(false);

  useEffect(() => {
    const onScroll = () => setScrolled(window.scrollY > 12);
    onScroll();
    window.addEventListener("scroll", onScroll, { passive: true });
    return () => window.removeEventListener("scroll", onScroll);
  }, []);

  useEffect(() => {
    document.body.style.overflow = mobileOpen ? "hidden" : "";
  }, [mobileOpen]);

  const base = (typeof window !== "undefined" && window.__base) || "";
  const links = [
    { id: "home",     label: "Home",     href: base + "index.html" },
    { id: "services", label: "Services", href: base + "services/index.html" },
    { id: "work",     label: "Work",     href: base + "work/index.html" },
    { id: "about",    label: "About",    href: base + "about/index.html" },
    { id: "blog",     label: "Blog",     href: "#" },
    { id: "contact",  label: "Contact",  href: base + "contact/index.html" },
  ];

  return (
    <>
      <nav className={`nav ${scrolled ? "is-scrolled" : ""}`} ref={(el) => {
        if (el && !el.__animated && window.gsap) {
          el.__animated = true;
          window.gsap.from(el, { y: -80, opacity: 0, duration: 1, ease: "power3.out", delay: 0.05 });
        }
      }}>
        <div className="container-x">
          <div className="nav__inner">
            <Logo />
            <div className="nav__links">
              {links.map(l => (
                <a key={l.id} href={l.href} className={`nav__link ${active === l.id ? "is-active" : ""}`}>
                  {l.label}
                </a>
              ))}
            </div>
            <div style={{ display: "flex", gap: 10, alignItems: "center" }}>
              <a href={(window.__base||"")+"contact/index.html"} className="btn btn-primary nav__cta">
                Get a Free Audit
                <Icon name="arrow-right" size={16} />
              </a>
              <button className="nav__hamburger" onClick={() => setMobileOpen(true)} aria-label="Open menu">
                <Icon name="menu" />
              </button>
            </div>
          </div>
        </div>
      </nav>

      {mobileOpen && (
        <div className="mobile-menu">
          <div style={{ position: "absolute", top: 18, right: 20 }}>
            <button className="nav__hamburger" onClick={() => setMobileOpen(false)} aria-label="Close menu">
              <Icon name="x" />
            </button>
          </div>
          {links.map((l, i) => (
            <a key={l.id} href={l.href} className="mobile-menu__link"
               style={{ animation: `slideIn 0.5s ${i * 0.06}s cubic-bezier(0.2, 0.8, 0.2, 1) both` }}>
              {l.label}
            </a>
          ))}
          <a href={(window.__base||"")+"contact/index.html"} className="btn btn-primary" style={{ marginTop: 24, alignSelf: "flex-start" }}>
            Get a Free Audit <Icon name="arrow-right" size={16} />
          </a>
          <style>{`@keyframes slideIn { from { opacity: 0; transform: translateY(20px); } to { opacity: 1; transform: translateY(0); } }`}</style>
        </div>
      )}
    </>
  );
}

/* ---------- Footer ---------- */
function Footer() {
  return (
    <footer className="footer">
      <div className="container-x">
        <div className="footer__grid">
          <div className="footer__brand">
            <Logo />
            <p>The performance marketing and web engineering studio for brands that refuse to coast on vanity metrics.</p>
            <div className="footer__socials">
              {["twitter","linkedin","instagram","youtube"].map(s => (
                <a key={s} className="footer__social" href="#" aria-label={s}><Icon name={s} size={16} /></a>
              ))}
            </div>
          </div>
          <div className="footer__col">
            <h4>Company</h4>
            <ul>
              <li><a href={(window.__base||"")+"about/index.html"}>About</a></li>
              <li><a href={(window.__base||"")+"work/index.html"}>Case Studies</a></li>
              <li><a href="#">Careers</a></li>
              <li><a href="#">Press</a></li>
            </ul>
          </div>
          <div className="footer__col">
            <h4>Services</h4>
            <ul>
              <li><a href={(window.__base||"")+"services/index.html"}>Web Development</a></li>
              <li><a href={(window.__base||"")+"services/index.html"}>SEO &amp; Content</a></li>
              <li><a href={(window.__base||"")+"services/index.html"}>Performance Ads</a></li>
              <li><a href={(window.__base||"")+"services/index.html"}>CRO</a></li>
            </ul>
          </div>
          <div className="footer__col">
            <h4>Resources</h4>
            <ul>
              <li><a href="#">Blog</a></li>
              <li><a href="#">Growth Playbook</a></li>
              <li><a href="#">ROI Calculator</a></li>
              <li><a href="#">Free Audit</a></li>
            </ul>
          </div>
          <div className="footer__col">
            <h4>Newsletter</h4>
            <p style={{ color: "var(--txt-2)", fontSize: 14, lineHeight: 1.55, margin: "0 0 14px" }}>
              Monthly growth playbooks. Zero fluff.
            </p>
            <form onSubmit={(e) => e.preventDefault()} style={{ display: "flex", gap: 6 }}>
              <input type="email" placeholder="you@company.com"
                     style={{
                       flex: 1, padding: "11px 14px", borderRadius: 999,
                       background: "rgba(255,255,255,0.04)",
                       border: "1px solid var(--border-glass)",
                       color: "#fff", fontSize: 13.5, outline: "none",
                       fontFamily: "inherit",
                     }} />
              <button className="btn btn-primary" style={{ padding: "10px 14px" }}>
                <Icon name="arrow-right" size={16} />
              </button>
            </form>
          </div>
        </div>
        <div className="footer__bottom">
          <div>© 2026 Techonymous Labs Inc. All rights reserved.</div>
          <div style={{ display: "flex", gap: 24 }}>
            <a href="#">Privacy</a>
            <a href="#">Terms</a>
            <a href="#">Cookies</a>
          </div>
        </div>
      </div>
    </footer>
  );
}

/* ---------- ScrollReveal helper ---------- */
function useScrollReveal(rootSelector = ".reveal") {
  useEffect(() => {
    const els = document.querySelectorAll(rootSelector);
    const io = new IntersectionObserver((entries) => {
      entries.forEach(e => {
        if (e.isIntersecting) {
          e.target.classList.add("is-in");
          io.unobserve(e.target);
        }
      });
    }, { threshold: 0.12, rootMargin: "0px 0px -8% 0px" });
    els.forEach(el => io.observe(el));
    return () => io.disconnect();
  }, [rootSelector]);
}

/* ---------- Count-up hook ---------- */
function useCountUp(target, { duration = 1800, start = false, decimals = 0 } = {}) {
  const [val, setVal] = useState(0);
  useEffect(() => {
    if (!start) return;
    const t0 = performance.now();
    let raf;
    const tick = (t) => {
      const p = Math.min(1, (t - t0) / duration);
      const eased = 1 - Math.pow(1 - p, 3);
      setVal(target * eased);
      if (p < 1) raf = requestAnimationFrame(tick);
    };
    raf = requestAnimationFrame(tick);
    return () => cancelAnimationFrame(raf);
  }, [start, target, duration]);
  return decimals === 0 ? Math.round(val) : val.toFixed(decimals);
}

/* ---------- Sparkline SVG ---------- */
function Sparkline({ data, color = "#00D4FF", className = "spark" }) {
  const max = Math.max(...data);
  const min = Math.min(...data);
  const w = 200, h = 36;
  const stepX = w / (data.length - 1);
  const pts = data.map((v, i) => {
    const x = i * stepX;
    const y = h - ((v - min) / (max - min || 1)) * (h - 4) - 2;
    return `${x},${y}`;
  });
  const d = "M " + pts.join(" L ");
  const dArea = d + ` L ${w},${h} L 0,${h} Z`;
  return (
    <svg viewBox={`0 0 ${w} ${h}`} className={className} preserveAspectRatio="none">
      <defs>
        <linearGradient id={`sg-${color.replace('#','')}`} x1="0" x2="0" y1="0" y2="1">
          <stop offset="0%" stopColor={color} stopOpacity="0.45"/>
          <stop offset="100%" stopColor={color} stopOpacity="0"/>
        </linearGradient>
      </defs>
      <path d={dArea} fill={`url(#sg-${color.replace('#','')})`} />
      <path d={d} fill="none" stroke={color} strokeWidth="1.6" strokeLinecap="round" strokeLinejoin="round" />
    </svg>
  );
}

/* ---------- Magnetic button effect ---------- */
function attachMagnetic(el, strength = 18) {
  if (!el || el.__magnetic) return;
  el.__magnetic = true;
  const onMove = (e) => {
    const r = el.getBoundingClientRect();
    const x = e.clientX - (r.left + r.width / 2);
    const y = e.clientY - (r.top + r.height / 2);
    el.style.transform = `translate(${x / strength}px, ${y / strength}px)`;
  };
  const onLeave = () => { el.style.transform = ""; };
  el.addEventListener("mousemove", onMove);
  el.addEventListener("mouseleave", onLeave);
}

/* Auto-attach magnetic to all .btn-primary */
function MagneticInit() {
  useEffect(() => {
    document.querySelectorAll(".btn-primary").forEach(b => attachMagnetic(b));
  });
  return null;
}

/* ---------- Page shell ---------- */
function PageShell({ children, active }) {
  return (
    <>
      <Cursor />
      <Navbar active={active} />
      {children}
      <Footer />
      <MagneticInit />
    </>
  );
}

/* expose to global window */
Object.assign(window, {
  Icon, Cursor, Aurora, Logo, LogoMark, Navbar, Footer, PageShell,
  useScrollReveal, useCountUp, Sparkline, attachMagnetic, MagneticInit,
});
