// Plenitude — Hero with orbiting mandala
const { useState, useEffect, useRef, useMemo } = React;

/* ---------- math helpers ---------- */
const clamp = (v, lo = 0, hi = 1) => Math.max(lo, Math.min(hi, v));
const lerp  = (a, b, t) => a + (b - a) * t;
const range = (s, s0, s1) => clamp((s - s0) / Math.max(1e-6, s1 - s0));
const easeOutCubic = t => 1 - Math.pow(1 - t, 3);
const easeInCubic  = t => t * t * t;
const easeInOutCubic = t => t < .5 ? 4*t*t*t : 1 - Math.pow(-2*t+2, 3)/2;
const easeOutQuart = t => 1 - Math.pow(1 - t, 4);
const easeInOutQuart = t => t < .5 ? 8*t*t*t*t : 1 - Math.pow(-2*t+2, 4)/2;

/* ---------- Hooks ---------- */
function useScrollProgress(hostRef) {
  const [p, setP] = useState(0);
  useEffect(() => {
    const update = () => {
      const el = hostRef.current;
      if (!el) return;
      const rect = el.getBoundingClientRect();
      const total = el.offsetHeight - window.innerHeight;
      const scrolled = -rect.top;
      const v = clamp(scrolled / Math.max(1, total));
      setP(v);
    };
    update();
    window.addEventListener('scroll', update, { passive: true });
    window.addEventListener('resize', update);
    return () => {
      window.removeEventListener('scroll', update);
      window.removeEventListener('resize', update);
    };
  }, []);
  return p;
}

function useScrollY() {
  const [y, setY] = useState(0);
  useEffect(() => {
    const onScroll = () => setY(window.scrollY);
    window.addEventListener('scroll', onScroll, { passive: true });
    onScroll();
    return () => window.removeEventListener('scroll', onScroll);
  }, []);
  return y;
}

function useReveal() {
  useEffect(() => {
    const els = document.querySelectorAll('.reveal');
    const io = new IntersectionObserver((entries) => {
      entries.forEach(e => { if (e.isIntersecting) e.target.classList.add('in'); });
    }, { threshold: 0.15 });
    els.forEach(el => io.observe(el));
    return () => io.disconnect();
  });
}

/* ---------- Top Nav ---------- */
function TopNav({ active, onNav, hidden }) {
  const y = useScrollY();
  const links = [
    { id: 'about',       label: 'Quem somos' },
    { id: 'therapies',   label: 'Terapias' },
    { id: 'schedule',    label: 'Cronograma' },
    { id: 'therapists',  label: 'Terapeutas' },
    { id: 'courses',     label: 'Cursos' },
    { id: 'blog',        label: 'Blog', href: 'https://www.plenitudeblog.com/' },
  ];
  return (
    <nav className={`nav ${y > 80 ? 'scrolled' : ''} ${hidden ? 'invisible' : ''}`}>
      <div style={{display:'flex', alignItems:'center', gap: 12, cursor:'pointer'}} onClick={() => onNav('top')}>
        <div className="nav-mark" />
        <div className="nav-word">PLEN<span className="i-orange">I</span>TUDE</div>
      </div>
      <div className="nav-links">
        {links.map(l =>
          l.href
            ? <a key={l.id} className="nav-link" href={l.href} target="_blank" rel="noopener noreferrer">{l.label}</a>
            : <span key={l.id} className={`nav-link ${active === l.id ? 'active' : ''}`} onClick={() => onNav(l.id)}>{l.label}</span>
        )}
      </div>
      <a className="btn-primary" href="https://wa.me/5561984222929" target="_blank" rel="noopener noreferrer">Agendar</a>
    </nav>
  );
}

/* ---------- Particle field — sparkles trailing the orbit ---------- */
function ParticleField({ progress, mandalaX, mandalaY }) {
  const particles = useMemo(() => {
    const list = [];
    const N = 22;
    for (let i = 0; i < N; i++) {
      const angle = (i / N) * Math.PI * 2 + (i * 0.13);
      const distance = 80 + Math.random() * 220;
      const size = 4 + Math.random() * 14;
      const delay = Math.random() * 0.4;
      const isOrange = Math.random() > 0.3;
      const ring = Math.random() > 0.6;
      list.push({ angle, distance, size, delay, isOrange, ring, i });
    }
    return list;
  }, []);

  // Particles activate during the orbit (0.05 → 0.85)
  const local = range(progress, 0.05, 0.85);
  if (local <= 0) return null;

  return (
    <div className="particle-field" aria-hidden="true">
      {particles.map(p => {
        const t = clamp((local - p.delay) / Math.max(.05, 1 - p.delay));
        const eased = easeOutCubic(t);
        // particles emit FROM the moving mandala position
        const x = mandalaX + Math.cos(p.angle + local * 6) * p.distance * eased;
        const y = mandalaY + Math.sin(p.angle + local * 6) * p.distance * eased;
        const opacity = (1 - eased) * 0.7;
        const scale = lerp(0.3, 1.1, eased);
        const color = p.isOrange ? '#FF9E1F' : '#3EF7B9';
        const style = p.ring
          ? { background: 'transparent', border: `1.5px solid ${color}` }
          : { background: color };
        return (
          <div key={p.i}
            className="particle"
            style={{
              ...style,
              width: p.size,
              height: p.size,
              left: `calc(50% - ${p.size/2}px)`,
              top:  `calc(50% - ${p.size/2}px)`,
              transform: `translate(${x}px, ${y}px) scale(${scale})`,
              opacity,
            }}
          />
        );
      })}
    </div>
  );
}

/* ---------- Hero stage with the orbiting mandala ---------- */
function HeroStage({ progress }) {
  /*
    CHOREOGRAPHY (single continuous orbit, 0 → 1):

    Phase A [0.00 – 0.10]  Vertical logo composed: mandala SITS ON TOP of "PLENITUDE" wordmark.
                           Mandala is centered on top, wordmark below. Subtle breathing.

    Phase B [0.10 – 0.45]  Mandala LIFTS off the wordmark and begins ORBITING the page —
                           a circular arc going UP-RIGHT → RIGHT → DOWN-RIGHT, while
                           continuously rotating around its own center. Wordmark holds
                           a beat, then begins fading + drifting down.

    Phase C [0.45 – 0.75]  Orbit continues DOWN-LEFT → LEFT → UP-LEFT, completing the
                           circle. Hero copy ("A biografia do eu") fades in CENTER as the
                           wordmark dissolves. Mandala scale grows toward the apex of orbit.

    Phase D [0.75 – 1.00]  Mandala completes orbit coming back toward TOP, then drifts up
                           and OUT of frame as the rest of the page (Quem Somos) appears.
  */

  const vw = typeof window !== 'undefined' ? window.innerWidth : 1440;
  const vh = typeof window !== 'undefined' ? window.innerHeight : 900;
  const isMobile = vw < 720;

  // Measure hero-copy so the mandala lands precisely above the text on every screen
  const copyRef = useRef(null);
  const [dynamicLandY, setDynamicLandY] = useState(isMobile ? -Math.round(vh * 0.22) : -Math.round(vh * 0.32));
  useEffect(() => {
    const compute = () => {
      const copyEl = copyRef.current;
      if (!copyEl) return;
      // hero-copy has inset:0 so offsetHeight = full viewport — measure content span instead
      const children = Array.from(copyEl.children);
      if (!children.length) return;
      const firstRect = children[0].getBoundingClientRect();
      const lastRect  = children[children.length - 1].getBoundingClientRect();
      const contentH  = lastRect.bottom - firstRect.top;
      const stageEl   = copyEl.closest('.hero-stage');
      const mandalaEl = stageEl && stageEl.querySelector('.logo-mandala');
      const mandalaW  = mandalaEl ? mandalaEl.offsetWidth : (window.innerWidth < 720 ? 165 : 290);
      setDynamicLandY(80 - contentH / 2 - mandalaW * 0.45 / 2 - 24);
    };
    const id = setTimeout(compute, 150);
    window.addEventListener('resize', compute);
    return () => { clearTimeout(id); window.removeEventListener('resize', compute); };
  }, []);

  // Orbit geometry — tighter on mobile so mandala stays on-screen
  const orbitR = Math.min(vw, vh) * (isMobile ? 0.20 : 0.32);

  // Vertical-stack offset: in Phase A the mandala center sits ABOVE the wordmark center.
  // On mobile use vh fractions so the two elements stay close together.
  const stackMandalaY = isMobile ? -Math.round(vh * 0.15) : -210;
  const stackWordY    = isMobile ?  Math.round(vh * 0.09) :  120;

  /* ---- MANDALA ORBIT ---- */
  // The orbit is a full revolution around the composition center.
  // We start at the TOP of the orbit (angle = -π/2, i.e. 12 o'clock), where the mandala
  // sits naturally on top of the wordmark.
  // Phase A: stays at the top (small bob), Phase B/C/D: orbits 360° clockwise then exits up.

  // Lift-off: 0 → 1 across phase A→B boundary
  const liftP = range(progress, 0.06, 0.18);
  const liftEase = easeInOutCubic(liftP);

  // Orbit angle: starts at -90° (top), revolves a full 360° between progress 0.10 → 0.85.
  const orbitProgress = range(progress, 0.10, 0.85);
  // Use ease-in-out so orbit feels organic
  const orbitEased = easeInOutQuart(orbitProgress);
  const baseAngle = -Math.PI / 2; // top
  const angle = baseAngle + orbitEased * Math.PI * 2; // full revolution

  // Orbit radius grows during lift-off, then breathes slightly as it goes around
  const orbitRadius = lerp(0, orbitR, liftEase) * (1 + Math.sin(orbitProgress * Math.PI) * 0.08);

  // Mandala position = stackMandalaY anchor + orbit offset
  // When liftEase=0 → mandala at (0, stackMandalaY). When liftEase=1 → orbiting around (0, 0).
  // So composition center pulls UP from "vertical-logo origin" to the screen center as we lift.
  const compCenterY = lerp(stackMandalaY, 0, liftEase); // composition center where the mandala orbits around
  // Wait — simpler: keep a single composition center, and at rest mandala is at top of orbit (radius=0 → it's at center). That doesn't match the "top of wordmark" feel.
  // Better: the mandala's resting position == center + (0, stackMandalaY). The orbit is around that ANCHOR, not around center. We'll lift it differently.

  // Re-approach: the mandala's anchor is a single point. At rest it sits at (0, stackMandalaY).
  // During orbit it revolves around the screen CENTER (0, 0) with radius orbitR.
  // The "lift" interpolates the position from the rest spot → onto the orbit ring at angle=-π/2.
  const restX = 0, restY = stackMandalaY;
  const orbitX = Math.cos(angle) * orbitR;
  const orbitY = Math.sin(angle) * orbitR;
  let mandalaX = lerp(restX, orbitX, liftEase);
  let mandalaY = lerp(restY, orbitY, liftEase);

  // Phase D landing: after progress 0.85, mandala settles at TOP-CENTER above the headline
  // and stays there (does NOT exit). It also stops rotating.
  const landP = range(progress, 0.78, 0.92);
  const landEase = easeInOutCubic(landP);
  // target landing position: top-center, just above where the hero headline sits
  const landX = 0;
  const landY = dynamicLandY;
  mandalaX = lerp(mandalaX, landX, landEase);
  mandalaY = lerp(mandalaY, landY, landEase);

  // Mandala self-rotation: spins through orbit, then settles to 0 during landing
  const spinAngle = orbitProgress * 540 + progress * 90;
  const mandalaRot = lerp(spinAngle, 0, landEase);
  // Mandala scale: small swell during orbit, settles to a smaller size when landed above title
  const orbitScale = lerp(1, 1.15, Math.abs(Math.sin(orbitProgress * Math.PI)));
  const mandalaScale = lerp(orbitScale, 0.45, landEase);
  // Stays fully opaque (no exit fade)
  const mandalaOpacity = 1;

  /* ---- WORDMARK ---- */
  // Sits at composition center + stackWordY at rest; remains there briefly then fades.
  const wordX = 0;
  const wordY = stackWordY + lerp(0, 60, range(progress, 0.18, 0.4));
  const wordOpacity = lerp(1, 0, easeInCubic(range(progress, 0.18, 0.42)));
  const wordScale = lerp(1, 0.92, range(progress, 0.18, 0.42));

  /* ---- TAGLINE ---- */
  // Sits BELOW the wordmark in phase A, fades with wordmark
  const taglineY = stackWordY + 110;
  const taglineOpacity = lerp(0, 1, range(progress, 0.0, 0.06)) *
                         lerp(1, 0, range(progress, 0.16, 0.32));

  /* ---- HERO COPY (eyebrow + headline + lead + CTAs) ---- */
  // Comes in once the wordmark has dissolved, anchored at center
  const copyP = range(progress, 0.42, 0.70);
  const copyEase = easeOutCubic(copyP);
  const copyOpacity = copyEase;
  // settle the copy with a small downward offset so the mandala sits above it cleanly
  const copyTransY = lerp(40, 80, copyEase);
  // And fades out gently as we approach the page exit (0.96 → 1)
  const copyExit = lerp(1, 0.0, range(progress, 0.96, 1.0));

  /* ---- GLOWS: drift with mandala, two layers ---- */
  const glowOrangeX = mandalaX * 0.6;
  const glowOrangeY = mandalaY * 0.6;
  const glowGreenX = -mandalaX * 0.4;
  const glowGreenY = -mandalaY * 0.4 + lerp(0, 100, progress);
  const glowGreenOpacity = lerp(0.0, 0.7, range(progress, 0.2, 0.7));

  /* ---- ORBIT TRAIL: faint dashed ring that materializes during the orbit ---- */
  const trailOpacity = lerp(0, .55, range(progress, 0.12, 0.3)) *
                       lerp(1, 0, range(progress, 0.78, 0.95));
  const trailRotate = orbitProgress * 90;
  const trailDiameter = orbitR * 2;

  /* ---- Scroll cue ---- */
  const cueOpacity = lerp(1, 0, range(progress, 0, 0.06));

  return (
    <div className="hero-stage">
      {/* Glows */}
      <div className="hero-glow"
        style={{ transform: `translate(calc(-50% + ${glowOrangeX}px), calc(-50% + ${glowOrangeY}px))` }} />
      <div className="hero-glow green"
        style={{
          transform: `translate(calc(-50% + ${glowGreenX}px), calc(-50% + ${glowGreenY}px))`,
          opacity: glowGreenOpacity
        }} />

      {/* Orbit trail ring */}
      <div className="orbit-trail-ring"
        style={{
          width: trailDiameter,
          height: trailDiameter,
          opacity: trailOpacity,
          transform: `translate(-50%, -50%) rotate(${trailRotate}deg)`
        }} />

      {/* Particles emitting from mandala */}
      <ParticleField progress={progress} mandalaX={mandalaX} mandalaY={mandalaY} />

      {/* MANDALA — orbits */}
      <div className="logo-mandala"
        style={{
          transform: `translate(calc(-50% + ${mandalaX}px), calc(-50% + ${mandalaY}px)) rotate(${mandalaRot}deg) scale(${mandalaScale})`,
          opacity: mandalaOpacity,
        }}>
        <img src="assets/mandala.png" alt="" draggable="false" />
      </div>

      {/* WORDMARK — stays put then fades */}
      <div className="logo-word"
        style={{
          transform: `translate(calc(-50% + ${wordX}px), calc(-50% + ${wordY}px)) scale(${wordScale})`,
          opacity: wordOpacity,
        }}>
        <img src="assets/logo-horizontal-no-mandala.png" alt="Plenitude" draggable="false" />
      </div>

      {/* Tagline */}
      <div className="logo-tagline"
        style={{
          left: '50%',
          top: `calc(50% + ${taglineY}px)`,
          transform: `translateX(-50%)`,
          opacity: taglineOpacity,
        }}>
        Autodescobrimento — uma palavra. Uma vida.
      </div>

      {/* Hero copy */}
      <div className="hero-copy" ref={copyRef}
        style={{
          opacity: copyOpacity * copyExit,
          transform: `translateY(${copyTransY}px)`,
          pointerEvents: copyOpacity > 0.5 ? 'auto' : 'none'
        }}>
        <div className="hero-eyebrow">— Plenitude —</div>
        <h1 className="hero-headline">
          A biografia<br/>
          <span className="em-italic">do</span> <span className="accent">eu</span>
        </h1>
        <p className="hero-lead">
          Um espaço dedicado ao bem-estar emocional e ao desenvolvimento pessoal.
          Terapias, cursos e encontros conduzidos com escuta atenta — para que você
          possa, no seu tempo, voltar para você.
        </p>
        <div className="hero-actions">
          <a className="btn-primary" style={{padding:'18px 32px', fontSize:'13px'}}
            href="https://wa.me/5561984222929" target="_blank" rel="noopener noreferrer">
            Agendar sessão SPOT
          </a>
          <button className="btn-outline" onClick={() => { const el = document.getElementById('therapies'); if (el) window.scrollTo({ top: el.offsetTop - 60, behavior: 'smooth' }); }}>Conhecer terapias</button>
        </div>
      </div>

      {/* Scroll cue */}
      <div className="scroll-cue" style={{ opacity: cueOpacity }}>
        <span>Role</span>
        <div className="line" />
      </div>
    </div>
  );
}

/* ---------- Phase pill ---------- */
function PhasePill({ progress, visible }) {
  const phase = progress < 0.10 ? 0 : progress < 0.45 ? 1 : progress < 0.78 ? 2 : 3;
  const labels = ['Marca', 'Em órbita', 'Eu', 'Início'];
  return (
    <div className="phase-pill" style={{ opacity: visible ? 1 : 0, pointerEvents: visible ? 'auto' : 'none' }}>
      <span>{labels[phase]}</span>
      <div className="dots">
        {[0,1,2,3].map(i => <div key={i} className={`dot ${i === phase ? 'active' : ''}`} />)}
      </div>
    </div>
  );
}

/* ---------- Progress bar ---------- */
function ProgressBar() {
  const [p, setP] = useState(0);
  useEffect(() => {
    const onScroll = () => {
      const total = document.documentElement.scrollHeight - window.innerHeight;
      setP(clamp(window.scrollY / Math.max(1, total)));
    };
    onScroll();
    window.addEventListener('scroll', onScroll, { passive: true });
    return () => window.removeEventListener('scroll', onScroll);
  }, []);
  return (
    <div className="progress-rail">
      <div className="progress-fill" style={{ transform: `scaleX(${p})` }} />
    </div>
  );
}

Object.assign(window, {
  useScrollProgress, useScrollY, useReveal,
  TopNav, HeroStage, PhasePill, ProgressBar, ParticleField,
  clamp, lerp, range, easeOutCubic, easeInOutCubic
});
