/* eslint-disable */
// HAIQ Landing — Particles canvas (full viewport, fixed, low z)
function Particles() {
  const ref = React.useRef(null);
  React.useEffect(() => {
    const c = ref.current;
    if (!c) return;
    const ctx = c.getContext('2d');
    const dpr = window.devicePixelRatio || 1;
    function size() {
      c.width = window.innerWidth * dpr;
      c.height = window.innerHeight * dpr;
      c.style.width = window.innerWidth + 'px';
      c.style.height = window.innerHeight + 'px';
      ctx.scale(dpr, dpr);
    }
    size();
    const N = 50;
    const dots = Array.from({length: N}, () => ({
      x: Math.random() * window.innerWidth,
      y: Math.random() * window.innerHeight,
      r: 1 + Math.random() * 2,
      a: 0.08 + Math.random() * 0.22,
      vy: -(0.1 + Math.random() * 0.3),
      offset: Math.random() * 1000,
    }));
    let raf, t = 0;
    function frame() {
      t++;
      ctx.clearRect(0, 0, window.innerWidth, window.innerHeight);
      for (const d of dots) {
        d.y += d.vy;
        d.x += Math.sin(t * 0.002 + d.offset) * 0.3;
        if (d.y < -4) { d.y = window.innerHeight + 4; d.x = Math.random() * window.innerWidth; }
        ctx.beginPath();
        ctx.fillStyle = `rgba(255,255,255,${d.a})`;
        ctx.arc(d.x, d.y, d.r, 0, Math.PI * 2);
        ctx.fill();
      }
      raf = requestAnimationFrame(frame);
    }
    frame();
    const onResize = () => { ctx.setTransform(1,0,0,1,0,0); size(); };
    window.addEventListener('resize', onResize);
    return () => { cancelAnimationFrame(raf); window.removeEventListener('resize', onResize); };
  }, []);
  return <canvas ref={ref} style={{position:'fixed', inset:0, zIndex:1, pointerEvents:'none'}} />;
}

// CSS-art spiral — 30 hairlines in 3D perspective
function Spiral({size = 360}) {
  const lines = Array.from({length: 30}, (_, i) => {
    const op = 0.04 + (i / 30) * 0.18;
    return (
      <div key={i} style={{
        position:'absolute', left:0, right:0, top:'50%', height:1,
        background:`rgba(255,255,255,${op.toFixed(3)})`,
        transform:`rotateX(${i * 6}deg) rotateY(${i * 3}deg) translateZ(${i * 2}px)`,
        transformOrigin:'50% 50%',
      }}/>
    );
  });
  return (
    <div style={{position:'relative', width:size, height:size, display:'flex', alignItems:'center', justifyContent:'center'}}>
      <div style={{position:'absolute', width:size*1.6, height:size*0.7, background:'radial-gradient(ellipse, rgba(255,255,255,0.06) 0%, transparent 70%)', filter:'blur(40px)'}}/>
      <div style={{
        width:size, height:size, perspective:'800px', transformStyle:'preserve-3d',
        animation:'haiqSpiral 30s linear infinite',
      }}>{lines}</div>
    </div>
  );
}

// Scroll progress 2px line
function ScrollProgress() {
  const [pct, setPct] = React.useState(0);
  React.useEffect(() => {
    const onScroll = () => {
      const h = document.documentElement;
      const max = h.scrollHeight - h.clientHeight;
      setPct(max > 0 ? (h.scrollTop / max) * 100 : 0);
    };
    window.addEventListener('scroll', onScroll);
    onScroll();
    return () => window.removeEventListener('scroll', onScroll);
  }, []);
  return (
    <div style={{position:'fixed', top:0, left:0, right:0, height:2, zIndex:101, background:'rgba(255,255,255,0.05)'}}>
      <div style={{height:'100%', width:`${pct}%`, background:'#fff', transition:'width 0.1s linear'}}/>
    </div>
  );
}

// SVG grain overlay (procedural via SVG turbulence)
function Grain() {
  return (
    <svg style={{position:'fixed', inset:0, width:'100%', height:'100%', opacity:0.025, pointerEvents:'none', zIndex:9999, mixBlendMode:'overlay'}}>
      <filter id="haiq-grain">
        <feTurbulence type="fractalNoise" baseFrequency="0.9" numOctaves="2" stitchTiles="stitch"/>
      </filter>
      <rect width="100%" height="100%" filter="url(#haiq-grain)"/>
    </svg>
  );
}

// Reveal on scroll
function Reveal({children, delay = 0, as: Tag = 'div', style = {}, ...rest}) {
  const ref = React.useRef(null);
  const [seen, setSeen] = React.useState(false);
  React.useLayoutEffect(() => {
    const el = ref.current; if (!el) return;
    // If already in viewport on mount, reveal immediately (helps hero + above-the-fold)
    const rect = el.getBoundingClientRect();
    if (rect.top < window.innerHeight && rect.bottom > 0) {
      requestAnimationFrame(() => setSeen(true));
      return;
    }
    const io = new IntersectionObserver(([e]) => {
      if (e.isIntersecting) { setSeen(true); io.disconnect(); }
    }, {threshold: 0.15});
    io.observe(el);
    return () => io.disconnect();
  }, []);
  return (
    <Tag ref={ref} style={{
      ...style,
      opacity: seen ? 1 : 0,
      transform: seen ? 'translateY(0)' : 'translateY(40px)',
      transition: `opacity 0.8s cubic-bezier(0.16,1,0.3,1) ${delay}s, transform 0.8s cubic-bezier(0.16,1,0.3,1) ${delay}s`,
    }} {...rest}>{children}</Tag>
  );
}

// Animated counter
function Counter({to, suffix = '', duration = 1500}) {
  const [val, setVal] = React.useState(0);
  const ref = React.useRef(null);
  React.useEffect(() => {
    const el = ref.current; if (!el) return;
    const io = new IntersectionObserver(([e]) => {
      if (!e.isIntersecting) return;
      io.disconnect();
      const start = performance.now();
      const target = typeof to === 'number' ? to : parseFloat(to);
      function tick(now) {
        const p = Math.min(1, (now - start) / duration);
        setVal(target * (1 - Math.pow(1 - p, 3)));
        if (p < 1) requestAnimationFrame(tick);
      }
      requestAnimationFrame(tick);
    }, {threshold: 0.4});
    io.observe(el);
    return () => io.disconnect();
  }, [to, duration]);
  const display = Number.isInteger(to) ? Math.floor(val) : val.toFixed(1);
  return <span ref={ref}>{display}{suffix}</span>;
}

Object.assign(window, { Particles, Spiral, ScrollProgress, Grain, Reveal, Counter });
