/* global React */
const { useState, useEffect, useRef } = React;

/* ─────────────────────────────────────────────────────────
   useMouseParallax — returns {x, y} in range -1..1 based on
   cursor position relative to the element.
   ────────────────────────────────────────────────────── */
function useMouseParallax(ref, strength = 1) {
  const [p, setP] = useState({ x: 0, y: 0 });
  useEffect(() => {
    const el = ref.current;
    if (!el) return;
    const onMove = (e) => {
      const r = el.getBoundingClientRect();
      const cx = r.left + r.width / 2;
      const cy = r.top + r.height / 2;
      setP({
        x: ((e.clientX - cx) / (r.width / 2)) * strength,
        y: ((e.clientY - cy) / (r.height / 2)) * strength,
      });
    };
    const onLeave = () => setP({ x: 0, y: 0 });
    window.addEventListener("mousemove", onMove);
    el.addEventListener("mouseleave", onLeave);
    return () => {
      window.removeEventListener("mousemove", onMove);
      el.removeEventListener("mouseleave", onLeave);
    };
  }, [ref, strength]);
  return p;
}

/* ─────────────────────────────────────────────────────────
   useTilt — 3D card tilt on mouse hover
   ────────────────────────────────────────────────────── */
function useTilt(ref, max = 8) {
  useEffect(() => {
    const el = ref.current;
    if (!el) return;
    const onMove = (e) => {
      const r = el.getBoundingClientRect();
      const px = (e.clientX - r.left) / r.width;
      const py = (e.clientY - r.top) / r.height;
      const rx = (0.5 - py) * max;
      const ry = (px - 0.5) * max;
      el.style.transform = `perspective(900px) rotateX(${rx}deg) rotateY(${ry}deg) translateZ(0)`;
    };
    const onLeave = () => { el.style.transform = ""; };
    el.addEventListener("mousemove", onMove);
    el.addEventListener("mouseleave", onLeave);
    return () => {
      el.removeEventListener("mousemove", onMove);
      el.removeEventListener("mouseleave", onLeave);
    };
  }, [ref, max]);
}

/* ─────────────────────────────────────────────────────────
   CountUp — animates from 0 to target. Supports formatters.
   ────────────────────────────────────────────────────── */
function CountUp({ to, suffix = "", duration = 1400, decimals = 0 }) {
  const [v, setV] = useState(0);
  const ref = useRef(null);
  useEffect(() => {
    let raf, start;
    const io = new IntersectionObserver(([e]) => {
      if (e.isIntersecting && !start) {
        start = performance.now();
        const tick = (now) => {
          const t = Math.min((now - start) / duration, 1);
          const eased = 1 - Math.pow(1 - t, 3);
          setV(to * eased);
          if (t < 1) raf = requestAnimationFrame(tick);
        };
        raf = requestAnimationFrame(tick);
      }
    }, { threshold: 0.4 });
    if (ref.current) io.observe(ref.current);
    return () => { cancelAnimationFrame(raf); io.disconnect(); };
  }, [to, duration]);
  return <span ref={ref}>{v.toFixed(decimals)}{suffix}</span>;
}

/* ─────────────────────────────────────────────────────────
   LiveStatus — pulsing dot + faux live viewer count in nav
   ────────────────────────────────────────────────────── */
function LiveStatus() {
  const [n, setN] = useState(247);
  useEffect(() => {
    const id = setInterval(() => {
      setN((v) => Math.max(180, Math.min(380, v + Math.round((Math.random() - 0.5) * 8))));
    }, 2200);
    return () => clearInterval(id);
  }, []);
  return (
    <span className="live-pill" title="Personas viendo ahora">
      <span className="live-dot"/>
      <span className="live-label">EN VIVO</span>
      <span className="live-num">{n}</span>
    </span>
  );
}

/* ─────────────────────────────────────────────────────────
   HUDOverlay — corner brackets + scanning lines + readouts
   Placed absolutely over the hero stage.
   ────────────────────────────────────────────────────── */
function HUDOverlay({ accent }) {
  return (
    <div className="hud" aria-hidden>
      <span className="hud-corner tl"/><span className="hud-corner tr"/>
      <span className="hud-corner bl"/><span className="hud-corner br"/>
      <span className="hud-scan"/>
      <div className="hud-readout tl">
        <span>OPT-A01</span>
        <span>TI · β5</span>
      </div>
      <div className="hud-readout tr">
        <span>49 · 18 · 145</span>
        <span className="dot"/>
        <span>READY</span>
      </div>
      <div className="hud-readout bl">
        <span>PD · CALIB</span>
        <span>62.4 mm</span>
      </div>
      <div className="hud-readout br">
        <span>LUM · 320 lx</span>
        <span className="dot"/>
      </div>
      <svg className="hud-rings" viewBox="0 0 400 400">
        <circle cx="200" cy="200" r="180" fill="none" stroke={accent} strokeOpacity="0.18" strokeWidth="1" strokeDasharray="4 8"/>
        <circle cx="200" cy="200" r="150" fill="none" stroke={accent} strokeOpacity="0.12" strokeWidth="1"/>
      </svg>
    </div>
  );
}

/* ─────────────────────────────────────────────────────────
   TryOnModal — fullscreen face-scan simulator
   ────────────────────────────────────────────────────── */
function TryOnModal({ open, onClose, accent }) {
  const [phase, setPhase] = useState(0);
  // 0: scanning, 1: detected, 2: fitted
  useEffect(() => {
    if (!open) { setPhase(0); return; }
    document.body.style.overflow = "hidden";
    const t1 = setTimeout(() => setPhase(1), 2200);
    const t2 = setTimeout(() => setPhase(2), 3800);
    return () => {
      document.body.style.overflow = "";
      clearTimeout(t1); clearTimeout(t2);
    };
  }, [open]);

  if (!open) return null;

  // Face mesh dots (deterministic positions, animated opacity)
  const dots = Array.from({ length: 56 }, (_, i) => {
    const a = (i / 56) * Math.PI * 2;
    const r = 90 + (i % 5) * 18;
    return { x: 200 + Math.cos(a) * r * 0.7, y: 220 + Math.sin(a) * r * 0.9, i };
  });

  return (
    <div className="tryon" onClick={onClose}>
      <div className="tryon-inner" onClick={(e) => e.stopPropagation()}>
        <button className="tryon-close" onClick={onClose} aria-label="Cerrar">✕</button>
        <div className="tryon-head">
          <div className="eyebrow light">Optidis · Vision AI</div>
          <h3>{phase === 0 ? "Detectando rostro…" : phase === 1 ? "Calibrando puntos faciales" : "Aether 01 · ajustado"}</h3>
        </div>
        <div className="tryon-stage">
          {/* Face silhouette */}
          <svg viewBox="0 0 400 440" className="tryon-face">
            <defs>
              <radialGradient id="faceGlow">
                <stop offset="0%" stopColor={accent} stopOpacity="0.25"/>
                <stop offset="100%" stopColor={accent} stopOpacity="0"/>
              </radialGradient>
            </defs>
            <circle cx="200" cy="220" r="180" fill="url(#faceGlow)"/>
            {/* Stylized face oval */}
            <ellipse cx="200" cy="230" rx="110" ry="140" fill="none" stroke="rgba(255,255,255,0.12)" strokeWidth="1.5"/>
            <ellipse cx="200" cy="230" rx="110" ry="140" fill="none" stroke={accent} strokeWidth="2"
              strokeDasharray={phase === 0 ? "8 12" : "0"} className="face-outline"/>
            {/* Eye positions */}
            <g opacity={phase >= 1 ? 1 : 0} className="eye-marks">
              <circle cx="160" cy="195" r="4" fill={accent}/>
              <circle cx="240" cy="195" r="4" fill={accent}/>
              <line x1="160" y1="195" x2="240" y2="195" stroke={accent} strokeWidth="1" strokeDasharray="2 3"/>
              <text x="200" y="180" fill="#fff" fontSize="11" textAnchor="middle" letterSpacing="1.5" fontFamily="ui-monospace, monospace">PD 62.4mm</text>
            </g>
            {/* Mesh dots */}
            {dots.map((d) => (
              <circle key={d.i} cx={d.x} cy={d.y} r="1.5" fill={accent}
                opacity={phase === 0 ? (0.3 + (d.i % 7) / 20) : 0.55}
                className="mesh-dot" style={{ animationDelay: `${(d.i % 12) * 60}ms` }}/>
            ))}
          </svg>

          {/* Glasses overlay when fitted */}
          {phase === 2 && (
            <div className="tryon-glasses">
              <svg viewBox="0 0 320 100" width="280">
                <defs>
                  <linearGradient id="tg" x1="0" y1="0" x2="0" y2="1">
                    <stop offset="0%" stopColor="#0b3d6e"/>
                    <stop offset="100%" stopColor="#062a4d"/>
                  </linearGradient>
                </defs>
                <circle cx="100" cy="50" r="42" fill={`${accent}40`} stroke="url(#tg)" strokeWidth="5"/>
                <circle cx="220" cy="50" r="42" fill={`${accent}40`} stroke="url(#tg)" strokeWidth="5"/>
                <path d="M 142 48 L 178 48" stroke="url(#tg)" strokeWidth="5" strokeLinecap="round"/>
              </svg>
            </div>
          )}

          <span className="tryon-scan"/>
        </div>
        <div className="tryon-stats">
          <div><span className="lbl">Calibre</span><strong>49 mm</strong></div>
          <div><span className="lbl">Puente</span><strong>18 mm</strong></div>
          <div><span className="lbl">Varilla</span><strong>145 mm</strong></div>
          <div><span className="lbl">Ajuste</span><strong className={phase === 2 ? "ok" : ""}>{phase === 2 ? "98%" : "—"}</strong></div>
        </div>
        <div className="tryon-foot">
          <button className="btn btn-ghost-light" onClick={onClose}>Cancelar</button>
          <button className="btn btn-primary" disabled={phase < 2}>
            {phase < 2 ? "Calibrando…" : "Añadir a mi par"}
          </button>
        </div>
      </div>
    </div>
  );
}

/* ─────────────────────────────────────────────────────────
   DotGrid — animated dot canvas background for Tech section
   Cursor-reactive: dots near cursor glow.
   ────────────────────────────────────────────────────── */
function DotGrid({ accent }) {
  const ref = useRef(null);
  useEffect(() => {
    const c = ref.current;
    if (!c) return;
    const ctx = c.getContext("2d");
    let raf, w, h, dots = [], mouse = { x: -9999, y: -9999 };
    const resize = () => {
      const r = c.parentElement.getBoundingClientRect();
      w = c.width = r.width * devicePixelRatio;
      h = c.height = r.height * devicePixelRatio;
      c.style.width = r.width + "px";
      c.style.height = r.height + "px";
      const gap = 36 * devicePixelRatio;
      dots = [];
      for (let y = gap / 2; y < h; y += gap)
        for (let x = gap / 2; x < w; x += gap)
          dots.push({ x, y, baseR: 1.2 * devicePixelRatio, phase: Math.random() * Math.PI * 2 });
    };
    const onMove = (e) => {
      const r = c.getBoundingClientRect();
      mouse.x = (e.clientX - r.left) * devicePixelRatio;
      mouse.y = (e.clientY - r.top) * devicePixelRatio;
    };
    const onLeave = () => { mouse.x = -9999; mouse.y = -9999; };
    const tick = (t) => {
      ctx.clearRect(0, 0, w, h);
      const time = t * 0.001;
      dots.forEach((d) => {
        const dx = d.x - mouse.x, dy = d.y - mouse.y;
        const dist = Math.sqrt(dx * dx + dy * dy);
        const near = Math.max(0, 1 - dist / (160 * devicePixelRatio));
        const pulse = 0.5 + 0.5 * Math.sin(time * 1.4 + d.phase);
        const r = d.baseR + near * 2.5 + pulse * 0.4;
        const alpha = 0.10 + near * 0.55 + pulse * 0.05;
        ctx.beginPath();
        ctx.fillStyle = `rgba(255,255,255,${alpha})`;
        ctx.arc(d.x, d.y, r, 0, Math.PI * 2);
        ctx.fill();
        if (near > 0.3) {
          ctx.beginPath();
          ctx.strokeStyle = `rgba(255,255,255,${near * 0.18})`;
          ctx.lineWidth = devicePixelRatio;
          ctx.arc(d.x, d.y, r * 3, 0, Math.PI * 2);
          ctx.stroke();
        }
      });
      raf = requestAnimationFrame(tick);
    };
    resize();
    raf = requestAnimationFrame(tick);
    window.addEventListener("resize", resize);
    window.addEventListener("mousemove", onMove);
    c.addEventListener("mouseleave", onLeave);
    return () => {
      cancelAnimationFrame(raf);
      window.removeEventListener("resize", resize);
      window.removeEventListener("mousemove", onMove);
      c.removeEventListener("mouseleave", onLeave);
    };
  }, []);
  return <canvas ref={ref} className="dot-grid"/>;
}

/* ─────────────────────────────────────────────────────────
   MagneticBtn — wraps children, follows cursor when near
   ────────────────────────────────────────────────────── */
function MagneticBtn({ children, className = "", strength = 14, ...props }) {
  const ref = useRef(null);
  useEffect(() => {
    const el = ref.current;
    if (!el) return;
    const onMove = (e) => {
      const r = el.getBoundingClientRect();
      const cx = r.left + r.width / 2;
      const cy = r.top + r.height / 2;
      const dx = e.clientX - cx, dy = e.clientY - cy;
      const dist = Math.sqrt(dx * dx + dy * dy);
      if (dist < 120) {
        const k = (1 - dist / 120) * strength;
        el.style.transform = `translate(${(dx / 120) * k}px, ${(dy / 120) * k}px)`;
      } else {
        el.style.transform = "";
      }
    };
    const onLeave = () => { el.style.transform = ""; };
    window.addEventListener("mousemove", onMove);
    el.addEventListener("mouseleave", onLeave);
    return () => {
      window.removeEventListener("mousemove", onMove);
      el.removeEventListener("mouseleave", onLeave);
    };
  }, [strength]);
  return <button ref={ref} className={`magnetic ${className}`} {...props}>{children}</button>;
}

/* ─────────────────────────────────────────────────────────
   ParallaxStage — wraps glasses, applies cursor parallax
   ────────────────────────────────────────────────────── */
function ParallaxStage({ children, strength = 14 }) {
  const ref = useRef(null);
  const p = useMouseParallax(ref, 1);
  return (
    <div ref={ref} className="parallax-stage" style={{
      transform: `perspective(1200px) rotateY(${p.x * 4}deg) rotateX(${-p.y * 3}deg) translate3d(${p.x * strength}px, ${p.y * strength}px, 0)`,
      transition: "transform 0.18s ease-out",
    }}>
      {children}
    </div>
  );
}

/* ─────────────────────────────────────────────────────────
   TiltCard — wrapper that applies useTilt to its child div
   ────────────────────────────────────────────────────── */
function TiltCard({ children, className = "", ...props }) {
  const ref = useRef(null);
  useTilt(ref, 6);
  return <div ref={ref} className={className} {...props}>{children}</div>;
}

/* ─────────────────────────────────────────────────────────
   Export to window
   ────────────────────────────────────────────────────── */
Object.assign(window, {
  useMouseParallax, useTilt,
  HUDOverlay, TryOnModal, CountUp, LiveStatus, DotGrid,
  MagneticBtn, ParallaxStage, TiltCard,
});
