// Syntari v3 — Landing (EN, unified)
// "Silent+" — Silent Engineering base, tech savvy interactions, Apple precision.

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

/* ─── Site-wide constants ─── */
const CAL_URL = 'https://cal.com/victor-souza-c3vkvi/syntari-tech-discovery';
const EMAIL   = 'info@syntari.com';

/* ─────────────────────────────────────────────
   Dynamic date helpers
   All copy about "this quarter / next quarter"
   is derived from new Date() so we never lie.
   ───────────────────────────────────────────── */

function getQuarterCopy() {
  const now = new Date();
  const month = now.getMonth(); // 0-11
  const year  = now.getFullYear();

  // Quarter start month indexes: 0 (Q1), 3 (Q2), 6 (Q3), 9 (Q4)
  const qStart = Math.floor(month / 3) * 3;
  const qNum   = qStart / 3 + 1;
  const qMonths = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'];

  // Next quarter
  const nextQStart = (qStart + 3) % 12;
  const nextQYear  = qStart === 9 ? year + 1 : year;

  // Within this quarter, compute a plausible "kicks off in" month
  // for the last open slot: the middle month of the quarter
  const kickoffMonthIdx = qStart + 1; // second month of current quarter
  const kickoffMonth = qMonths[kickoffMonthIdx % 12];

  // Discovery for next cohort opens one month before next quarter starts
  const discoveryMonthIdx = (nextQStart - 1 + 12) % 12;
  const discoveryMonth    = qMonths[discoveryMonthIdx];

  return {
    qLabel:         `Q${qNum} ${year}`,
    quarterLabel:   `Q${qNum} ${year}`,
    nextQLabel:     `Q${(qNum % 4) + 1} ${nextQYear}`,
    taking:         `Taking 2 projects this quarter`,
    kickoffCopy:    `Kicks off in ${kickoffMonth}`,
    nextCohortCopy: `Next cohort opens for discovery in ${discoveryMonth}.`,
  };
}

/* ─────────────────────────────────────────────
   Building blocks
   ───────────────────────────────────────────── */

function useReveal(ref, { threshold = 0.2 } = {}) {
  useEffect(() => {
    const el = ref.current;
    if (!el) return;
    const io = new IntersectionObserver((entries) => {
      entries.forEach(e => { if (e.isIntersecting) { e.target.classList.add('in'); io.unobserve(e.target); } });
    }, { threshold });
    el.querySelectorAll('[data-reveal]').forEach(n => io.observe(n));
    return () => io.disconnect();
  }, [ref, threshold]);
}

function HoverButton({ children, variant = 'primary', onClick, as = 'button', href }) {
  const [circles, setCircles] = useState([]);
  const idRef = useRef(0);
  const palette = useMemo(() => [
    'oklch(0.82 0.13 40)',   // amber
    'oklch(0.85 0.15 130)',  // lime
    'oklch(0.75 0.14 240)',  // azure
    'oklch(0.78 0.16 350)',  // magenta
  ], []);
  const onEnter = (e) => {
    const r = e.currentTarget.getBoundingClientRect();
    const x = e.clientX - r.left, y = e.clientY - r.top;
    const id = ++idRef.current;
    const color = palette[(id - 1) % palette.length];
    setCircles(c => [...c, { id, x, y, color, phase: 'in' }]);
    requestAnimationFrame(() => requestAnimationFrame(() => {
      setCircles(c => c.map(cc => cc.id === id ? { ...cc, phase: 'mid' } : cc));
    }));
  };
  const onLeave = (e) => {
    const r = e.currentTarget.getBoundingClientRect();
    const x = e.clientX - r.left, y = e.clientY - r.top;
    setCircles(c => c.map(cc => ({ ...cc, x, y, phase: 'out' })));
    setTimeout(() => setCircles([]), 1000);
  };
  const Tag = as;
  const props = as === 'a' ? { href, onClick } : { onClick };
  if (variant === 'ghost') {
    return <button className="ghost-btn" onClick={onClick}>{children}</button>;
  }
  return (
    <Tag className="hover-btn" onMouseEnter={onEnter} onMouseLeave={onLeave} {...props}>
      <span className="label">{children}</span>
      {circles.map(c => (
        <span key={c.id} className={`circle ${c.phase === 'mid' ? 'in' : c.phase === 'out' ? 'out' : ''}`}
          style={{ left: c.x, top: c.y, background: c.color }} />
      ))}
    </Tag>
  );
}

function TiltCard({ children, className = '', maxTilt = 6, style }) {
  const ref = useRef();
  const onMove = (e) => {
    const el = ref.current; if (!el) return;
    const r = el.getBoundingClientRect();
    const px = (e.clientX - r.left) / r.width;
    const py = (e.clientY - r.top) / r.height;
    const rx = (py - 0.5) * -maxTilt;
    const ry = (px - 0.5) *  maxTilt;
    el.style.setProperty('--sx', `${px * 100}%`);
    el.style.setProperty('--sy', `${py * 100}%`);
    el.querySelector('.tilt-inner').style.transform = `rotateX(${rx}deg) rotateY(${ry}deg)`;
  };
  const onLeave = () => {
    const el = ref.current; if (!el) return;
    el.querySelector('.tilt-inner').style.transform = 'rotateX(0) rotateY(0)';
  };
  return (
    <div ref={ref} className={`tilt-card ${className}`} style={style} onMouseMove={onMove} onMouseLeave={onLeave}>
      <div className="tilt-inner">
        <span className="spot" />
        {children}
      </div>
    </div>
  );
}

/* ─────────────────────────────────────────────
   Dot Globe — pure SVG, rotating
   ───────────────────────────────────────────── */

function DotGlobe({ size = 720, rings = 14, color = 'rgba(255,255,255,0.32)' }) {
  // Generate points on a sphere — Fibonacci lattice, then project.
  const points = useMemo(() => {
    const n = 760;
    const pts = [];
    const golden = Math.PI * (3 - Math.sqrt(5));
    for (let i = 0; i < n; i++) {
      const y = 1 - (i / (n - 1)) * 2;
      const radius = Math.sqrt(1 - y * y);
      const theta = golden * i;
      const x = Math.cos(theta) * radius;
      const z = Math.sin(theta) * radius;
      pts.push({ x, y, z });
    }
    return pts;
  }, []);

  const [t, setT] = useState(0);
  useEffect(() => {
    let raf, start = performance.now();
    const tick = (now) => {
      setT((now - start) / 1000);
      raf = requestAnimationFrame(tick);
    };
    raf = requestAnimationFrame(tick);
    return () => cancelAnimationFrame(raf);
  }, []);

  const r = size / 2 - 8;
  const yaw = t * 0.12;
  const pitch = -0.35;
  const cy = Math.cos(pitch), sy_ = Math.sin(pitch);
  const ca = Math.cos(yaw),   sa = Math.sin(yaw);

  return (
    <svg width={size} height={size} viewBox={`0 0 ${size} ${size}`} style={{ display: 'block' }}>
      <defs>
        <radialGradient id="globeGlow" cx="50%" cy="50%" r="50%">
          <stop offset="0%" stopColor="oklch(0.82 0.13 40)" stopOpacity="0.22" />
          <stop offset="60%" stopColor="oklch(0.82 0.13 40)" stopOpacity="0.03" />
          <stop offset="100%" stopColor="oklch(0.82 0.13 40)" stopOpacity="0" />
        </radialGradient>
        <radialGradient id="globeCore" cx="50%" cy="50%" r="50%">
          <stop offset="0%" stopColor="#08080a" />
          <stop offset="85%" stopColor="#08080a" stopOpacity="0" />
        </radialGradient>
      </defs>
      <circle cx={size/2} cy={size/2} r={r + 60} fill="url(#globeGlow)" />
      <circle cx={size/2} cy={size/2} r={r - 2} fill="url(#globeCore)" />
      {/* Orbit ring */}
      <ellipse cx={size/2} cy={size/2} rx={r} ry={r * 0.28} fill="none" stroke="rgba(255,255,255,0.06)" strokeWidth="1" />
      <g>
        {points.map((p, i) => {
          // yaw around y
          let x = p.x * ca - p.z * sa;
          let z = p.x * sa + p.z * ca;
          let y = p.y;
          // pitch around x
          const y2 = y * cy - z * sy_;
          const z2 = y * sy_ + z * cy;
          y = y2; z = z2;
          if (z < -0.1) return null; // cull backside
          const depth = (z + 1) / 2; // 0..1
          const rad = 0.9 + depth * 1.6;
          const op = 0.15 + depth * 0.55;
          const cx = size / 2 + x * r;
          const cyp = size / 2 + y * r;
          return <circle key={i} cx={cx} cy={cyp} r={rad} fill={color} opacity={op} />;
        })}
      </g>
    </svg>
  );
}

/* ─────────────────────────────────────────────
   Nav
   ───────────────────────────────────────────── */

function Nav() {
  const [scrolled, setScrolled] = useState(false);
  const quarterCopy = getQuarterCopy();
  useEffect(() => {
    const onScroll = () => setScrolled(window.scrollY > 12);
    window.addEventListener('scroll', onScroll);
    return () => window.removeEventListener('scroll', onScroll);
  }, []);
  return (
    <nav style={{
      position: 'fixed', top: 0, left: 0, right: 0, zIndex: 50,
      padding: scrolled ? '16px 40px' : '26px 40px',
      display: 'flex', alignItems: 'center', justifyContent: 'space-between',
      background: scrolled ? 'rgba(8,8,10,0.72)' : 'transparent',
      backdropFilter: scrolled ? 'blur(18px) saturate(140%)' : 'none',
      WebkitBackdropFilter: scrolled ? 'blur(18px) saturate(140%)' : 'none',
      borderBottom: scrolled ? '1px solid var(--line)' : '1px solid transparent',
      transition: 'padding .3s ease, background .3s ease, border-color .3s ease',
    }}>
      <a href="#" style={{ display: 'flex', alignItems: 'center', gap: 12 }}>
        <span style={{ fontSize: 17, fontWeight: 500, letterSpacing: '-0.015em' }}>Syntari</span>
      </a>
      <div style={{ display: 'flex', gap: 36, fontSize: 14, color: 'var(--fg-muted)' }}>
        <a href="#approach" className="nav-link">Approach</a>
        <a href="#systems"  className="nav-link">Systems</a>
        <a href="#process"  className="nav-link">Process</a>
        <a href="#slots"    className="nav-link">Availability</a>
      </div>
      <div style={{ display: 'flex', alignItems: 'center', gap: 20 }}>
        <span style={{ fontSize: 13, color: 'var(--fg-muted)' }}>
          {quarterCopy.taking}
        </span>
        <HoverButton as="a" href={CAL_URL}>Book a call</HoverButton>
      </div>
    </nav>
  );
}

/* ─────────────────────────────────────────────
   Hero
   ───────────────────────────────────────────── */

function Hero() {
  const ref = useRef();
  useReveal(ref);
  return (
    <section ref={ref} style={{
      position: 'relative',
      minHeight: '100vh',
      padding: '200px 48px 140px',
      display: 'flex',
      alignItems: 'center',
      overflow: 'hidden',
    }}>
      {/* Globe — offset right, not dead-center */}
      <div style={{ position: 'absolute', right: '-180px', top: '50%', transform: 'translateY(-50%)', opacity: 0.85 }}>
        <div data-reveal className="reveal">
          <DotGlobe size={820} />
        </div>
      </div>
      {/* A single, quiet halo */}
      <div className="halo" style={{ width: 520, height: 520, right: '5%', top: '20%', background: 'oklch(0.82 0.13 40 / 0.14)' }} />

      {/* Content — left aligned, editorial */}
      <div style={{ position: 'relative', zIndex: 2, maxWidth: 1400, width: '100%', margin: '0 auto' }}>
        <div style={{ maxWidth: 880 }}>
          <h1 data-reveal className="reveal-up" style={{
            fontSize: 'clamp(48px, 6.6vw, 104px)',
            lineHeight: 1.0,
            letterSpacing: '-0.04em',
            fontWeight: 300,
            margin: '0 0 44px',
            textWrap: 'balance',
          }}>
            Growth, product, and engineering have collapsed <span className="serif" style={{ fontWeight: 400 }}>into one role.</span> We run it for you.
          </h1>

          <p data-reveal className="reveal-up" style={{
            fontSize: 20,
            lineHeight: 1.55,
            color: 'var(--fg-muted)',
            maxWidth: 560,
            margin: '0 0 56px',
            textWrap: 'pretty',
          }}>
            Ads, landing pages, AI agents, and the wiring behind them. We build it all as one system,
            judged by the new revenue it brings in.
          </p>

          <div data-reveal className="reveal-up" style={{ display: 'flex', gap: 14, alignItems: 'center' }}>
            <HoverButton as="a" href={CAL_URL}>Book a discovery call</HoverButton>
            <a href="#systems" style={{ fontSize: 14, color: 'var(--fg-muted)', display: 'inline-flex', alignItems: 'center', gap: 8, padding: '15px 8px' }}>
              See what we build <span>→</span>
            </a>
          </div>
        </div>
      </div>

      {/* Quiet scroll cue */}
      <div style={{
        position: 'absolute', bottom: 40, left: 48,
        display: 'flex', alignItems: 'center', gap: 12,
        color: 'var(--fg-dim)', fontSize: 12,
      }}>
        <span style={{ width: 28, height: 1, background: 'var(--fg-faint)' }} />
        <span>Scroll</span>
      </div>
    </section>
  );
}

Object.assign(window, { HoverButton, TiltCard, DotGlobe, Nav, Hero, useReveal, getQuarterCopy, CAL_URL, EMAIL });
