// chrome.jsx — Header, Footer, CTA, Brand, DotLabel
// Small reusable pieces. Exports to window for the section files.

const { useEffect, useState } = React;

// -------- useSpotlight: viewport-wide cursor tracker for [data-glow] cards --------
// Writes --mx / --my (cursor in viewport px) on <html> on every pointermove.
// Every card with data-glow (or matching class in styles.css) uses these via
// background-attachment:fixed, so a single global update lights the card
// under the cursor across the whole page. Locked to Traffy purple in CSS.
function useSpotlight() {
  useEffect(() => {
    const root = document.documentElement;
    const onMove = (e) => {
      root.style.setProperty("--mx", e.clientX);
      root.style.setProperty("--my", e.clientY);
    };
    document.addEventListener("pointermove", onMove, { passive: true });
    return () => document.removeEventListener("pointermove", onMove);
  }, []);
}

// -------- ProgressiveBlur: edge fade via stacked backdrop-filter layers --------
// Adapted from ibelick/motion-primitives — re-written for plain JSX (no
// Tailwind, no `cn()`, no `motion/react` import). Each of N layers sits
// absolutely over the parent, masked to its own segment along `direction`,
// with increasing `backdropFilter: blur()`. Stacked together they form a
// smooth wave of blur intensity — heavier at the edge, none at center.
//
// Usage:
//   <div style={{position:'relative'}}>
//     <ContentToBlur />
//     <ProgressiveBlur direction="left"  className="my-edge-left"  blurIntensity={1} />
//     <ProgressiveBlur direction="right" className="my-edge-right" blurIntensity={1} />
//   </div>
const PROGRESSIVE_BLUR_ANGLES = { top: 0, right: 90, bottom: 180, left: 270 };
function ProgressiveBlur({
  direction = "bottom",
  blurLayers = 8,
  className = "",
  blurIntensity = 0.25,
  style,
}) {
  const layers = Math.max(blurLayers, 2);
  const segmentSize = 1 / (blurLayers + 1);
  const angle = PROGRESSIVE_BLUR_ANGLES[direction] ?? 180;
  return (
    <div className={`progressive-blur ${className}`} style={style} aria-hidden="true">
      {Array.from({ length: layers }).map((_, i) => {
        const stops = [
          i * segmentSize,
          (i + 1) * segmentSize,
          (i + 2) * segmentSize,
          (i + 3) * segmentSize,
        ]
          .map((pos, posIdx) =>
            `rgba(255,255,255,${posIdx === 1 || posIdx === 2 ? 1 : 0}) ${pos * 100}%`
          )
          .join(", ");
        const gradient = `linear-gradient(${angle}deg, ${stops})`;
        return (
          <div
            key={i}
            className="progressive-blur-layer"
            style={{
              maskImage: gradient,
              WebkitMaskImage: gradient,
              backdropFilter: `blur(${i * blurIntensity}px)`,
              WebkitBackdropFilter: `blur(${i * blurIntensity}px)`,
            }}
          />
        );
      })}
    </div>
  );
}

// -------- DotLabel: the · KICKER · marker --------
function DotLabel({ children, className = "", style }) {
  return (
    <span className={`dot-label ${className}`} style={style}>
      <span className="dot" aria-hidden="true"></span>
      <span>{children}</span>
    </span>
  );
}

// -------- Brand: the italic 'traffy' wordmark --------
function Brand({ size, italic = true, style, className = "" }) {
  return (
    <span
      className={`brand ${className}`}
      style={{ fontSize: size, fontStyle: italic ? "italic" : "normal", ...style }}
    >
      traffy
    </span>
  );
}

// -------- CTA: the turquoise pill --------
function CTA({ children = "Leave request", variant, onClick, href }) {
  const cls = `cta-pill${variant ? " " + variant : ""}`;
  if (href) return <a className={cls} href={href} onClick={onClick}>{children}</a>;
  return <button className={cls} onClick={onClick}>{children}</button>;
}

// -------- Header: capsule / flush / pinned, with optional PNG logo --------
function Header({ lang, setLang, onLeaveRequest, t }) {
  const [menuOpen, setMenuOpen] = useState(false);

  useEffect(() => {
    const onScroll = () => {
      document.body.classList.toggle("scrolled", window.scrollY > 24);
    };
    window.addEventListener("scroll", onScroll, { passive: true });
    onScroll();
    return () => window.removeEventListener("scroll", onScroll);
  }, []);

  // Lock body scroll when mobile menu is open
  useEffect(() => {
    document.body.style.overflow = menuOpen ? "hidden" : "";
    return () => { document.body.style.overflow = ""; };
  }, [menuOpen]);

  // Section anchors are absolute (/#id) so they also work from /blog pages.
  // The Blog link is data-spa for client-side navigation.
  const navItems = [
    ["/#services",  t ? t("nav.services")  : "Services", false],
    ["/#creatives", t ? t("nav.creatives") : "Creatives", false],
    ["/#cases",     t ? t("nav.cases")     : "Cases", false],
    ["/#why",       t ? t("nav.why")       : "Why Traffy", false],
    ["/#contacts",  t ? t("nav.contacts")  : "Contacts", false],
    ["/blog",       t ? t("nav.blog")      : "Blog", true],
  ];

  const closeMenu = () => setMenuOpen(false);

  return (
    <header className={`site-header${menuOpen ? " menu-open" : ""}`}>
      <div className="header-inner">
        <a href="/" data-spa="" className="brand" onClick={closeMenu}>
          <img className="brand-mark" src={(window.__resources && window.__resources.traffyLogo) || "traffy-logo.png"} alt="traffy" />
        </a>
        <nav className="nav">
          {navItems.map(([href, label, spa]) => (
            <a key={href} href={href} {...(spa ? { "data-spa": "" } : {})}>{label}</a>
          ))}
        </nav>
        <div className="header-tools">
          <div className="lang" role="group" aria-label="Language">
            <button
              type="button"
              aria-pressed={lang === "en"}
              onClick={() => setLang("en")}
            >EN</button>
            <span className="sep">/</span>
            <button
              type="button"
              aria-pressed={lang === "ru"}
              onClick={() => setLang("ru")}
            >RU</button>
          </div>
          <CTA onClick={onLeaveRequest}>{t ? t("cta.short") : "Leave request"}</CTA>
          <button
            className="hamburger"
            type="button"
            onClick={() => setMenuOpen(v => !v)}
            aria-label={menuOpen ? "Close menu" : "Open menu"}
            aria-expanded={menuOpen}
          >
            <span /><span /><span />
          </button>
        </div>
      </div>

      {/* Mobile nav — right-side drawer */}
      <nav className={`mobile-nav${menuOpen ? " is-open" : ""}`} aria-hidden={!menuOpen}>
        <button className="drawer-close" type="button" onClick={closeMenu} aria-label="Close menu">×</button>
        {navItems.map(([href, label, spa]) => (
          <a key={href} href={href} {...(spa ? { "data-spa": "" } : {})} onClick={closeMenu}>{label}</a>
        ))}
        <div className="mobile-nav-tools">
          <div className="lang" role="group" aria-label="Language">
            <button type="button" aria-pressed={lang === "en"} onClick={() => { setLang("en"); closeMenu(); }}>EN</button>
            <span className="sep">/</span>
            <button type="button" aria-pressed={lang === "ru"} onClick={() => { setLang("ru"); closeMenu(); }}>RU</button>
          </div>
          <CTA onClick={() => { onLeaveRequest(); closeMenu(); }}>
            {t ? t("contacts.cta") : "Leave request"}
          </CTA>
        </div>
      </nav>
    </header>
  );
}

// -------- Footer --------
function Footer() {
  return (
    <footer className="footer">
      <div className="footer-inner">
        <div className="footer-cols">
          <div className="footer-col">
            <h4>Sales</h4>
            <a href="mailto:sales@traffy.com">sales@traffy.com</a>
            <p className="muted" style={{ marginTop: 12 }}>Pavel Kotov</p>
            <a href="#">LinkedIn</a>
            <a href="#">@Pavel_Traffy</a>
          </div>
          <div className="footer-col">
            <h4>PR</h4>
            <a href="mailto:pr@traffy.com">pr@traffy.com</a>
            <p className="muted" style={{ marginTop: 12 }}>Veronika Neumerzhitckaia</p>
            <a href="#">LinkedIn</a>
            <a href="#">@VeronikaNeumerzhitckaia_Traffy</a>
          </div>
          <div className="footer-col">
            <h4>Legal</h4>
            <p>AdWave LTD</p>
            <p className="muted">Company № HE 380370</p>
            <p className="muted">Est. 23.02.2018</p>
            <p className="muted">Eleftherias 113, 3042<br/>Limassol, Cyprus</p>
          </div>
        </div>
        <div className="footer-bottom">
          <span className="brand-mini">traffy</span>
          <span className="links">
            <a href="#">Telegram</a>
            <a href="#">LinkedIn</a>
            <span>© 2018–2026</span>
          </span>
        </div>
      </div>
    </footer>
  );
}

// -------- Reveal: hook that adds in-view on intersect --------
// Uses a scroll/rAF-based getBoundingClientRect check (IntersectionObserver
// runs unreliably in this iframe environment). Auto-staggers children of
// a section: each .reveal inside gets a per-element delay so a block
// fades in as a sequence, not all at once.
function useReveals() {
  useEffect(() => {
    let cancelled = false;

    const inView = (rect) =>
      rect.top < window.innerHeight * 0.88 &&
      rect.bottom > 0;

    const scan = () => {
      if (cancelled) return;
      // group reveals by their containing section so we can stagger
      const groups = new Map();
      document.querySelectorAll(".reveal:not(.in-view)").forEach((el) => {
        if (!inView(el.getBoundingClientRect())) return;
        const sec = el.closest("section") || document.body;
        if (!groups.has(sec)) groups.set(sec, []);
        groups.get(sec).push(el);
      });
      groups.forEach((els) => {
        // sort top-to-bottom inside the section
        els.sort((a, b) => a.getBoundingClientRect().top - b.getBoundingClientRect().top);
        els.forEach((el, i) => {
          // honor explicit per-element delay if author set --rv-d
          const cur = el.style.getPropertyValue("--rv-d");
          // 110ms stagger — close to AdSkill's 100-150ms cascade rhythm, paired
          // with the 800ms reveal duration for a snappy fade-up without losing
          // the sense of sequence.
          if (!cur) el.style.setProperty("--rv-d", `${i * 110}ms`);
          el.classList.add("in-view");
          // fallback: if CSS animation didn't advance after a beat,
          // snap to end state (some preview/capture envs pause animations).
          setTimeout(() => {
            const anim = el.getAnimations && el.getAnimations()[0];
            if (anim && anim.currentTime === 0 && anim.playState !== "finished") {
              el.classList.add("snap");
            }
          }, 250);
        });
      });
    };

    scan();
    const t1 = setTimeout(scan, 50);
    const t2 = setTimeout(scan, 250);

    const onScroll = () => requestAnimationFrame(scan);
    window.addEventListener("scroll", onScroll, { passive: true });
    window.addEventListener("resize", onScroll);

    const mo = new MutationObserver(() => requestAnimationFrame(scan));
    mo.observe(document.body, { childList: true, subtree: true });

    return () => {
      cancelled = true;
      clearTimeout(t1); clearTimeout(t2);
      window.removeEventListener("scroll", onScroll);
      window.removeEventListener("resize", onScroll);
      mo.disconnect();
    };
  }, []);
}

// -------- SectionRule: animated drawing rule at top of each section
function SectionRule() {
  return <div className="section-rule reveal" />;
}

// -------- ScrollProgress: thin accent line at top of viewport --------
function ScrollProgress() {
  const ref = React.useRef(null);
  useEffect(() => {
    const el = ref.current;
    if (!el) return;
    let raf;
    const onScroll = () => {
      cancelAnimationFrame(raf);
      raf = requestAnimationFrame(() => {
        const h = document.documentElement.scrollHeight - window.innerHeight;
        el.style.width = h > 0 ? `${(window.scrollY / h) * 100}%` : "0%";
      });
    };
    window.addEventListener("scroll", onScroll, { passive: true });
    return () => { window.removeEventListener("scroll", onScroll); cancelAnimationFrame(raf); };
  }, []);
  return <div ref={ref} className="scroll-progress" aria-hidden="true" />;
}

Object.assign(window, {
  DotLabel, Brand, CTA, Header, Footer, useReveals, SectionRule, ScrollProgress,
  ProgressiveBlur, useSpotlight,
});
