import React, { useRef, useEffect, useState } from 'react';
import { X } from 'lucide-react';
import { useCropHandles, type CropBounds, type HandleType } from '@/hooks/useCropHandles';

interface ManualCropUIProps {
  imageUrl: string;
  onCropChange: (bounds: CropBounds | null) => void;
  imageDimensions?: { width: number; height: number };
  initialCrop?: CropBounds;
}

const HANDLE_SIZE = 12;
const HANDLE_TYPES: HandleType[] = [
  'top-left',
  'top',
  'top-right',
  'right',
  'bottom-right',
  'bottom',
  'bottom-left',
  'left',
];

export default function ManualCropUI({
  imageUrl,
  onCropChange,
  imageDimensions,
  initialCrop,
}: ManualCropUIProps) {
  const imageRef = useRef<HTMLImageElement>(null);
  const containerRef = useRef<HTMLDivElement>(null);
  const [displayDimensions, setDisplayDimensions] = useState<{ width: number; height: number } | null>(null);
  const [error, setError] = useState<string | null>(null);

  const actualDimensions = imageDimensions || displayDimensions;

  const { crop, setCrop, startDrag, moveDrag, endDrag, resetCrop, isDragging } = useCropHandles(
    actualDimensions
      ? {
          imageDimensions: actualDimensions,
          initialCrop,
          minSize: 100,
        }
      : { imageDimensions: { width: 1, height: 1 }, initialCrop, minSize: 100 }
  );

  // Measure image dimensions on load
  const handleImageLoad = (e: React.SyntheticEvent<HTMLImageElement>) => {
    const img = e.currentTarget;
    const width = img.naturalWidth || img.width;
    const height = img.naturalHeight || img.height;

    if (width && height) {
      setDisplayDimensions({ width, height });
      setError(null);
    }
  };

  const handleImageError = () => {
    setError('Failed to load image');
  };

  // Emit crop changes to parent
  useEffect(() => {
    onCropChange(crop);
  }, [crop, onCropChange]);

  if (error) {
    return (
      <div className="flex items-center justify-center p-8 bg-surface-container rounded-none">
        <div className="text-center">
          <p className="text-error">{error}</p>
        </div>
      </div>
    );
  }

  // If no dimensions yet, show minimal loading state with hidden image
  if (!actualDimensions) {
    return (
      <div className="flex flex-col gap-4">
        <div className="relative bg-surface-container rounded-none overflow-hidden border border-border">
          <img
            ref={imageRef}
            src={imageUrl}
            alt="Photo preview"
            onLoad={handleImageLoad}
            onError={handleImageError}
            className="w-full h-full object-contain"
            style={{ visibility: 'hidden' }}
          />
        </div>
        <div className="text-sm text-secondary text-center">Loading image...</div>
      </div>
    );
  }

  const containerWidth = containerRef.current?.clientWidth || 400;
  const scale = containerWidth / actualDimensions.width;

  const displayWidth = actualDimensions.width * scale;
  const displayHeight = actualDimensions.height * scale;

  const getHandlePosition = (
    handleType: HandleType
  ): { left: string; top: string; transform: string } => {
    if (!crop) {
      return { left: '0', top: '0', transform: 'translate(0, 0)' };
    }

    const x = crop.x * scale;
    const y = crop.y * scale;
    const w = crop.width * scale;
    const h = crop.height * scale;

    const offsets = {
      'top-left': { left: x, top: y },
      top: { left: x + w / 2, top: y },
      'top-right': { left: x + w, top: y },
      right: { left: x + w, top: y + h / 2 },
      'bottom-right': { left: x + w, top: y + h },
      bottom: { left: x + w / 2, top: y + h },
      'bottom-left': { left: x, top: y + h },
      left: { left: x, top: y + h / 2 },
    };

    const pos = offsets[handleType];
    return {
      left: `${pos.left}px`,
      top: `${pos.top}px`,
      transform: 'translate(-50%, -50%)',
    };
  };

  const handleMouseDown = (handleType: HandleType) => (e: React.MouseEvent) => {
    e.preventDefault();
    if (!containerRef.current || !crop) return;

    const rect = containerRef.current.getBoundingClientRect();
    const startX = (e.clientX - rect.left) / scale;
    const startY = (e.clientY - rect.top) / scale;

    startDrag(handleType, startX, startY);
  };

  const handleTouchStart = (handleType: HandleType) => (e: React.TouchEvent) => {
    e.preventDefault();
    if (!containerRef.current || !crop || e.touches.length === 0) return;

    const rect = containerRef.current.getBoundingClientRect();
    const touch = e.touches[0];
    const startX = (touch.clientX - rect.left) / scale;
    const startY = (touch.clientY - rect.top) / scale;

    startDrag(handleType, startX, startY);
  };

  // Global mouse/touch move and end listeners
  useEffect(() => {
    if (!isDragging) return;

    const handleMouseMove = (e: MouseEvent) => {
      if (!containerRef.current) return;
      const rect = containerRef.current.getBoundingClientRect();
      const currentX = (e.clientX - rect.left) / scale;
      const currentY = (e.clientY - rect.top) / scale;
      moveDrag(currentX, currentY);
    };

    const handleTouchMove = (e: TouchEvent) => {
      if (!containerRef.current || e.touches.length === 0) return;
      const rect = containerRef.current.getBoundingClientRect();
      const touch = e.touches[0];
      const currentX = (touch.clientX - rect.left) / scale;
      const currentY = (touch.clientY - rect.top) / scale;
      moveDrag(currentX, currentY);
    };

    const handleEnd = () => {
      endDrag();
    };

    document.addEventListener('mousemove', handleMouseMove);
    document.addEventListener('mouseup', handleEnd);
    document.addEventListener('touchmove', handleTouchMove, { passive: false });
    document.addEventListener('touchend', handleEnd);

    return () => {
      document.removeEventListener('mousemove', handleMouseMove);
      document.removeEventListener('mouseup', handleEnd);
      document.removeEventListener('touchmove', handleTouchMove);
      document.removeEventListener('touchend', handleEnd);
    };
  }, [isDragging, scale, moveDrag, endDrag]);

  return (
    <div className="flex flex-col gap-4">
      {/* Image container with crop preview */}
      <div
        ref={containerRef}
        className="relative bg-surface-container rounded-none overflow-hidden border border-border"
        style={{
          aspectRatio: `${actualDimensions.width} / ${actualDimensions.height}`,
          maxWidth: '100%',
        }}
      >
        {/* Image */}
        <img
          ref={imageRef}
          src={imageUrl}
          alt="Photo preview"
          onLoad={handleImageLoad}
          onError={handleImageError}
          className="w-full h-full object-contain"
        />

        {/* Semi-transparent overlay outside crop box */}
        {crop && (
          <div className="absolute inset-0 pointer-events-none">
            {/* Top overlay */}
            <div
              className="absolute left-0 right-0 bg-surface-container-lowest/40"
              style={{
                top: 0,
                height: `${crop.y * scale}px`,
              }}
            />
            {/* Bottom overlay */}
            <div
              className="absolute left-0 right-0 bg-surface-container-lowest/40"
              style={{
                top: `${(crop.y + crop.height) * scale}px`,
                bottom: 0,
              }}
            />
            {/* Left overlay */}
            <div
              className="absolute top-0 bottom-0 bg-surface-container-lowest/40"
              style={{
                left: 0,
                width: `${crop.x * scale}px`,
                top: `${crop.y * scale}px`,
                height: `${crop.height * scale}px`,
              }}
            />
            {/* Right overlay */}
            <div
              className="absolute top-0 bottom-0 bg-surface-container-lowest/40"
              style={{
                left: `${(crop.x + crop.width) * scale}px`,
                right: 0,
                top: `${crop.y * scale}px`,
                height: `${crop.height * scale}px`,
              }}
            />

            {/* Crop bounding box */}
            <div
              className="absolute border-2 border-cyan-400"
              style={{
                left: `${crop.x * scale}px`,
                top: `${crop.y * scale}px`,
                width: `${crop.width * scale}px`,
                height: `${crop.height * scale}px`,
              }}
            />

            {/* Handles */}
            {HANDLE_TYPES.map((handleType) => (
              <button
                key={handleType}
                onMouseDown={handleMouseDown(handleType)}
                onTouchStart={handleTouchStart(handleType)}
                className={`absolute w-${HANDLE_SIZE} h-${HANDLE_SIZE} bg-cyan-400 rounded-none border-2 border-white shadow-none hover:scale-125 transition-transform cursor-grab active:cursor-grabbing ${
                  isDragging ? 'scale-125' : ''
                }`}
                style={{
                  ...getHandlePosition(handleType),
                  width: `${HANDLE_SIZE}px`,
                  height: `${HANDLE_SIZE}px`,
                }}
                aria-label={`Drag ${handleType} handle`}
              />
            ))}
          </div>
        )}
      </div>

      {/* Controls */}
      <div className="flex gap-2">
        {crop && (
          <button
            onClick={() => resetCrop()}
            className="flex items-center justify-center gap-2 flex-1 px-4 py-2.5 bg-border text-white rounded-none font-normal text-base transition-colors hover:bg-surface-bright"
          >
            <X className="w-5 h-5" />
            <span>Use Full Photo</span>
          </button>
        )}
        {!crop && (
          <div className="text-sm text-secondary text-center flex-1 py-2.5">
            Drag handles to adjust crop area
          </div>
        )}
      </div>

      {/* Crop bounds display (debug) */}
      {crop && (
        <div className="text-xs text-secondary text-center">
          Crop: {Math.round(crop.x)}, {Math.round(crop.y)} | Size: {Math.round(crop.width)} x{' '}
          {Math.round(crop.height)}
        </div>
      )}
    </div>
  );
}
