import { useEffect, useRef, useState } from "react";
import { cn } from "@/lib/utils";
import { type AspectRatio, formatAspectRatioForCSS } from "@/utils/aspectRatioUtils";

interface CropRegion {
  x: number; // 0-1 normalized
  y: number; // 0-1 normalized
  width: number; // 0-1 normalized
  height: number; // 0-1 normalized
}

interface CropControlProps {
  videoElement: HTMLVideoElement | null;
  cropRegion: CropRegion;
  onCropChange: (region: CropRegion) => void;
  aspectRatio: AspectRatio;
}

type DragHandle = 'top' | 'right' | 'bottom' | 'left' | null;

export function CropControl({ videoElement, cropRegion, onCropChange, aspectRatio }: CropControlProps) {
  const canvasRef = useRef<HTMLCanvasElement>(null);
  const containerRef = useRef<HTMLDivElement>(null);
  const [isDragging, setIsDragging] = useState<DragHandle>(null);
  const [dragStart, setDragStart] = useState({ x: 0, y: 0 });
  const [initialCrop, setInitialCrop] = useState<CropRegion>(cropRegion);

  useEffect(() => {
    if (!videoElement || !canvasRef.current) return;

    const canvas = canvasRef.current;
    const ctx = canvas.getContext('2d', { alpha: false });
    if (!ctx) return;

    canvas.width = videoElement.videoWidth || 1920;
    canvas.height = videoElement.videoHeight || 1080;

    const draw = () => {
      if (videoElement.readyState >= 2) {
        ctx.clearRect(0, 0, canvas.width, canvas.height);
        ctx.drawImage(videoElement, 0, 0, canvas.width, canvas.height);
      }
      requestAnimationFrame(draw);
    };

    const rafId = requestAnimationFrame(draw);
    return () => cancelAnimationFrame(rafId);
  }, [videoElement]);

  const getContainerRect = () => {
    return containerRef.current?.getBoundingClientRect() || { width: 0, height: 0, left: 0, top: 0 };
  };

  const handlePointerDown = (e: React.PointerEvent, handle: DragHandle) => {
    e.stopPropagation();
    e.preventDefault();
    setIsDragging(handle);
    const rect = getContainerRect();
    setDragStart({
      x: (e.clientX - rect.left) / rect.width,
      y: (e.clientY - rect.top) / rect.height,
    });
    setInitialCrop(cropRegion);
    
    e.currentTarget.setPointerCapture(e.pointerId);
  };

  const handlePointerMove = (e: React.PointerEvent) => {
    if (!isDragging) return;

    const rect = getContainerRect();
    const currentX = (e.clientX - rect.left) / rect.width;
    const currentY = (e.clientY - rect.top) / rect.height;
    const deltaX = currentX - dragStart.x;
    const deltaY = currentY - dragStart.y;

    let newCrop = { ...initialCrop };

    switch (isDragging) {
      case 'top': {
        const newY = Math.max(0, initialCrop.y + deltaY);
        const bottom = initialCrop.y + initialCrop.height;
        newCrop.y = Math.min(newY, bottom - 0.1);
        newCrop.height = bottom - newCrop.y;
        break;
      }
      case 'bottom':
        newCrop.height = Math.max(0.1, Math.min(initialCrop.height + deltaY, 1 - initialCrop.y));
        break;
      case 'left': {
        const newX = Math.max(0, initialCrop.x + deltaX);
        const right = initialCrop.x + initialCrop.width;
        newCrop.x = Math.min(newX, right - 0.1);
        newCrop.width = right - newCrop.x;
        break;
      }
      case 'right':
        newCrop.width = Math.max(0.1, Math.min(initialCrop.width + deltaX, 1 - initialCrop.x));
        break;
    }

    onCropChange(newCrop);
  };

  const handlePointerUp = (e: React.PointerEvent) => {
    if (isDragging) {
      try {
        e.currentTarget.releasePointerCapture(e.pointerId);
      } catch {
      }
    }
    setIsDragging(null);
  };

  const cropPixelX = cropRegion.x * 100;
  const cropPixelY = cropRegion.y * 100;
  const cropPixelWidth = cropRegion.width * 100;
  const cropPixelHeight = cropRegion.height * 100;
  const videoAspectRatio = videoElement ? videoElement.videoWidth / videoElement.videoHeight : 16/9;
  const isVideoPortrait = videoAspectRatio < 1;
  const maxContainerWidth = isVideoPortrait ? '40vw' : '75vw';
  const maxContainerHeight = '75vh';

  return (
    <div className="w-full p-8">
      <div
        ref={containerRef}
        className="relative w-full bg-black rounded-lg overflow-visible cursor-default select-none shadow-2xl"
        style={{ 
          aspectRatio: videoAspectRatio,
          maxWidth: maxContainerWidth,
          maxHeight: maxContainerHeight,
          margin: '0 auto',
        }}
        onPointerMove={handlePointerMove}
        onPointerUp={handlePointerUp}
        onPointerLeave={handlePointerUp}
      >
        <canvas
          ref={canvasRef}
          className="w-full h-full rounded-lg"
          style={{ imageRendering: 'auto' }}
        />
        
        <div className="absolute inset-0 pointer-events-none" style={{ transition: 'none' }}>
          <svg width="100%" height="100%" className="absolute inset-0" style={{ transition: 'none' }}>
            <defs>
              <mask id="cropMask">
                <rect width="100%" height="100%" fill="white" />
                <rect
                  x={`${cropPixelX}%`}
                  y={`${cropPixelY}%`}
                  width={`${cropPixelWidth}%`}
                  height={`${cropPixelHeight}%`}
                  fill="black"
                  style={{ transition: 'none' }}
                />
              </mask>
            </defs>
            <rect 
              width="100%" 
              height="100%" 
              fill="black" 
              fillOpacity="0.6" 
              mask="url(#cropMask)" 
              style={{ transition: 'none' }}
            />
          </svg>
        </div>

        <div
          className={cn(
            "absolute h-[3px] cursor-ns-resize z-20 pointer-events-auto bg-[#34B27B]"
          )}
          style={{
            left: `${cropPixelX}%`,
            top: `${cropPixelY}%`,
            width: `${cropPixelWidth}%`,
            transform: 'translateY(-50%)',
            willChange: 'transform',
            transition: 'none',
          }}
          onPointerDown={(e) => handlePointerDown(e, 'top')}
        />

        <div
          className={cn(
            "absolute h-[3px] cursor-ns-resize z-20 pointer-events-auto bg-[#34B27B]"
          )}
          style={{
            left: `${cropPixelX}%`,
            top: `${cropPixelY + cropPixelHeight}%`,
            width: `${cropPixelWidth}%`,
            transform: 'translateY(-50%)',
            willChange: 'transform',
            transition: 'none',
          }}
          onPointerDown={(e) => handlePointerDown(e, 'bottom')}
        />

        <div
          className={cn(
            "absolute w-[3px] cursor-ew-resize z-20 pointer-events-auto bg-[#34B27B]"
          )}
          style={{
            left: `${cropPixelX}%`,
            top: `${cropPixelY}%`,
            height: `${cropPixelHeight}%`,
            transform: 'translateX(-50%)',
            willChange: 'transform',
            transition: 'none',
          }}
          onPointerDown={(e) => handlePointerDown(e, 'left')}
        />

        <div
          className={cn(
            "absolute w-[3px] cursor-ew-resize z-20 pointer-events-auto bg-[#34B27B]"
          )}
          style={{
            left: `${cropPixelX + cropPixelWidth}%`,
            top: `${cropPixelY}%`,
            height: `${cropPixelHeight}%`,
            transform: 'translateX(-50%)',
            willChange: 'transform',
            transition: 'none',
          }}
          onPointerDown={(e) => handlePointerDown(e, 'right')}
        />
      </div>
    </div>
  );
}
