/* Hero da ThetaHealing Intro — React + Framer Motion.
   Cada bloco usa uma técnica diferente do banco de animações
   "Não Codei" (naocodei.com), escolhida para combinar com o que ela
   representa, em vez de repetir o mesmo fade em tudo:

   - tag "Encontro introdutório" → 04 · entrar crescendo (pop com mola)
   - título → BlurText, inspirado nas animações de texto por palavra
   - promessa/CTA final → 02 · subir e aparecer
   - data + modalidade, e as duas tags → 05 · cascata (stagger)
   - botão principal → 10 · brilho que atravessa (loop sutil)
   - selo/logo → 24 · inclinar em 3D (segue o mouse) + entrada em bloco

   Progressive enhancement: o HTML dentro de #heroRoot já vem com o
   conteúdo estático completo (mesmo CTA funcionando) — se algum CDN
   falhar, o visitante ainda vê e consegue clicar em tudo. Este script
   só troca esse conteúdo pela versão animada quando tudo carrega. */

(() => {
  const root = document.getElementById('heroRoot');
  if (!root || !window.React || !window.ReactDOM || !window.Motion) return;

  const { useState, useEffect, useRef, useMemo } = React;
  const { motion } = window.Motion;
  const EASE = [0.16, 1, 0.3, 1];
  const POP_EASE = [0.34, 1.56, 0.64, 1];
  const reduceMotion = window.matchMedia('(prefers-reduced-motion: reduce)').matches;

  function useDelayedShow(delay) {
    const [shown, setShown] = useState(reduceMotion);
    useEffect(() => {
      if (reduceMotion) return;
      const t = setTimeout(() => setShown(true), delay * 1000);
      return () => clearTimeout(t);
    }, []);
    return shown;
  }

  // 02 · Subir e aparecer — desfoque + leve subida, num tempo fixo.
  function Reveal({ el = 'div', className, children, blur = 14, y = 24, delay = 0, ...rest }) {
    const shown = useDelayedShow(delay);
    const Tag = motion[el] || motion.div;
    return (
      <Tag
        className={className}
        initial={reduceMotion ? false : { opacity: 0, filter: `blur(${blur}px)`, y }}
        animate={shown ? { opacity: 1, filter: 'blur(0px)', y: 0 } : { opacity: 0, filter: `blur(${blur}px)`, y }}
        transition={{ duration: 0.8, ease: EASE }}
        {...rest}
      >
        {children}
      </Tag>
    );
  }

  // 04 · Entrar crescendo — escala com uma pequena "mola" no final,
  // boa para selos e etiquetas pequenas.
  function Pop({ el = 'span', className, children, delay = 0 }) {
    const shown = useDelayedShow(delay);
    const Tag = motion[el] || motion.span;
    return (
      <Tag
        className={className}
        initial={reduceMotion ? false : { opacity: 0, scale: 0.7 }}
        animate={shown ? { opacity: 1, scale: 1 } : { opacity: 0, scale: 0.7 }}
        transition={{ duration: 0.55, ease: POP_EASE }}
      >
        {children}
      </Tag>
    );
  }

  // 05 · Cascata — os filhos entram um depois do outro, com um pequeno
  // atraso entre eles (usado na data/modalidade e nas duas tags).
  function Stagger({ el = 'div', className, items, itemEl = 'div', itemClassName, step = 0.09, delay = 0 }) {
    const Tag = motion[el] || motion.div;
    const ItemTag = motion[itemEl] || motion.div;
    return (
      <Tag className={className}>
        {items.map((item, i) => {
          const shown = useDelayedShow(delay + i * step);
          return (
            <ItemTag
              key={i}
              className={typeof itemClassName === 'function' ? itemClassName(item, i) : itemClassName}
              initial={reduceMotion ? false : { opacity: 0, y: 18 }}
              animate={shown ? { opacity: 1, y: 0 } : { opacity: 0, y: 18 }}
              transition={{ duration: 0.6, ease: EASE }}
            >
              {item}
            </ItemTag>
          );
        })}
      </Tag>
    );
  }

  // Título palavra a palavra, com desfoque que vai focando — dispara
  // assim que o bloco entra na tela (na prática, junto do carregamento,
  // já que a hero está sempre visível ao abrir a página).
  function BlurText({ text, className, wordClassName, baseDelay = 0 }) {
    const ref = useRef(null);
    const [visible, setVisible] = useState(reduceMotion);

    useEffect(() => {
      if (reduceMotion) return;
      const elNode = ref.current;
      if (!elNode) return;
      const io = new IntersectionObserver((entries) => {
        entries.forEach((entry) => {
          if (entry.isIntersecting) { setVisible(true); io.unobserve(entry.target); }
        });
      }, { threshold: 0.1 });
      io.observe(elNode);
      return () => io.disconnect();
    }, []);

    const words = useMemo(() => text.split(' '), [text]);

    return (
      <span ref={ref} className={`hero__title-line ${className || ''}`}>
        {words.map((word, i) => (
          <motion.span
            key={word + i}
            className={wordClassName}
            style={{ display: 'inline-block', marginRight: '0.28em' }}
            initial={{ filter: 'blur(10px)', opacity: 0, y: 30 }}
            animate={
              visible
                ? { filter: ['blur(10px)', 'blur(5px)', 'blur(0px)'], opacity: [0, 0.5, 1], y: [30, -4, 0] }
                : {}
            }
            transition={{ duration: 0.7, times: [0, 0.5, 1], ease: 'easeOut', delay: baseDelay + (i * 100) / 1000 }}
          >
            {word}
          </motion.span>
        ))}
      </span>
    );
  }

  // 24 · Inclinar em 3D — o mouse só é medido aqui; quem inclina e
  // suaviza é a transição do CSS (.logo-slot { transition: transform }).
  function useTilt(force = 10) {
    const ref = useRef(null);
    useEffect(() => {
      if (reduceMotion) return;
      const el = ref.current;
      if (!el) return;
      const onMove = (ev) => {
        const r = el.getBoundingClientRect();
        const x = (ev.clientX - r.left) / r.width - 0.5;
        const y = (ev.clientY - r.top) / r.height - 0.5;
        el.style.transform = `perspective(900px) rotateY(${x * force}deg) rotateX(${-y * force}deg)`;
      };
      const onLeave = () => { el.style.transform = ''; };
      el.addEventListener('mousemove', onMove);
      el.addEventListener('mouseleave', onLeave);
      return () => {
        el.removeEventListener('mousemove', onMove);
        el.removeEventListener('mouseleave', onLeave);
      };
    }, []);
    return ref;
  }

  function LogoVisual({ delay }) {
    const [missing, setMissing] = useState(false);
    const tiltRef = useTilt(9);
    return (
      <Reveal el="div" className="hero__visual" blur={18} y={16} delay={delay}>
        <div ref={tiltRef} className={'logo-slot fx-tilt' + (missing ? ' is-missing' : '')}>
          <div className="logo-glow" aria-hidden="true"></div>
          <img
            src="assets/thetahealing-intro-logo.png"
            alt="Selo ThetaHealing Intro"
            onError={() => setMissing(true)}
          />
          <p className="logo-slot__hint">
            Coloque o arquivo em<br /><code>assets/thetahealing-intro-logo.png</code>
          </p>
        </div>
      </Reveal>
    );
  }

  function ArrowIcon() {
    return (
      <svg width="18" height="18" viewBox="0 0 24 24" fill="none" aria-hidden="true">
        <path d="M5 12h14M13 6l6 6-6 6" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" />
      </svg>
    );
  }

  function Hero() {
    return (
      <React.Fragment>
        <div className="hero__content">
          <Pop el="span" className="tag tag--green" delay={0.1}>
            Encontro introdutório
          </Pop>

          <h1 className="hero__title">
            <BlurText text="ThetaHealing" baseDelay={0.2} />
            <BlurText text="Intro" wordClassName="hero__title-em" baseDelay={0.38} />
          </h1>

          <Reveal el="p" className="hero__promise" delay={0.55}>
            3 horas para conhecer uma nova forma de olhar para suas crenças, padrões e escolhas.
          </Reveal>

          <Stagger
            className="hero__meta"
            delay={0.7}
            items={[
              <p className="hero__date" key="date">
                <span className="hero__date-num">19/09</span> · das 9h às 12h
              </p>,
              <p className="hero__mode" key="mode">Ao vivo e online pelo Zoom</p>,
            ]}
          />

          <Stagger
            className="hero__tags"
            delay={0.85}
            itemEl="span"
            itemClassName={(_, i) => 'tag ' + (i === 0 ? 'tag--violet' : 'tag--pink')}
            items={['Gratuito', 'Sem pré-requisito']}
          />

          <Reveal
            el="a"
            className="btn btn--cta fx-shine"
            delay={1}
            href="https://docs.google.com/forms/d/e/1FAIpQLSdjqFvhrr96mKq0qgZXFBcWKBLNxwzFhoCzdnav1R8O7RePcg/viewform"
            target="_blank"
            rel="noopener"
          >
            <span>Quero participar</span>
            <ArrowIcon />
          </Reveal>

          <Reveal el="p" className="hero__instructors" delay={1.15}>
            Com Fellipe e Djalma<br />Instrutores de ThetaHealing há 9 anos
          </Reveal>
        </div>

        <LogoVisual delay={0.1} />
      </React.Fragment>
    );
  }

  ReactDOM.render(<Hero />, root);
})();
