import {
  useRef,
  type CSSProperties,
  type MouseEvent,
  type ReactNode,
} from 'react';
import { SPRINGS, prefersReducedMotion } from './utils.js';

export interface TiltCardProps {
  children: ReactNode;
  /** Maximum tilt angle in degrees. Default 8. */
  intensity?: number;
  /** Glare highlight intensity 0..1. Default 0.18. */
  glare?: number;
  /** Perspective in pixels. Default 800. */
  perspective?: number;
  /** Bypass motion. */
  disableMotion?: boolean;
  className?: string;
  style?: CSSProperties;
}

/**
 * `<TiltCard>` — interactive 3D tilt + cursor-tracking glare on hover.
 * Designed for hero cards, marketing tiles, and KPI surfaces. Settles
 * back to neutral on mouse leave with a snappy spring.
 *
 * Performance: all transforms applied as CSS variables on a single ref,
 * so React doesn't re-render on each pointer move.
 */
export function TiltCard({
  children,
  intensity = 8,
  glare = 0.18,
  perspective = 800,
  disableMotion,
  className,
  style,
}: TiltCardProps) {
  const ref = useRef<HTMLDivElement>(null);
  const reduced = disableMotion ?? prefersReducedMotion();

  const onMove = (e: MouseEvent<HTMLDivElement>) => {
    if (reduced) return;
    const el = ref.current;
    if (!el) return;
    const rect = el.getBoundingClientRect();
    const x = (e.clientX - rect.left) / rect.width; // 0..1
    const y = (e.clientY - rect.top) / rect.height; // 0..1
    const rotateY = (x - 0.5) * intensity * 2;
    const rotateX = -(y - 0.5) * intensity * 2;
    el.style.transition = 'transform 60ms linear';
    el.style.transform = `perspective(${perspective}px) rotateX(${rotateX}deg) rotateY(${rotateY}deg) translateZ(0)`;
    el.style.setProperty('--bl-tilt-glare-x', `${x * 100}%`);
    el.style.setProperty('--bl-tilt-glare-y', `${y * 100}%`);
  };

  const onLeave = () => {
    if (reduced) return;
    const el = ref.current;
    if (!el) return;
    el.style.transition = `transform 420ms ${SPRINGS.bouncy}`;
    el.style.transform = `perspective(${perspective}px) rotateX(0deg) rotateY(0deg) translateZ(0)`;
  };

  return (
    <div
      ref={ref}
      data-testid="bl-tilt-card"
      onMouseMove={onMove}
      onMouseLeave={onLeave}
      className={className}
      style={{
        position: 'relative',
        transformStyle: 'preserve-3d',
        willChange: 'transform',
        ...style,
      }}
    >
      {children}
      {!reduced && glare > 0 && (
        <span
          aria-hidden
          style={{
            position: 'absolute',
            inset: 0,
            pointerEvents: 'none',
            borderRadius: 'inherit',
            background: `radial-gradient(circle at var(--bl-tilt-glare-x, 50%) var(--bl-tilt-glare-y, 50%), rgba(255,255,255,${glare}), transparent 55%)`,
            mixBlendMode: 'overlay',
          }}
        />
      )}
    </div>
  );
}
