/* ═══════════════════════════════════════════════════════════
   SHARED — ícones SVG, hooks e constantes reutilizadas
   Nenhum emoji é usado como ícone (regra do briefing).
   ═══════════════════════════════════════════════════════════ */

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

/* ── Links reais em produção ──────────────────────────────── */
const LINKS = {
  cadastro: 'https://sistema.klyvo.app.br/cadastro',
  login: 'https://sistema.klyvo.app.br/login',
  plano: (p) => `https://sistema.klyvo.app.br/cadastro?plano=${p}`,
  whatsapp: 'https://wa.me/5577988749316',
  waDemo:
    'https://wa.me/5577988749316?text=Ol%C3%A1%2C+quero+agendar+uma+demonstra%C3%A7%C3%A3o+do+Klyvo!',
  waInfo:
    'https://wa.me/5577988749316?text=Ol%C3%A1%2C+quero+saber+mais+sobre+o+Klyvo!',
  quemSomos: '/quem-somos',
  privacidade: '/politica-de-privacidade',
  termos: '/termos-de-uso',
};

/* ── Camada de mensuração (mesmos eventos da v1) ────────────
   Sem dados pessoais. Envia pro GA4 (gtag) e, quando presentes,
   os pixels do Meta (fbq) e Google Ads (gtag) já ativos. */
function track(event, params = {}) {
  if (window.gtag) gtag('event', event, params);
}

function trackCta(event, params = {}, e) {
  track(event, params);
  if (window.fbq) {
    e?.preventDefault?.();
    // currentTarget vira null assim que o evento termina de se propagar
    // (comportamento padrão do DOM) — captura o href já aqui, antes do delay.
    const href = e?.currentTarget?.href;
    fbq('track', 'Lead', { content_name: event });
    setTimeout(() => {
      if (href) window.location.href = href;
    }, 250);
  }
}

/* ── Navegação por âncora interna sem sujar a URL ────────────
   scrollIntoView respeita o scroll-margin-top das seções (ver
   styles.css), então o offset da navbar fixa continua funcionando. */
function scrollToSection(href, e) {
  e?.preventDefault?.();
  document.querySelector(href)?.scrollIntoView({ behavior: 'smooth', block: 'start' });
}

/* ── Ícone genérico: recebe `path` e desenha em stroke ───── */
function Icon({ d, size = 24, fill = 'none', strokeWidth = 2, ...rest }) {
  return (
    <svg
      viewBox="0 0 24 24"
      width={size}
      height={size}
      fill={fill}
      stroke="currentColor"
      strokeWidth={strokeWidth}
      strokeLinecap="round"
      strokeLinejoin="round"
      aria-hidden="true"
      {...rest}
    >
      {Array.isArray(d) ? d.map((p, i) => <path key={i} d={p} />) : <path d={d} />}
    </svg>
  );
}

/* ── Paths dos ícones (Lucide-style, traçados à mão) ─────── */
const ICONS = {
  arrowRight: 'M5 12h14M12 5l7 7-7 7',
  calendar: ['M16 2v4M8 2v4M3 10h18', 'M5 4h14a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V6a2 2 0 0 1 2-2z'],
  calendarCheck: ['M16 2v4M8 2v4M3 10h18', 'M5 4h14a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V6a2 2 0 0 1 2-2z', 'm9 16 2 2 4-4'],
  calendarX: ['M16 2v4M8 2v4M3 10h18', 'M5 4h14a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V6a2 2 0 0 1 2-2z', 'm14 14-4 4m0-4 4 4'],
  fileX: ['M15 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7Z', 'M14 2v5h5', 'M9.5 10.5 14 15m0-4.5L9.5 15'],
  fileText: ['M15 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7Z', 'M14 2v5h5', 'M16 13H8M16 17H8M10 9H8'],
  trendDown: ['M22 17 13.5 8.5 8.5 13.5 2 7', 'M16 17h6v-6'],
  tooth: 'M12 2.5c-3.9 0-6.5 2.3-6.5 5.5 0 1.8.6 3.1 1.2 4.6.7 1.7 1 4.3 1.7 6.8.3 1.1 1.8 1.1 2.1 0 .5-1.7.6-3.9 1.5-3.9s1 2.2 1.5 3.9c.3 1.1 1.8 1.1 2.1 0 .7-2.5 1-5.1 1.7-6.8.6-1.5 1.2-2.8 1.2-4.6 0-3.2-2.6-5.5-6.5-5.5z',
  stethoscope: ['M11 2v2M5 2v2', 'M5 3H4a2 2 0 0 0-2 2v4a6 6 0 0 0 12 0V5a2 2 0 0 0-2-2h-1', 'M8 15a6 6 0 0 0 12 0v-3', 'M20 8a2 2 0 1 0 0 4 2 2 0 0 0 0-4z'],
  dollar: ['M12 2v20', 'M17 5H9.5a3.5 3.5 0 0 0 0 7h5a3.5 3.5 0 0 1 0 7H6'],
  message: 'M7.9 20A9 9 0 1 0 4 16.1L2 22Z',
  lock: ['M7 11V7a5 5 0 0 1 10 0v4', 'M5 11h14a2 2 0 0 1 2 2v7a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-7a2 2 0 0 1 2-2z'],
  zap: 'M13 2 3 14h9l-1 8 10-12h-9l1-8z',
  circleX: ['M12 2a10 10 0 1 0 0 20 10 10 0 0 0 0-20z', 'm15 9-6 6m0-6 6 6'],
  link: ['M14.7 6.3a1 1 0 0 0 0 1.4l1.6 1.6a1 1 0 0 0 1.4 0l3.77-3.77a6 6 0 0 1-7.94 7.94l-6.91 6.91a2.12 2.12 0 0 1-3-3l6.91-6.91a6 6 0 0 1 7.94-7.94l-3.76 3.76z'],
  card: ['M21 12V7H5a2 2 0 0 1 0-4h14v4', 'M3 5v14a2 2 0 0 0 2 2h16v-5', 'M18 12a2 2 0 0 0 0 4h4v-4Z'],
  shield: 'M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10z',
  sliders: ['M4 21v-7M4 10V3M12 21v-9M12 8V3M20 21v-5M20 12V3', 'M1 14h6M9 8h6M17 16h6'],
  users: ['M16 21v-2a4 4 0 0 0-4-4H6a4 4 0 0 0-4 4v2', 'M9 3a4 4 0 1 0 0 8 4 4 0 0 0 0-8z', 'M22 21v-2a4 4 0 0 0-3-3.87M16 3.13a4 4 0 0 1 0 7.75'],
  barChart: ['M3 3v18h18', 'M7 16v-4', 'M12 16V8', 'M17 16v-7'],
};

/* ── Logotipo oficial Klyvo (mesmo SVG da v1) ────────────── */
function LogoMark({ className = 'nav-logo-mark' }) {
  return (
    <svg className={className} viewBox="0 0 32 32" fill="none" aria-hidden="true">
      <rect x="5.2" y="4.5" width="6.6" height="23" rx="3.3" fill="#2B6CE0" />
      <path d="M11 15.5 L23 27" stroke="#3B82F6" strokeWidth="6.6" strokeLinecap="round" strokeLinejoin="round" />
      <path d="M11 16.5 L22.5 5.5" stroke="#22BE97" strokeWidth="6.6" strokeLinecap="round" strokeLinejoin="round" />
    </svg>
  );
}

function Logo({ className = '' }) {
  return (
    <a
      href="#topo"
      className={`nav-logo ${className}`.trim()}
      aria-label="Klyvo — página inicial"
      onClick={(e) => scrollToSection('#topo', e)}
    >
      <LogoMark />
      <span>klyvo</span>
    </a>
  );
}

/* ── Hook: reveal com IntersectionObserver ───────────────
   Fallback: se o browser não suportar IO, tudo fica visível. */
function useReveal() {
  useEffect(() => {
    const els = document.querySelectorAll('.reveal:not(.is-visible)');

    if (!('IntersectionObserver' in window)) {
      els.forEach((el) => el.classList.add('is-visible'));
      return;
    }

    const io = new IntersectionObserver(
      (entries) => {
        entries.forEach((entry) => {
          if (entry.isIntersecting) {
            entry.target.classList.add('is-visible');
            io.unobserve(entry.target);
          }
        });
      },
      { threshold: 0.12, rootMargin: '0px 0px -40px 0px' }
    );

    els.forEach((el) => io.observe(el));
    return () => io.disconnect();
  });
}

/* ── Hook: posição de scroll ─────────────────────────────── */
function useScrollY() {
  const [y, setY] = useState(0);

  useEffect(() => {
    let raf = null;
    const onScroll = () => {
      if (raf) return;
      raf = requestAnimationFrame(() => {
        setY(window.scrollY);
        raf = null;
      });
    };
    window.addEventListener('scroll', onScroll, { passive: true });
    onScroll();
    return () => {
      window.removeEventListener('scroll', onScroll);
      if (raf) cancelAnimationFrame(raf);
    };
  }, []);

  return y;
}

/* ── Hook: número que conta/rola até o valor-alvo (sem libs) ──
   Usado no preço dos planos: ao trocar mensal↔anual, o número
   desliza até o novo valor em vez de trocar seco. */
function useAnimatedNumber(target, duration = 480) {
  const [value, setValue] = useState(target);
  const fromRef = useRef(target);
  const rafRef = useRef(null);

  useEffect(() => {
    const from = fromRef.current;
    if (from === target) return;

    const start = performance.now();
    const ease = (t) => 1 - Math.pow(1 - t, 3); // ease-out cubic

    const tick = (now) => {
      const t = Math.min(1, (now - start) / duration);
      const current = from + (target - from) * ease(t);
      setValue(current);
      if (t < 1) {
        rafRef.current = requestAnimationFrame(tick);
      } else {
        fromRef.current = target;
      }
    };

    rafRef.current = requestAnimationFrame(tick);
    return () => cancelAnimationFrame(rafRef.current);
  }, [target, duration]);

  return value;
}

/* ── Confete em canvas puro (sem canvas-confetti) ────────────
   Usado ao trocar pra cobrança Anual no toggle de planos: uma
   explosão curta de partículas a partir do ponto (x, y) em
   coordenadas de viewport (ex: getBoundingClientRect do switch). */
function fireConfetti(x, y) {
  if (window.matchMedia('(prefers-reduced-motion: reduce)').matches) return;

  const canvas = document.createElement('canvas');
  canvas.width = window.innerWidth;
  canvas.height = window.innerHeight;
  Object.assign(canvas.style, {
    position: 'fixed',
    inset: '0',
    zIndex: '9999',
    pointerEvents: 'none',
  });
  document.body.appendChild(canvas);
  const ctx = canvas.getContext('2d');

  const colors = ['#0ea5e9', '#22be97', '#f59e0b', '#6366f1'];
  const count = 50;
  const spreadDeg = 60;
  const particles = Array.from({ length: count }, () => {
    // Leque voltado para cima (ângulo base = -90°), como o confetti original.
    const angle = (-90 + (Math.random() - 0.5) * spreadDeg) * (Math.PI / 180);
    const speed = 12 + Math.random() * 18; // ~startVelocity: 30, com variação
    return {
      x,
      y,
      vx: Math.cos(angle) * speed,
      vy: Math.sin(angle) * speed,
      size: 5 + Math.random() * 4,
      color: colors[Math.floor(Math.random() * colors.length)],
      rotation: Math.random() * 360,
      spin: (Math.random() - 0.5) * 20,
      alpha: 1,
    };
  });

  const gravity = 0.35;
  const decay = 0.94;
  let frame = 0;
  const maxFrames = 90;

  function tick() {
    frame++;
    ctx.clearRect(0, 0, canvas.width, canvas.height);

    particles.forEach((p) => {
      p.vx *= decay;
      p.vy = p.vy * decay + gravity;
      p.x += p.vx;
      p.y += p.vy;
      p.rotation += p.spin;
      p.alpha = Math.max(0, 1 - frame / maxFrames);

      ctx.save();
      ctx.globalAlpha = p.alpha;
      ctx.translate(p.x, p.y);
      ctx.rotate((p.rotation * Math.PI) / 180);
      ctx.fillStyle = p.color;
      ctx.fillRect(-p.size / 2, -p.size / 2, p.size, p.size * 0.6);
      ctx.restore();
    });

    if (frame < maxFrames) {
      requestAnimationFrame(tick);
    } else {
      canvas.remove();
    }
  }

  requestAnimationFrame(tick);
}

Object.assign(window, {
  Icon,
  ICONS,
  LINKS,
  Logo,
  LogoMark,
  track,
  trackCta,
  scrollToSection,
  useReveal,
  useScrollY,
  useAnimatedNumber,
  fireConfetti,
});
