import React, { useState, useCallback } from 'react';
import Cropper, { Area, Point } from 'react-easy-crop';
import { Check, X, ZoomIn, ZoomOut } from 'lucide-react';
import { motion } from 'motion/react';

interface ImageCropperProps {
  image;
  aspect;
  onCropComplete(croppedImage) => void;
  onCancel() => void;
  circularCrop?;
}

export const ImageCropper.FC = ({ 
  image, 
  aspect, 
  onCropComplete, 
  onCancel,
  circularCrop = false
}) => {
  const [crop, setCrop] = useState({ x});
  const [zoom, setZoom] = useState(1);
  const [croppedAreaPixels, setCroppedAreaPixels] = useState<Area | null>(null);

  const onCropChange = (crop) => {
    setCrop(crop);
  };

  const onZoomChange = (zoom) => {
    setZoom(zoom);
  };

  const onCropCompleteInternal = useCallback((_croppedArea) => {
    setCroppedAreaPixels(croppedAreaPixels);
  }, []);

  const createImage = (url)=>
    new Promise((resolve, reject) => {
      const image = new Image();
      image.addEventListener('load', () => resolve(image));
      image.addEventListener('error', (error) => reject(error));
      image.setAttribute('crossOrigin', 'anonymous');
      image.src = url;
    });

  const getCroppedImg = async (
    imageSrc)=> {
    const image = await createImage(imageSrc);
    const canvas = document.createElement('canvas');
    const ctx = canvas.getContext('2d');

    if (!ctx) {
      throw new Error('No 2d context');
    }

    canvas.width = pixelCrop.width;
    canvas.height = pixelCrop.height;

    ctx.drawImage(
      image,
      pixelCrop.x,
      pixelCrop.y,
      pixelCrop.width,
      pixelCrop.height,
      0,
      0,
      pixelCrop.width,
      pixelCrop.height
    );

    return new Promise((resolve, reject) => {
      canvas.toBlob((blob) => {
        if (!blob) {
          reject(new Error('Canvas is empty'));
          return;
        }
        resolve(blob);
      }, 'image/jpeg');
    });
  };

  const handleDone = async () => {
    if (croppedAreaPixels) {
      try {
        const croppedImage = await getCroppedImg(image, croppedAreaPixels);
        onCropComplete(croppedImage);
      } catch (e) {
        console.error(e);
      }
    }
  };

  return (
    <motion.div 
      initial={{ opacity}}
      animate={{ opacity}}
      exit={{ opacity}}
      className="fixed inset-0 z-[100] bg-black flex flex-col"
    >
      <div className="relative flex-1 bg-neutral-900">
        <Cropper
          image={image}
          crop={crop}
          zoom={zoom}
          aspect={aspect}
          cropShape={circularCrop ? 'round' 'rect'}
          showGrid={false}
          onCropChange={onCropChange}
          onCropComplete={onCropCompleteInternal}
          onZoomChange={onZoomChange}
        />
      </div>

      <div className="glass-thick p-6 space-y-6">
        <div className="flex items-center gap-4">
          <ZoomOut size={20} className="text-white/40" />
          <input
            type="range"
            value={zoom}
            min={1}
            max={3}
            step={0.1}
            aria-labelledby="Zoom"
            onChange={(e) => setZoom(Number(e.target.value))}
            className="flex-1 h-1.5 bg-white/10 rounded-lg appearance-none cursor-pointer accent-orange-500"
          />
          <ZoomIn size={20} className="text-white/40" />
        </div>

        <div className="flex items-center justify-between gap-4">
          <button
            onClick={onCancel}
            className="flex-1 flex items-center justify-center gap-2 py-3 rounded-2xl bg-white/5 hover-white/10 transition-colors font-bold"
          >
            <X size={20} />
            Cancel
          </button>
          <button
            onClick={handleDone}
            className="flex-1 flex items-center justify-center gap-2 py-3 rounded-2xl bg-orange-500 shadow-lg shadow-orange-500/20 active-95 transition-transform font-bold"
          >
            <Check size={20} />
            Apply
          </button>
        </div>
      </div>
    </motion.div>
  );
};
