// Shared chrome — Nav, Footer, helpers — for all pages in Relay v4
const { useState, useEffect, useRef, useLayoutEffect } = React;

/* ============ SCROLL REVEAL ============
   Adds class `in` to any element with class `reveal` once it enters the
   viewport. Pair with CSS .reveal { opacity:0; transform:translateY }
   .reveal.in { opacity:1; transform:none } for a clean fade-up.
*/
function useScrollReveal() {
  useEffect(() => {
    if (typeof IntersectionObserver === 'undefined') return;
    const els = document.querySelectorAll('.reveal');
    const io = new IntersectionObserver((entries) => {
      for (const e of entries) {
        if (e.isIntersecting) {
          e.target.classList.add('in');
          io.unobserve(e.target);
        }
      }
    }, { threshold: 0.12, rootMargin: '0px 0px -80px 0px' });
    els.forEach((el) => io.observe(el));
    return () => io.disconnect();
  }, []);
}

/* ============ MAGIC CARD (mouse-tracking spotlight) ============
   Wraps a clickable card. Tracks pointer position via CSS custom
   properties (--mx, --my); the spotlight is rendered via ::before.
*/
function MagicCard({ as: Tag = 'a', className = '', children, ...rest }) {
  const ref = useRef(null);
  const onMove = (e) => {
    const el = ref.current;
    if (!el) return;
    const r = el.getBoundingClientRect();
    el.style.setProperty('--mx', `${e.clientX - r.left}px`);
    el.style.setProperty('--my', `${e.clientY - r.top}px`);
  };
  return (
    <Tag ref={ref} className={`magic ${className}`} onMouseMove={onMove} {...rest}>
      {children}
    </Tag>
  );
}

/* ============ ANIMATED GRID PATTERN ============ */
function GridPattern({ className = '' }) {
  return <div className={`grid-bg ${className}`} aria-hidden></div>;
}

/* ============ HERO ILLUSTRATION (relay / change motif) ============
   Four blocks scatter in from the corners and snap into place around a
   center node. Lines then draw in connecting them. Reads as: a system
   coming together. Long quiet hold, then dis/re-assembles on a cycle.
*/
function HeroIllustration() {
  return (
    <div className="hero-illo" aria-hidden>
      <svg viewBox="0 0 600 600" preserveAspectRatio="xMidYMid meet" role="presentation">
        <defs>
          <radialGradient id="hero-illo-glow" cx="50%" cy="50%" r="50%">
            <stop offset="0%"   stopColor="rgba(155, 230, 122, 0.14)" />
            <stop offset="55%"  stopColor="rgba(155, 230, 122, 0.04)" />
            <stop offset="100%" stopColor="rgba(155, 230, 122, 0)" />
          </radialGradient>
        </defs>

        {/* Soft center glow */}
        <circle cx="300" cy="300" r="250" fill="url(#hero-illo-glow)" />

        {/* Faint axis guides */}
        <line x1="100" y1="300" x2="500" y2="300"
              stroke="rgba(255, 255, 255, 0.04)" strokeDasharray="2 6" />
        <line x1="300" y1="100" x2="300" y2="500"
              stroke="rgba(255, 255, 255, 0.04)" strokeDasharray="2 6" />

        {/* Connection lines — draw in last */}
        <line className="illo-line illo-line-1" x1="200" y1="200" x2="300" y2="300"
              stroke="rgba(155, 230, 122, 0.45)" strokeWidth="1.2" strokeLinecap="round" />
        <line className="illo-line illo-line-2" x1="400" y1="200" x2="300" y2="300"
              stroke="rgba(155, 230, 122, 0.45)" strokeWidth="1.2" strokeLinecap="round" />
        <line className="illo-line illo-line-3" x1="200" y1="400" x2="300" y2="300"
              stroke="rgba(155, 230, 122, 0.45)" strokeWidth="1.2" strokeLinecap="round" />
        <line className="illo-line illo-line-4" x1="400" y1="400" x2="300" y2="300"
              stroke="rgba(155, 230, 122, 0.45)" strokeWidth="1.2" strokeLinecap="round" />

        {/* Pulse ring radiates from center during hold */}
        <circle className="illo-pulse" cx="300" cy="300" r="6"
                fill="none" stroke="#b6ff5e" strokeWidth="1.5" />

        {/* Center node */}
        <g className="illo-center">
          <circle cx="300" cy="300" r="16"
                  fill="none" stroke="rgba(155, 230, 122, 0.3)" strokeWidth="1"
                  strokeDasharray="2 4" />
          <circle cx="300" cy="300" r="5" fill="#b6ff5e" />
        </g>

        {/* Four blocks — scatter in from corners */}
        <g className="illo-block illo-block-1">
          <rect x="150" y="150" width="100" height="100" rx="2"
                fill="rgba(155, 230, 122, 0.05)"
                stroke="rgba(155, 230, 122, 0.55)" strokeWidth="1.4" />
          <circle cx="200" cy="200" r="2.5" fill="rgba(155, 230, 122, 0.6)" />
        </g>
        <g className="illo-block illo-block-2">
          <rect x="350" y="150" width="100" height="100" rx="2"
                fill="rgba(155, 230, 122, 0.05)"
                stroke="rgba(155, 230, 122, 0.55)" strokeWidth="1.4" />
          <circle cx="400" cy="200" r="2.5" fill="rgba(155, 230, 122, 0.6)" />
        </g>
        <g className="illo-block illo-block-3">
          <rect x="150" y="350" width="100" height="100" rx="2"
                fill="rgba(155, 230, 122, 0.05)"
                stroke="rgba(155, 230, 122, 0.55)" strokeWidth="1.4" />
          <circle cx="200" cy="400" r="2.5" fill="rgba(155, 230, 122, 0.6)" />
        </g>
        <g className="illo-block illo-block-4">
          <rect x="350" y="350" width="100" height="100" rx="2"
                fill="rgba(155, 230, 122, 0.05)"
                stroke="rgba(155, 230, 122, 0.55)" strokeWidth="1.4" />
          <circle cx="400" cy="400" r="2.5" fill="rgba(155, 230, 122, 0.6)" />
        </g>
      </svg>
    </div>
  );
}

/* ============ SECTION DIVIDER ============ */
function SectionDivider() {
  return (
    <div className="wrap max">
      <div className="divider" aria-hidden>
        <span></span>
      </div>
    </div>
  );
}

/* ============ PAGE TRANSITIONS ============
   Intercept clicks to our own .html pages, fade body out, then navigate.
   Browser then loads the next page; reveal animations on the new page
   fade things back in. Net effect: pages feel like one continuous motion.
*/
function usePageTransitions() {
  useEffect(() => {
    const handler = (e) => {
      if (e.defaultPrevented) return;
      if (e.ctrlKey || e.metaKey || e.shiftKey || e.button !== 0) return;
      const a = e.target.closest('a[href]');
      if (!a) return;
      if (a.target === '_blank' || a.hasAttribute('download')) return;
      const href = a.getAttribute('href') || '';
      if (!href) return;
      if (href.startsWith('#')) return;
      if (href.startsWith('mailto:') || href.startsWith('tel:')) return;
      if (a.origin && a.origin !== window.location.origin) return;
      const path = a.pathname || '';
      const isPage = path.endsWith('.html') || path === '/' || path.endsWith('/');
      if (!isPage) return;
      // Don't transition to the same page we're already on
      if (a.href === window.location.href) return;

      e.preventDefault();
      document.documentElement.classList.add('is-leaving');
      setTimeout(() => { window.location.href = a.href; }, 220);
    };
    document.addEventListener('click', handler);
    return () => document.removeEventListener('click', handler);
  }, []);
}

/* ============ NOW PANEL (personal, friendly hero visual) ============ */
function NowPanel() {
  return (
    <div className="now-panel">
      <div className="now-head">
        <span className="now-label">A more human kind of help</span>
        <span className="now-loc">Ōtautahi · Christchurch</span>
      </div>
      <p className="now-greet">
        One person who knows the context, makes the next step clear, and stays with the work <em>until it feels settled.</em>
      </p>
      <ul className="now-list">
        <li><span className="now-bullet"></span>Start with the real situation, not a predefined package.</li>
        <li><span className="now-bullet"></span>Get practical advice without the technical theatre.</li>
        <li><span className="now-bullet"></span>Leave with a plan you can actually act on.</li>
      </ul>
      <div className="now-foot">
        <span className="now-dot"></span>
        <span>Replies within a working day · New enquiries welcome</span>
      </div>
    </div>
  );
}

const ArrowOut = ({ size = 16 }) => (
  <svg width={size} height={size} viewBox="0 0 16 16" fill="none" aria-hidden>
    <path d="M4 12L12 4M12 4H6M12 4V10" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round" />
  </svg>
);
const ArrowRight = ({ size = 14 }) => (
  <svg width={size} height={size} viewBox="0 0 14 14" fill="none" aria-hidden>
    <path d="M2.5 7H11.5M11.5 7L7.5 3M11.5 7L7.5 11" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round" />
  </svg>
);
const LogoMark = ({ height = 16 }) => (
  <svg className="nav-mark" viewBox="0 0 50 24" style={{ height }} aria-hidden>
    <path d="M0 24 L8 0 L18 0 L10 24 Z" />
    <path d="M16 24 L24 0 L34 0 L26 24 Z" />
    <path d="M32 24 L40 0 L50 0 L42 24 Z" />
  </svg>
);

/* ============ STATUS PILL ============ */
function StatusPill({ status, active }) {
  return (
    <span className={`status-pill ${active ? 'is-active' : ''}`}>
      {active && <span className="status-dot" aria-hidden></span>}
      {status}
    </span>
  );
}

/* ============ NAV ============ */
function Nav({ active }) {
  const [open, setOpen] = useState(false);
  const items = [
    { id: 'work',     label: 'Work',     href: 'work.html' },
    { id: 'contact',  label: 'Contact',  href: 'contact.html' },
  ];

  // Close menu on Escape
  useEffect(() => {
    if (!open) return;
    const onKey = (e) => { if (e.key === 'Escape') setOpen(false); };
    document.addEventListener('keydown', onKey);
    return () => document.removeEventListener('keydown', onKey);
  }, [open]);

  return (
    <div className="nav-wrap">
      <nav className="nav">
        <a className="nav-brand" href="index.html">
          <LogoMark />
          <span className="nav-brand-word">Relay</span>
          <span className="nav-brand-sub">Consulting</span>
        </a>
        <div className="nav-links">
          {items.map(it => (
            <a key={it.id} href={it.href} className={active === it.id ? 'active' : ''}>
              {it.label}
            </a>
          ))}
        </div>
        <button
          className="nav-toggle"
          onClick={() => setOpen(o => !o)}
          aria-label={open ? 'Close menu' : 'Open menu'}
          aria-expanded={open ? 'true' : 'false'}
          type="button"
        >
          <span></span><span></span><span></span>
        </button>
        <a className="nav-cta" href="contact.html">Get in touch</a>
      </nav>
      <div className={`nav-mobile ${open ? 'open' : ''}`} aria-hidden={!open}>
        {items.map(it => (
          <a key={it.id} href={it.href} className={active === it.id ? 'active' : ''}
             onClick={() => setOpen(false)}>
            {it.label}
          </a>
        ))}
      </div>
    </div>
  );
}

/* ============ TOOLS DATA ============ */
const TOOLS = [
  { name: 'Microsoft 365',    src: 'assets/office365.png' },
  { name: 'Google Workspace', src: 'assets/googleworkspace.png' },
  { name: 'GitHub',           src: 'assets/github.png' },
  { name: 'Vercel',           src: 'assets/vercel.png' },
  { name: 'Cloudflare',       src: 'assets/cloudflare.webp' },
  { name: 'Tailscale',        src: 'assets/tailscale.png' },
  { name: 'Keeper',           src: 'assets/keeper.png' },
  { name: 'FortiGate',        src: 'assets/fortigate.png' },
  { name: 'Entra ID',         src: 'assets/entra.png' },
  { name: 'Shopify',          src: 'assets/shopify.avif' },
  { name: 'Veeam',            src: 'assets/veeam.png' },
  { name: 'Acronis',          src: 'assets/Acronis.png' },
  { name: 'Nakivo',           src: 'assets/nakivo.png' },
  { name: 'Railway',          src: 'assets/railway.png' },
];

const PROJECTS = [
  {
    name: 'Arcana',
    tagline: 'Fine Wine & Rare Spirits Specialist',
    status: 'In Progress',
    active: true,
  },
  {
    name: 'Personal Portfolio',
    tagline: 'A personal portfolio website.',
    status: 'Coming Soon',
    active: false,
  },
  {
    name: 'Personal Portfolio + Store',
    tagline: 'A personal portfolio website with a small online store.',
    status: 'Coming Soon',
    active: false,
  },
];

function Marquee() {
  const items = [...TOOLS, ...TOOLS];
  return (
    <div className="wrap max">
      <div className="marquee">
        <div className="marquee-track">
          {items.map((t, i) => (
            <span className="tool" key={`${t.name}-${i}`}>
              <img src={t.src} alt="" loading="lazy" />
              <span>{t.name}</span>
            </span>
          ))}
        </div>
      </div>
    </div>
  );
}

/* ============ CTA ============ */
function CTA({ headline, body }) {
  return (
    <section className="wrap max">
      <div className="cta">
        <div>
          <span className="eyebrow">— Get in touch</span>
          <h2>{headline || <>Let’s make the next step <em>easy.</em></>}</h2>
          <p>{body || `Send through the rough version. A short conversation is usually all it takes to find the sensible way forward.`}</p>
        </div>
        <div className="cta-actions">
          <a className="btn primary" href="mailto:support@relayconsulting.nz">
            support@relayconsulting.nz <ArrowRight />
          </a>
          <a className="btn ghost" href="contact.html">
            Or use the form
          </a>
        </div>
      </div>
    </section>
  );
}

/* ============ FOOTER ============ */
function Footer() {
  return (
    <div className="footer-shell wrap max">
      <footer className="footer">
        <div className="footer-grid">
          <div>
            <a href="index.html" className="nav-brand">
              <LogoMark height={18} />
              <span className="nav-brand-word" style={{ fontSize: 17 }}>Relay</span>
              <span className="nav-brand-sub" style={{ fontSize: 17 }}>Consulting</span>
            </a>
            <p className="footer-tagline">
              Independent technical advice and considered digital support for businesses across New Zealand. Based in Christchurch.
            </p>
          </div>
          <div>
            <h4>Explore</h4>
            <ul>
              <li><a href="work.html">Work</a></li>
              <li><a href="contact.html">Contact</a></li>
            </ul>
          </div>
          <div>
            <h4>About</h4>
            <ul>
              <li><a href="work.html">Approach</a></li>
              <li><a href="privacy.html">Privacy</a></li>
              <li><span>Independent practice</span></li>
            </ul>
          </div>
        </div>

        <div className="bigmark">Relay///</div>

        <div className="footer-bottom">
          <span>© 2026 Relay Consulting Ltd. All rights reserved.</span>
          <span style={{ fontFamily: 'ui-monospace, monospace', fontSize: 11, letterSpacing: '0.08em' }}>
            ŌTAUTAHI · AOTEAROA NZ
          </span>
        </div>
      </footer>
    </div>
  );
}

/* ============ PAGE WRAPPER ============ */
function Page({ active, children }) {
  useScrollReveal();
  usePageTransitions();
  return (
    <>
      <Nav active={active} />
      {children}
      <Footer />
    </>
  );
}

Object.assign(window, {
  Page, Nav, Footer, Marquee, CTA,
  LogoMark, ArrowOut, ArrowRight,
  MagicCard, HeroIllustration, NowPanel,
  SectionDivider, usePageTransitions,
  useScrollReveal,
  StatusPill, TOOLS, PROJECTS,
});
