import { useMemo } from 'react';

type Position = 'top' | 'bottom';

interface GradualBlurProps {
  /** Edge to attach the blur overlay */
  position?: Position;
  /** Base blur strength multiplier */
  strength?: number;
  /** Overlay height (CSS value) */
  height?: string;
  /** Number of stacked blur layers (higher = smoother) */
  divCount?: number;
  /** Use exponential progression for stronger end blur */
  exponential?: boolean;
  /** Distribution curve: linear | ease-out */
  curve?: 'linear' | 'ease-out';
  /** Opacity applied to each blur layer */
  opacity?: number;
  /** z-index for the overlay */
  zIndex?: number;
  /** Additional class names */
  className?: string;
}

const getGradientDirection = (position: Position) =>
  position === 'top' ? 'to top' : 'to bottom';

export function GradualBlur({
  position = 'top',
  strength = 2,
  height = '6rem',
  divCount = 5,
  exponential = false,
  curve = 'linear',
  opacity = 1,
  zIndex = 10,
  className = '',
}: GradualBlurProps) {
  const blurDivs = useMemo(() => {
    const divs: React.ReactNode[] = [];
    const increment = 100 / divCount;
    const direction = getGradientDirection(position);

    const curveFunc = curve === 'ease-out'
      ? (p: number) => 1 - Math.pow(1 - p, 2)
      : (p: number) => p;

    for (let i = 1; i <= divCount; i++) {
      let progress = i / divCount;
      progress = curveFunc(progress);

      let blurValue: number;
      if (exponential) {
        blurValue = Math.pow(2, progress * 4) * 0.0625 * strength;
      } else {
        blurValue = progress * strength;
      }

      const p1 = Math.round((increment * i - increment) * 10) / 10;
      const p2 = Math.round(increment * i * 10) / 10;
      const p3 = Math.round((increment * i + increment) * 10) / 10;
      const p4 = Math.round((increment * i + increment * 2) * 10) / 10;

      let gradient = `transparent ${p1}%, black ${p2}%`;
      if (p3 <= 100) gradient += `, black ${p3}%`;
      if (p4 <= 100) gradient += `, transparent ${p4}%`;

      const maskImage = `linear-gradient(${direction}, ${gradient})`;

      divs.push(
        <div
          key={i}
          style={{
            position: 'absolute',
            inset: 0,
            maskImage,
            WebkitMaskImage: maskImage,
            backdropFilter: `blur(${blurValue.toFixed(3)}rem)`,
            WebkitBackdropFilter: `blur(${blurValue.toFixed(3)}rem)`,
            opacity,
          }}
        />,
      );
    }

    return divs;
  }, [position, strength, divCount, exponential, curve, opacity]);

  return (
    <div
      className={className}
      style={{
        position: 'absolute',
        [position]: 0,
        left: 0,
        right: 0,
        height,
        pointerEvents: 'none',
        zIndex,
        overflow: 'hidden',
      }}
    >
      <div style={{ position: 'relative', width: '100%', height: '100%' }}>
        {blurDivs}
      </div>
    </div>
  );
}
