import React, { useCallback, useEffect, useRef, useState } from "react";
import Cropper, { Area } from "react-easy-crop";
import { Button, Slider } from "antd";
import Modal from "./Modal";
import { CloudUpload } from "lucide-react";

interface ImageCropperProps {
  src?: string;
  aspect?: number;
  onChange: (file: File, preview: string) => void;
  customPreview?: React.ReactNode;
  className?: string;
  disabled?: boolean;
}

const ImageCropper: React.FC<ImageCropperProps> = ({
  src,
  aspect = 1,
  onChange,
  customPreview,
  className,
  disabled,
}) => {
  const inputRef = useRef<HTMLInputElement>(null);

  const [imageSrc, setImageSrc] = useState<string | null>(null);
  const [preview, setPreview] = useState<string | null>(null);
  const [open, setOpen] = useState(false);

  const [crop, setCrop] = useState({ x: 0, y: 0 });
  const [zoom, setZoom] = useState(1);
  const [croppedAreaPixels, setCroppedAreaPixels] = useState<Area | null>(null);
  const [fileName, setFileName] = useState<string>("cropped-image.png");

  useEffect(() => {
    if (src) setPreview(src);
  }, [src]);

  const onCropComplete = useCallback((_: Area, croppedPixels: Area) => {
    setCroppedAreaPixels(croppedPixels);
  }, []);

  const createImage = (url: string): Promise<HTMLImageElement> =>
    new Promise((resolve, reject) => {
      const img = new Image();
      img.src = url;
      img.crossOrigin = "anonymous";
      img.onload = () => resolve(img);
      img.onerror = reject;
    });

  const getCroppedImage = async () => {
    if (!imageSrc || !croppedAreaPixels) return;

    const image = await createImage(imageSrc);
    const canvas = document.createElement("canvas");
    const ctx = canvas.getContext("2d")!;

    canvas.width = croppedAreaPixels.width;
    canvas.height = croppedAreaPixels.height;

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

    return new Promise<{ file: File; url: string }>((resolve) => {
      canvas.toBlob((blob) => {
        if (!blob) return;

        // Use original filename but ensure .png extension
        const baseName = fileName.includes(".")
          ? fileName.substring(0, fileName.lastIndexOf("."))
          : fileName;
        const newFileName = `${baseName}.png`;

        const file = new File([blob], newFileName, {
          type: "image/png",
        });
        const url = URL.createObjectURL(blob);
        resolve({ file, url });
      }, "image/png");
    });
  };

  const handleFileChange = (e: React.ChangeEvent<HTMLInputElement>) => {
    const file = e.target.files?.[0];
    if (!file) return;

    const reader = new FileReader();
    reader.onload = () => {
      setCrop({ x: 0, y: 0 });
      setZoom(1);
      setFileName(file.name);
      setImageSrc(reader.result as string);
      setOpen(true);
    };
    reader.readAsDataURL(file);

    if (inputRef.current) inputRef.current.value = "";
  };

  const handleSave = async () => {
    const result = await getCroppedImage();
    if (!result) return;

    setPreview(result.url);
    onChange(result.file, result.url);
    setOpen(false);
  };

  return (
    <div className="space-y-3">
      <input
        ref={inputRef}
        type="file"
        id="crop-image-upload"
        accept="image/*"
        onChange={handleFileChange}
        style={{ display: "none" }}
        disabled={disabled}
      />

      <label htmlFor="crop-image-upload">
        <div
          className={`h-20 w-20 group flex items-center justify-center
            border border-dashed border-gray-300
            rounded-lg p-2 cursor-pointer
            hover:border-blue-500 transition ${className}`}
          title="Upload"
        >
          {customPreview ? (
            customPreview
          ) : preview ? (
            <img
              src={preview}
              alt="Preview"
              className={`h-20 w-20 object-cover`}
            />
          ) : (
            <div className="flex flex-col items-center text-gray-400">
              <CloudUpload className="h-10 w-10 group-hover:text-blue-500" />
              <span className="text-xs mt-1">Upload</span>
            </div>
          )}
        </div>
      </label>

      {/* Crop Modal */}
      <Modal
        isOpen={open}
        title="Crop Image"
        onClose={() => setOpen(false)}
        className="w-[460px]"
      >
        <div className="relative h-[300px] w-full rounded-md overflow-hidden bg-black">
          {imageSrc && (
            <Cropper
              image={imageSrc}
              crop={crop}
              zoom={zoom}
              aspect={aspect}
              onCropChange={setCrop}
              onZoomChange={setZoom}
              onCropComplete={onCropComplete}
            />
          )}
        </div>

        {/* Zoom */}
        <div className="mt-4">
          <span className="text-sm font-medium text-gray-700">Zoom</span>
          <Slider min={1} max={3} step={0.1} value={zoom} onChange={setZoom} />
        </div>

        {/* Actions */}
        <div className="flex justify-end gap-3 mt-5">
          <Button onClick={() => setOpen(false)}>Cancel</Button>
          <Button type="primary" onClick={handleSave}>
            Save
          </Button>
        </div>
      </Modal>
    </div>
  );
};

export default ImageCropper;
