import React, { useState, useEffect, useCallback } from 'react';
import { Upload, Modal } from 'antd';
import { uploadImage } from '../../Features/upload/upload';
import { useDispatch } from 'react-redux';
import ImageCropper from '../../Components/Forms/Cropper2.jsx';
import ShapeCropper from './ShapeCropper.jsx';
import { PiCropBold } from 'react-icons/pi';
import { FiPenTool } from 'react-icons/fi';
import { DefaultModal } from '../../Components/Modal/DefaultModal.jsx';
import '../../Styles/Product/Product.scss';
import { Messages } from '../Notifications/Messages.jsx';
const allowedTypes = [
  'image/jpeg',
  'image/png',
  'image/webp',
  'image/svg+xml',
  'image/gif',
  'image/avif',
];
const CropUpload = ({
  updateImageUrl,
  ImageLink,
  onlineImage,
  isProductList = {},
  handleClose = () => {}
}) => {
  const dispatch = useDispatch();
  const [messageType, setMessageType] = useState(null);
  const [messageData, setMessageData] = useState(null);
  const [fileList, setFileList] = useState([]);
  const [previewVisible, setPreviewVisible] = useState(false);
  const [previewImage, setPreviewImage] = useState('');
  const [editImageOpen, setEditImageOpen] = useState(false);
  const [croppedImage, setCroppedImage] = useState(null);
  const [shapedImage, setShapedImage] = useState(false);
  const [cropImage, setCropImage] = useState(false);
  const [shapedData, setShapedData] = useState(null);
  const [resizedImageUrl, setResizedImageUrl] = useState('');

  useEffect(() => {
    if (ImageLink != '' && ImageLink != null) {
      updateImageUrl(ImageLink);
      setFileList([
        {
          uid: `${Date.now()}-${Math.random()}`, // Ensures uniqueness
          name: `image${Date.now()}-${Math.random()}.png`,
          status: 'done',
          url: ImageLink,
        },
      ]);
    } else {
      updateImageUrl();
      // setFileList([]);
      // handleRemove()
    }
  }, [ImageLink]);

  useEffect(() => {
    if (ImageLink != '' && ImageLink != null) {
      if (Object.keys(isProductList)?.length > 0) {
        const { isProductListPutapi } = isProductList;
        if (isProductListPutapi) {
          setFileList([
            {
              uid: `${Date.now()}-${Math.random()}`, // Ensures uniqueness
              name: `image${Date.now()}-${Math.random()}.png`,
              status: 'done',
              url: ImageLink,
            },
          ]);
        } else {
          setFileList([]);
        }
      } else {
        // setFileList([]);
      }
    } else {
      // setFileList([]);
    }
  }, []);

  useEffect(() => {
    if (onlineImage !== '' && onlineImage != null && onlineImage != undefined) {
      setEditImageOpen(true);
      handleResizeImage(onlineImage);
    } else {
      setShapedImage(false);
      setCropImage(false);
    }
  }, [onlineImage]);

  useEffect(() => {
    if (fileList.length > 0) {
      const imageUrl = fileList?.[0]?.url;
      if (imageUrl !== '' && imageUrl !== null && imageUrl !== undefined) {
        handleResizeImage(imageUrl);
      } else {
        setShapedImage(false);
        setCropImage(false);
      }
    }
  }, [fileList]);

  const handleResizeImage = async (imageUrl) => {
    try {
      const resizedImageUrl = await resizeImage(imageUrl, 300, 150);
      setResizedImageUrl(resizedImageUrl);
    } catch (error) {
      console.error('Error resizing image:', error);
    }
  };

  const SetDefault = async () => {
    setEditImageOpen(false);
    setCroppedImage(null);
    setShapedData(null);
    setShapedImage(false);
    setCropImage(false);
    updateImageUrl(
      onlineImage !== '' && onlineImage != null
        ? onlineImage
        : fileList?.[0]?.['url'] != '' && fileList?.[0]?.['url'] != null
          ? fileList?.[0]?.['url']
          : ''
    );
    if (Object.keys(isProductList)?.length > 0) {
      const { isProductListPutapi, record, imagePutFunction } = isProductList;
      if (isProductListPutapi) {
        imagePutFunction(
          onlineImage !== '' && onlineImage != null
            ? onlineImage
            : fileList?.[0]?.['url'] != '' && fileList?.[0]?.['url'] != null
              ? fileList?.[0]?.['url']
              : '',
          record
        );
        handleClose();
        setMessageData("Image updated successfully");
        setMessageType("success");
      }
    }
  };

  const handleEditImageCancle = () => {
    setCroppedImage(null);
    setShapedData(null);
    setEditImageOpen(false);
    updateImageUrl('');
    setFileList([]);
    setShapedImage(false);
    setCropImage(false);
  };

  const handleSubmit = async () => {
    const base64 = croppedImage;
    const byteCharacters = atob(base64?.split(',')[1]);
    const byteNumbers = new Array(byteCharacters.length);
    for (let i = 0; i < byteCharacters.length; i++) {
      byteNumbers[i] = byteCharacters.charCodeAt(i);
    }
    const byteArray = new Uint8Array(byteNumbers);
    const blob = new Blob([byteArray], { type: 'image/png' });
    const file = new File([blob], 'cropped_image.png', { type: 'image/png' });
    try {
      await handleUpload({
        file,
        onSuccess: () => console.log('Upload successful'),
        onError: () => console.error('Upload failed'),
      });
      setEditImageOpen(false);
      await setCroppedImage(null);
      setShapedImage(false);
      setCropImage(false);
      handleClose();
      setMessageData("Image updated successfully");
      setMessageType("success");
    } catch (error) {
      console.error('Error in handleUpload:', error);
    }
  };

  const handleShapeSubmit = async () => {
    const base64 = shapedData[0];
    const byteCharacters = atob(base64?.split(',')[1]);
    const byteNumbers = new Array(byteCharacters.length);
    for (let i = 0; i < byteCharacters.length; i++) {
      byteNumbers[i] = byteCharacters.charCodeAt(i);
    }
    const byteArray = new Uint8Array(byteNumbers);
    const blob = new Blob([byteArray], { type: 'image/png' });
    const file = new File([blob], 'cropped_image.png', { type: 'image/png' });
    try {
      await handleUpload({
        file,
        onSuccess: () => console.log('Upload successful'),
        onError: () => console.error('Upload failed'),
      });
      setEditImageOpen(false);
      await setShapedData(null);
      setShapedImage(false);
      setCropImage(false);
      handleClose();
      setMessageData("Image updated successfully");
      setMessageType("success");
    } catch (error) {
      console.error('Error in handleUpload:', error);
    }
  };

  const handleCancel = () => setPreviewVisible(false);

  const onChange = async ({ fileList: newFileList }) => {
    setFileList(newFileList);

    if (Object.keys(isProductList)?.length > 0) {
      const { isProductListPutapi } = isProductList;
      if (isProductListPutapi && newFileList?.[0]?.originFileObj) {
        const file = newFileList[0].originFileObj;
        try {
          const res = await dispatch(uploadImage(file)).unwrap();
          if (res?.data?.status) {
            updateImageUrl(res?.data?.image);
            if (res?.data?.image) {
              setFileList([
                {
                  uid: `${Date.now()}-${Math.random()}`, // Ensures uniqueness
                  name: `image${Date.now()}-${Math.random()}.png`,
                  status: 'done',
                  url: res?.data?.image,
                },
              ]);
            }
          }
        } catch (error) {
          console.error('Image upload failed:', error);
        }
      }
    }

    if (newFileList?.length > 0) {
      setEditImageOpen(true);
    }
  };
  const onPreview = async (file) => {
    let src = file.url;
    if (!src) {
      src = await new Promise((resolve) => {
        const reader = new FileReader();
        reader.readAsDataURL(file.originFileObj);
        reader.onload = () => resolve(reader.result);
      });
    }
    setPreviewImage(src);
    setPreviewVisible(true);
  };

  const handleCrop = (croppedData) => {
    setCroppedImage(croppedData);
  };

  const handleShape = (shapedData) => {
    setShapedData(shapedData);
  };

  const handleUpload = async ({ file, onSuccess, onError }) => {
    try {
      if (!file) {
        console.error('File object is null or undefined.');
        onError();
        return;
      }

      const data = await dispatch(uploadImage(file)).unwrap();

      if (data?.data?.status) {
        if (Object.keys(isProductList)?.length > 0) {
          const { isProductListPutapi, record, imagePutFunction } =
            isProductList;
          if (isProductListPutapi) {
            imagePutFunction(data?.data?.image, record);
            setFileList([{ url: data?.data?.image }]);
            onSuccess(); // Trigger onSuccess to indicate a successful upload
            setCroppedImage(null);
            setShapedData(null);
          } else {
            updateImageUrl(data?.data?.image);
            setFileList([{ url: data?.data?.image }]);
            onSuccess(); // Trigger onSuccess to indicate a successful upload
            setCroppedImage(null);
            setShapedData(null);
          }
        } else {
          updateImageUrl(data?.data?.image);
          setFileList([{ url: data?.data?.image }]);
          onSuccess(); // Trigger onSuccess to indicate a successful upload
          setCroppedImage(null);
          setShapedData(null);
        }
      } else {
        console.error('API request was not successful:', data?.data?.error);
        onError(); // Trigger onError to indicate a failed upload
      }
    } catch (error) {
      console.error('Error calling API:', error);
      onError(); // Trigger onError in case of an error
    }
  };
  const handleRemove = () => {
    if (Object.keys(isProductList)?.length > 0) {
      const { isProductListPutapi, record, imagePutFunction } = isProductList;
      if (isProductListPutapi) {
        imagePutFunction('', record);
      }
    }
    updateImageUrl('');
    setEditImageOpen(false);
    setShapedImage(false);
    setCropImage(false);
  };

  const handleShapeCrop = () => {
    setShapedImage(true);
    setCropImage(false);
    setCroppedImage(null);
  };

  const handleCropTool = () => {
    setCropImage(true);
    setShapedImage(false);
    setShapedData(null);
  };

  function resizeImage(imageUrl, width, height) {
    if (!imageUrl) {
      // Handle the case where imageUrl is null or undefined
      console.error('Image URL is null or undefined.');
      return Promise.reject('Image URL is null or undefined.');
    }

    return new Promise((resolve, reject) => {
      const img = new Image();
      img.crossOrigin = 'anonymous'; // Set crossOrigin to handle cross-origin images
      img.onload = function () {
        const canvas = document.createElement('canvas');
        const ctx = canvas.getContext('2d');
        canvas.width = width;
        canvas.height = height;
        ctx.drawImage(img, 0, 0, width, height);
        const resizedImageUrl = canvas.toDataURL();
        resolve(resizedImageUrl);
      };
      img.onerror = function (error) {
        reject(error);
      };
      img.src = imageUrl;
    });
  }

  const beforeUpload = (file) => {
    const isAllowed = allowedTypes.includes(file.type);
    if (!isAllowed) {
      Modal.error({
        title: 'Invalid File Type',
        content:
          'Only JPG, JPEG, PNG, WEBP, SVG, GIF, and AVIF files are allowed.',
      });
    }
    return isAllowed || Upload.LIST_IGNORE; // prevents adding to fileList if invalid
  };

  const onComplete = useCallback(() => {
    setMessageData(null);
    setMessageType(null);
  }, []);

  return (
    <>
      <Messages
        messageType={messageType}
        messageData={messageData}
        onComplete={onComplete}
      />
      <div
        className={
          Object.keys(isProductList)?.length > 0
            ? fileList.length > 0
              ? 'cropUploadFieldSmall'
              : 'cropUploadFieldSmallNoData'
            : ''
        }
      >
        <Upload
          action="https://run.mocky.io/v3/435e224c-44fb-4773-9faf-380c5e6a2188"
          listType="picture-card"
          fileList={fileList}
          customRequest={handleUpload} // Use customRequest to handle the upload process manually
          onChange={onChange}
          onPreview={onPreview}
          onRemove={handleRemove}
          beforeUpload={beforeUpload}
        >
          {fileList.length < 1 && '+ Upload'}
        </Upload>
      </div>
      <Modal visible={previewVisible} onCancel={handleCancel} footer={null}>
        <img alt="Preview" style={{ width: '100%' }} src={previewImage} />
      </Modal>
      <DefaultModal
        title="Edit Image"
        width={800}
        open={editImageOpen}
        footer={
          (cropImage && croppedImage === null) ||
          (shapedImage && shapedData === null)
            ? false
            : true
        }
        buttonText="SUBMIT"
        children={
          <>
            <div className="shape-crop">
              {!croppedImage && !cropImage && !shapedImage && (
                <div>
                  <img
                    src={
                      onlineImage !== '' && onlineImage != null
                        ? onlineImage
                        : fileList?.[0]?.['url'] != '' &&
                            fileList?.[0]?.['url'] != null
                          ? fileList?.[0]?.['url']
                          : ''
                    }
                    style={{ width: '200px', height: '100px' }}
                    alt="Edit Image"
                  />
                </div>
              )}
              <div className="shape-crop-div">
                <div
                  className="crop-button"
                  style={{ backgroundColor: cropImage && '#52c41a' }}
                  onClick={() => handleCropTool()}
                >
                  <div>
                    <PiCropBold className="crop-icon" />
                  </div>
                  <div>Crop Tool</div>
                </div>
                <div
                  className="crop-button"
                  style={{ backgroundColor: shapedImage && '#52c41a' }}
                  onClick={() => handleShapeCrop()}
                >
                  <div>
                    <FiPenTool className="crop-icon" />
                  </div>
                  <div>Pen Tool</div>
                </div>
              </div>

              <div>
                {cropImage && (
                  <ImageCropper
                    imageUrl={
                      onlineImage !== '' && onlineImage != null
                        ? onlineImage
                        : fileList?.[0]?.['url'] != '' &&
                            fileList?.[0]?.['url'] != null
                          ? fileList?.[0]?.['url']
                          : ''
                    }
                    onCrop={handleCrop}
                  />
                )}

                {croppedImage && cropImage && (
                  <div
                    style={{
                      display: 'flex',
                      alignItems: 'center',
                      flexDirection: 'column',
                      gap: '2rem',
                    }}
                  >
                    <h4 style={{ marginLeft: '-33rem' }}>
                      Cropped Image Preview
                    </h4>
                    <img
                      src={croppedImage}
                      alt="Cropped Image"
                      style={{ width: '200px', height: '100px' }}
                    />
                  </div>
                )}
                {shapedImage && (
                  <ShapeCropper
                    imageUrl={
                      resizedImageUrl !== '' && resizedImageUrl !== null
                        ? resizedImageUrl
                        : ''
                    }
                    onShape={handleShape}
                  />
                )}
              </div>
            </div>
          </>
        }
        handleSubmit={
          croppedImage == null && shapedData == null
            ? SetDefault
            : croppedImage != null
              ? handleSubmit
              : handleShapeSubmit
        }
        handleCancel={handleEditImageCancle}
      />
    </>
  );
};

export default CropUpload;
