"use client";
import { useEffect, useRef } from "react";

// Custom Cursor mit Trail (Canvas-basiert, GPU-freundlich).
// Default-Cursor wird via CSS auf non-hover/non-touch versteckt, dieser
// Canvas-Cursor ersetzt ihn auf Desktop. Touch-Devices bekommen den
// Default-Cursor (siehe media query in CSS).

const TRAIL_LENGTH = 14;

export function CustomCursor() {
  const canvasRef = useRef<HTMLCanvasElement>(null);
  const rafRef = useRef<number | null>(null);
  const points = useRef<Array<{ x: number; y: number; t: number }>>([]);
  const target = useRef<{ x: number; y: number; hover: boolean }>({ x: 0, y: 0, hover: false });
  const visible = useRef(true);

  useEffect(() => {
    const canvas = canvasRef.current;
    if (!canvas) return;
    const ctx = canvas.getContext("2d");
    if (!ctx) return;

    // Touch- und Coarse-Pointer-Devices: skip.
    if (window.matchMedia("(pointer: coarse)").matches) return;

    let dpr = window.devicePixelRatio || 1;
    function resize() {
      dpr = window.devicePixelRatio || 1;
      canvas!.width = window.innerWidth * dpr;
      canvas!.height = window.innerHeight * dpr;
      canvas!.style.width = `${window.innerWidth}px`;
      canvas!.style.height = `${window.innerHeight}px`;
      ctx!.scale(dpr, dpr);
    }
    resize();
    window.addEventListener("resize", resize);

    function onMove(e: MouseEvent) {
      target.current.x = e.clientX;
      target.current.y = e.clientY;
      const el = e.target as HTMLElement | null;
      const interactive =
        !!el?.closest('a, button, [role="button"], input, textarea, select, [data-cursor="hover"]');
      target.current.hover = interactive;
      if (!visible.current) {
        canvas!.style.opacity = "1";
        visible.current = true;
      }
    }
    function onLeave() {
      canvas!.style.opacity = "0";
      visible.current = false;
    }
    window.addEventListener("mousemove", onMove, { passive: true });
    document.addEventListener("mouseleave", onLeave);
    document.addEventListener("mouseenter", onLeave); // reset on enter

    function loop() {
      if (!ctx) return;
      ctx.clearRect(0, 0, canvas!.width / dpr, canvas!.height / dpr);

      const now = performance.now();
      points.current.unshift({ x: target.current.x, y: target.current.y, t: now });
      if (points.current.length > TRAIL_LENGTH) points.current.length = TRAIL_LENGTH;

      const accent = getComputedStyle(document.documentElement).getPropertyValue("--accent").trim() || "#e84a8f";
      const accent2 = getComputedStyle(document.documentElement).getPropertyValue("--accent-2").trim() || "#39ff14";

      // Trail
      for (let i = TRAIL_LENGTH - 1; i >= 0; i--) {
        const p = points.current[i];
        if (!p) continue;
        const age = (now - p.t) / 1000;
        if (age > 0.4) continue;
        const fade = 1 - i / TRAIL_LENGTH;
        const r = 4 + (TRAIL_LENGTH - i) * 0.45;
        ctx.beginPath();
        ctx.arc(p.x, p.y, r, 0, Math.PI * 2);
        ctx.fillStyle = i % 2 === 0 ? accent : accent2;
        ctx.globalAlpha = fade * 0.5;
        ctx.fill();
        ctx.globalAlpha = 1;
      }

      // Cursor-Head (Dot + Ring)
      const head = points.current[0];
      if (head) {
        const r1 = target.current.hover ? 14 : 6;
        const r2 = target.current.hover ? 22 : 12;
        ctx.beginPath();
        ctx.arc(head.x, head.y, r2, 0, Math.PI * 2);
        ctx.strokeStyle = accent;
        ctx.lineWidth = 1;
        ctx.globalAlpha = target.current.hover ? 0.7 : 0.35;
        ctx.stroke();
        ctx.globalAlpha = 1;
        ctx.beginPath();
        ctx.arc(head.x, head.y, r1 / 2, 0, Math.PI * 2);
        ctx.fillStyle = accent;
        ctx.fill();
      }

      rafRef.current = requestAnimationFrame(loop);
    }
    rafRef.current = requestAnimationFrame(loop);

    return () => {
      window.removeEventListener("resize", resize);
      window.removeEventListener("mousemove", onMove);
      document.removeEventListener("mouseleave", onLeave);
      document.removeEventListener("mouseenter", onLeave);
      if (rafRef.current) cancelAnimationFrame(rafRef.current);
    };
  }, []);

  return (
    <canvas
      ref={canvasRef}
      aria-hidden
      className="custom-cursor-canvas pointer-events-none fixed inset-0 z-[200] hidden opacity-0 transition-opacity duration-200 md:block"
      style={{ mixBlendMode: "screen" }}
    />
  );
}
