// Liquid Eye — canvas-rendered iris with animated liquid fill that tracks cursor.
// Uses metaball blobs + noisy iris rings for an organic, wet, liquid-mercury look.
function LiquidEye({ size = 880 }) {
  const canvasRef = React.useRef(null);
  const wrapRef = React.useRef(null);
  const pointerRef = React.useRef({ x: 0, y: 0, target: { x: 0, y: 0 } });
  const accent = (getComputedStyle(document.documentElement).getPropertyValue('--accent') || '#7C5CFF').trim();

  React.useEffect(() => {
    const canvas = canvasRef.current;
    const wrap = wrapRef.current;
    if (!canvas || !wrap) return;
    const ctx = canvas.getContext('2d', { alpha: true });
    const DPR = Math.min(window.devicePixelRatio || 1, 2);
    let W = size, H = size;
    function resize() {
      const rect = wrap.getBoundingClientRect();
      W = rect.width; H = rect.height;
      canvas.width = W * DPR; canvas.height = H * DPR;
      canvas.style.width = W + 'px'; canvas.style.height = H + 'px';
      ctx.setTransform(DPR, 0, 0, DPR, 0, 0);
    }
    resize();
    const ro = new ResizeObserver(resize); ro.observe(wrap);

    // Track pointer relative to wrap center, clamped to eye radius
    function onMove(e) {
      const rect = wrap.getBoundingClientRect();
      const cx = rect.left + rect.width / 2;
      const cy = rect.top + rect.height / 2;
      pointerRef.current.target.x = (e.clientX - cx) / (rect.width / 2);
      pointerRef.current.target.y = (e.clientY - cy) / (rect.height / 2);
    }
    window.addEventListener('pointermove', onMove, { passive: true });

    // Parse accent into rgb
    function hexToRgb(hex) {
      const h = hex.replace('#', '');
      const v = h.length === 3 ? h.split('').map(c => c + c).join('') : h;
      const n = parseInt(v, 16);
      return [(n >> 16) & 255, (n >> 8) & 255, n & 255];
    }
    const [AR, AG, AB] = hexToRgb(accent || '#7C5CFF');

    // Pseudo-noise
    function noise(x, y, t) {
      return (
        Math.sin(x * 1.7 + t * 0.6) * 0.5 +
        Math.sin(y * 2.3 - t * 0.4) * 0.3 +
        Math.sin((x + y) * 1.1 + t * 0.9) * 0.2
      );
    }

    let start = performance.now();
    let raf;
    function frame(now) {
      const t = (now - start) / 1000;

      // Smooth pointer follow
      pointerRef.current.x += (pointerRef.current.target.x - pointerRef.current.x) * 0.08;
      pointerRef.current.y += (pointerRef.current.target.y - pointerRef.current.y) * 0.08;

      const cx = W / 2, cy = H / 2;
      const R = Math.min(W, H) * 0.38; // eye outer radius
      const irisR = R * 0.62;

      ctx.clearRect(0, 0, W, H);

      // --- outer halo ---
      const halo = ctx.createRadialGradient(cx, cy, R * 0.4, cx, cy, R * 1.6);
      halo.addColorStop(0, `rgba(${AR},${AG},${AB},0.18)`);
      halo.addColorStop(1, 'rgba(0,0,0,0)');
      ctx.fillStyle = halo;
      ctx.fillRect(0, 0, W, H);

      // --- eye almond shape (subtle) ---
      ctx.save();
      ctx.beginPath();
      ctx.ellipse(cx, cy, R * 1.25, R * 0.78, 0, 0, Math.PI * 2);
      ctx.strokeStyle = `rgba(${AR},${AG},${AB},0.10)`;
      ctx.lineWidth = 1;
      ctx.stroke();
      ctx.restore();

      // --- sclera (dark, subtle gradient) ---
      ctx.save();
      ctx.beginPath();
      ctx.arc(cx, cy, R, 0, Math.PI * 2);
      const sclera = ctx.createRadialGradient(cx - R * 0.3, cy - R * 0.3, 0, cx, cy, R);
      sclera.addColorStop(0, 'rgba(24,22,40,0.9)');
      sclera.addColorStop(1, 'rgba(8,8,14,0.98)');
      ctx.fillStyle = sclera;
      ctx.fill();
      ctx.restore();

      // --- iris position tracks pointer ---
      const maxOffset = R - irisR - 4;
      const pdist = Math.min(1, Math.hypot(pointerRef.current.x, pointerRef.current.y));
      const pang = Math.atan2(pointerRef.current.y, pointerRef.current.x);
      const ix = cx + Math.cos(pang) * maxOffset * pdist;
      const iy = cy + Math.sin(pang) * maxOffset * pdist;

      // --- clip to iris circle ---
      ctx.save();
      ctx.beginPath();
      ctx.arc(ix, iy, irisR, 0, Math.PI * 2);
      ctx.clip();

      // Liquid background
      const bg = ctx.createRadialGradient(ix, iy, irisR * 0.1, ix, iy, irisR);
      bg.addColorStop(0, `rgba(${AR},${AG},${AB},0.95)`);
      bg.addColorStop(0.6, `rgba(${Math.round(AR*0.5)},${Math.round(AG*0.3)},${Math.round(AB*0.8)},0.9)`);
      bg.addColorStop(1, 'rgba(10,6,24,1)');
      ctx.fillStyle = bg;
      ctx.fillRect(ix - irisR, iy - irisR, irisR * 2, irisR * 2);

      // Liquid metaballs — organic flowing shapes inside iris
      const blobCount = 6;
      for (let i = 0; i < blobCount; i++) {
        const bt = t * (0.3 + i * 0.07) + i * 1.7;
        const br = irisR * (0.35 + 0.25 * Math.sin(bt * 0.7 + i));
        const ba = bt * 0.5 + i * (Math.PI * 2 / blobCount);
        const dist = irisR * (0.25 + 0.2 * Math.sin(bt));
        const bx = ix + Math.cos(ba) * dist + noise(i, bt, t) * 10;
        const by = iy + Math.sin(ba) * dist + noise(i + 3, bt, t) * 10;
        const g = ctx.createRadialGradient(bx, by, 0, bx, by, br);
        const alpha = 0.35 + 0.2 * Math.sin(bt);
        g.addColorStop(0, `rgba(255,255,255,${alpha * 0.6})`);
        g.addColorStop(0.4, `rgba(${AR},${AG},${AB},${alpha * 0.5})`);
        g.addColorStop(1, 'rgba(0,0,0,0)');
        ctx.globalCompositeOperation = 'screen';
        ctx.fillStyle = g;
        ctx.beginPath();
        ctx.arc(bx, by, br, 0, Math.PI * 2);
        ctx.fill();
      }
      ctx.globalCompositeOperation = 'source-over';

      // Iris rings — concentric with noise displacement
      for (let r = irisR * 0.95; r > irisR * 0.25; r -= 4) {
        ctx.beginPath();
        const segs = 80;
        for (let s = 0; s <= segs; s++) {
          const a = (s / segs) * Math.PI * 2;
          const disp = noise(Math.cos(a) * 3, Math.sin(a) * 3 + r * 0.01, t * 0.3) * 3;
          const rr = r + disp;
          const px = ix + Math.cos(a) * rr;
          const py = iy + Math.sin(a) * rr;
          if (s === 0) ctx.moveTo(px, py); else ctx.lineTo(px, py);
        }
        ctx.strokeStyle = `rgba(255,255,255,${0.04 + 0.06 * Math.sin(r * 0.1 + t)})`;
        ctx.lineWidth = 0.6;
        ctx.stroke();
      }

      // Highlight sheen top-left
      const sheen = ctx.createRadialGradient(ix - irisR * 0.4, iy - irisR * 0.4, 0, ix - irisR * 0.4, iy - irisR * 0.4, irisR * 0.8);
      sheen.addColorStop(0, 'rgba(255,255,255,0.28)');
      sheen.addColorStop(0.5, 'rgba(255,255,255,0.05)');
      sheen.addColorStop(1, 'rgba(255,255,255,0)');
      ctx.fillStyle = sheen;
      ctx.fillRect(ix - irisR, iy - irisR, irisR * 2, irisR * 2);

      // Pupil — black with subtle dilation pulse
      const pupilR = irisR * (0.26 + 0.03 * Math.sin(t * 1.2));
      ctx.beginPath();
      ctx.arc(ix, iy, pupilR, 0, Math.PI * 2);
      ctx.fillStyle = 'rgba(0,0,0,0.95)';
      ctx.fill();

      // Pupil sheen
      ctx.beginPath();
      ctx.arc(ix - pupilR * 0.3, iy - pupilR * 0.3, pupilR * 0.25, 0, Math.PI * 2);
      ctx.fillStyle = 'rgba(255,255,255,0.5)';
      ctx.fill();

      ctx.restore(); // unclip iris

      // --- outer iris ring (crisp edge) ---
      ctx.beginPath();
      ctx.arc(ix, iy, irisR, 0, Math.PI * 2);
      ctx.strokeStyle = `rgba(${AR},${AG},${AB},0.9)`;
      ctx.lineWidth = 1.5;
      ctx.shadowColor = `rgba(${AR},${AG},${AB},0.8)`;
      ctx.shadowBlur = 24;
      ctx.stroke();
      ctx.shadowBlur = 0;

      // outer eye ring
      ctx.beginPath();
      ctx.arc(cx, cy, R, 0, Math.PI * 2);
      ctx.strokeStyle = `rgba(${AR},${AG},${AB},0.35)`;
      ctx.lineWidth = 1;
      ctx.stroke();

      // crosshairs
      ctx.strokeStyle = `rgba(${AR},${AG},${AB},0.15)`;
      ctx.lineWidth = 1;
      ctx.beginPath();
      ctx.moveTo(cx - R * 1.4, cy); ctx.lineTo(cx - R * 1.05, cy);
      ctx.moveTo(cx + R * 1.05, cy); ctx.lineTo(cx + R * 1.4, cy);
      ctx.moveTo(cx, cy - R * 1.1); ctx.lineTo(cx, cy - R * 0.85);
      ctx.moveTo(cx, cy + R * 0.85); ctx.lineTo(cx, cy + R * 1.1);
      ctx.stroke();

      raf = requestAnimationFrame(frame);
    }
    raf = requestAnimationFrame(frame);

    return () => {
      cancelAnimationFrame(raf);
      ro.disconnect();
      window.removeEventListener('pointermove', onMove);
    };
  }, [size]);

  return (
    <div ref={wrapRef} className="liquid-eye-wrap" style={{ width: size, height: size }}>
      <canvas ref={canvasRef} />
    </div>
  );
}

window.LiquidEye = LiquidEye;
