import React, {
  forwardRef,
  useEffect,
  useImperativeHandle,
  useRef,
  useState,
} from 'react';
import { useStyles } from './styles/customFileUploadStyles';
import {
  Box,
  Button,
  CircularProgress,
  Grid,
  InputLabel,
  Modal,
  Typography,
} from '@mui/material';
import { TransformWrapper, TransformComponent } from 'react-zoom-pan-pinch';
import Dropzone from 'react-dropzone';
import SaveAltIcon from '@mui/icons-material/SaveAlt';
import RemoveRedEyeOutlinedIcon from '@mui/icons-material/RemoveRedEyeOutlined';
import RemoveOutlinedIcon from '@mui/icons-material/RemoveOutlined';
import AddOutlinedIcon from '@mui/icons-material/AddOutlined';
import ZoomOutOutlinedIcon from '@mui/icons-material/ZoomOutOutlined';
import CloseIcon from '@mui/icons-material/Close';
import downloadIcon from '../assets/images/icon/download.svg';
import { pushNotification } from '../utils/notification';
import { FILE_TYPE, NOTIFICATION } from '../constants';
import uploadIcon from '../assets/images/icon/upload.svg';
import PdfIcon from '../assets/images/icon/pdf.png';
import DocIcon from '../assets/images/icon/doc.png';
import { fileUpload } from '../services/file.upload.services';
import { IMAGE_LOCATION_BASE_URL } from '../common/envVariables';

const CustomFileUpload = forwardRef(function CustomFileUpload(
  {
    documentName,
    label,
    saveFileName,
    onUploadDone,
    maxFileSizeInMb,
    maxFiles,
    uploadedFileUrl,
    errorMessage,
    isDisabled = false,
  },
  ref
) {
  const classes = useStyles();
  const imageRef = useRef(null);
  const fileInputRef = useRef(null);
  const [image, setImage] = useState(null);
  const [isLoading, setIsLoading] = useState(false);
  const [openPreview, setOpenPreview] = useState(false);
  const [imageName, setImageName] = useState(
    uploadedFileUrl ? uploadedFileUrl.split('/').pop() : ''
  );
  const [fileExtension, setFileExtension] = useState(
    uploadedFileUrl ? uploadedFileUrl.split('.').pop() : ''
  );
  const [oldUploadedFileUrl, setOldUploadedFileUrl] = useState(
    uploadedFileUrl ? uploadedFileUrl : ''
  );

  useImperativeHandle(ref, () => ({
    focus: () => {
      if (fileInputRef.current) {
        fileInputRef.current.focus();
      }
    },
    scrollIntoView: (...args) => {
      if (fileInputRef.current) {
        fileInputRef.current.scrollIntoView(...args);
      }
    },
  }));

  useEffect(() => {
    const makeFullUrlIfNeeded = (url) => {
      // Return early if url is undefined or empty
      if (!url) {
        setOldUploadedFileUrl('');
        setFileExtension('');
        setImageName('');
        return;
      }
      
      const isHttp = url.startsWith('http://') || url.startsWith('https://');
      if (!isHttp) {
        setOldUploadedFileUrl(`${IMAGE_LOCATION_BASE_URL}${url}`);
        setFileExtension(url.split('.').pop() || '');
        setImageName(url.split('/').pop() || '');
        return;
      }
      const urlObject = new URL(url);
      const fileName = urlObject.pathname.split('/').pop();
      setImageName(fileName);
      setFileExtension(fileName.split('.').pop());
      setOldUploadedFileUrl(url);
      return url;
    };
    makeFullUrlIfNeeded(uploadedFileUrl);
  }, [uploadedFileUrl]);

  const handleClearImage = () => {
    setImage(null);
    setImageName('');
    setFileExtension('');
    setOldUploadedFileUrl('');
    onUploadDone(documentName, '');
  };

  const handleFileUpload = async (value) => {
    if (!value) {
      return;
    }
    let formData = new FormData();
    formData.append('file', value);
    formData.append('fileName', value?.name);
    try {
      setIsLoading(true);
      const data = await fileUpload(formData);
      onUploadDone(documentName, data?.data?.data?.Key);
      return;
    } catch (error) {
      // console.error(error);
      pushNotification('Error while uploading file', NOTIFICATION.ERROR);
    } finally {
      setIsLoading(false);
    }
  };

  const handleDrop = async (acceptedFiles) => {
    const file = acceptedFiles[0];
    await handleFileUpload(file);
    setImage(file);
    setImageName(file.name);
    setOldUploadedFileUrl('');
    setFileExtension('');
  };

  const handelRejection = (rejectedFiles) => {
    rejectedFiles.forEach((rejection) => {
      pushNotification(
        `${rejection?.file?.name} :  ${rejection?.errors?.[0]?.message}`,
        NOTIFICATION.ERROR
      );
    });
  };

  const handlePreview = () => {
    setOpenPreview(true);
  };

  const handleClose = () => {
    setOpenPreview(false);
  };

  const handleDownload = () => {
    if (image) {
      const imageUrl = URL.createObjectURL(image);
      const anchor = document.createElement('a');
      anchor.href = imageUrl;
      anchor.download = saveFileName || imageName || 'Image';
      anchor.click();
    }
    if (oldUploadedFileUrl) {
      const imageUrl = oldUploadedFileUrl;
      const anchor = document.createElement('a');
      anchor.href = imageUrl;
      anchor.download = saveFileName || imageName || 'Image';
      anchor.click();
    }
  };

  const Controls = ({ zoomIn, zoomOut, resetTransform }) => (
    <>
      <Grid className={classes.controlButtons}>
        <Button
          className={`${classes.zoomOutButton}  ${classes.controlButton}`}
          onClick={() => zoomOut()}
        >
          <RemoveOutlinedIcon className={classes.iconSize} />
        </Button>
        <Button
          className={`${classes.zoomResetButton} ${classes.controlButton}`}
          onClick={() => resetTransform()}
        >
          <ZoomOutOutlinedIcon className={classes.iconSize} />
        </Button>
        <Button
          className={`${classes.zoomInButton} ${classes.controlButton}`}
          onClick={() => zoomIn()}
        >
          <AddOutlinedIcon className={classes.iconSize} />
        </Button>
      </Grid>
    </>
  );
  const FileUploadComponent = ({
    isLoading,
    fileUrl,
    fileExtension,
    maxFileSizeInMb,
    handlePreview,
    handleDownload,
    classes,
  }) => (
    <>
      <Box className={classes?.addButton}>
        <Box className={classes?.addButtonContent}>
          {isLoading ? (
            <CircularProgress />
          ) : (
            <>
              {fileUrl ? (
                <>
                  {fileExtension === 'pdf' ? (
                    <img
                      alt="Uploaded file"
                      src={PdfIcon}
                      height="125px"
                      width="auto"
                    />
                  ) : fileExtension === 'doc' ||
                    fileExtension === 'docx' ||
                    fileExtension ===
                      'vnd.openxmlformats-officedocument.wordprocessingml.document' ||
                    fileExtension === 'msword' ? (
                    <img
                      alt="Uploaded file"
                      src={DocIcon}
                      height="125px"
                      width="auto"
                    />
                  ) : (
                    <img
                      alt="Uploaded file"
                      src={fileUrl}
                      height="125px"
                      width="auto"
                    />
                  )}
                  <Box className={classes?.onImageButton}>
                    <button
                      type="button"
                      className={classes.eyeButton}
                      onClick={handlePreview}
                    >
                      <RemoveRedEyeOutlinedIcon className={classes.iconSize} />
                    </button>
                    <button
                      type="button"
                      className={classes.downloadButton}
                      onClick={handleDownload}
                    >
                      <SaveAltIcon className={classes.iconSize} />
                    </button>
                  </Box>
                </>
              ) : (
                <>
                  <Box
                    className={classes?.addIcon}
                    component="img"
                    src={uploadIcon}
                  />
                  <Typography className={classes?.addText}>
                    Drag and drop file here, or click add
                  </Typography>
                  <Typography className={classes.addSubtext}>
                    Allowed file types are jpeg, png, pdf, svg, doc to a maximum
                    size of {maxFileSizeInMb} MB
                  </Typography>
                </>
              )}
            </>
          )}
        </Box>
      </Box>
      {errorMessage && (
        <Box className={classes.errorMessage}>{errorMessage}</Box>
      )}
    </>
  );

  const PreviewComponent = ({
    fileUrl,
    fileExtension,
    handleDownload,
    classes,
  }) => (
    <>
      {fileExtension === 'pdf' ? (
        <>
          <Box className={classes.pdfAndDocPreviewBox}>
            <img
              alt="Uploaded file"
              src={PdfIcon}
              ref={imageRef}
              height="125px"
              width="auto"
            />
            <Button
              className={classes.pdfAndDocPreviewDownloadButton}
              variant="contained"
              onClick={handleDownload}
            >
              Download
            </Button>
          </Box>
        </>
      ) : fileExtension === 'doc' ||
        fileExtension === 'docx' ||
        fileExtension ===
          'vnd.openxmlformats-officedocument.wordprocessingml.document' ||
        fileExtension === 'msword' ? (
        <>
          <Box className={classes.pdfAndDocPreviewBox}>
            <img
              alt="Uploaded file"
              src={DocIcon}
              ref={imageRef}
              height="125px"
              width="auto"
            />
            <Button
              className={classes.pdfAndDocPreviewDownloadButton}
              variant="contained"
              onClick={handleDownload}
            >
              Download
            </Button>
          </Box>
        </>
      ) : (
        <TransformWrapper>
          {(utils) => (
            <React.Fragment>
              <Box className={classes.transFormImageBox}>
                <TransformComponent
                  wrapperClass={classes.customTransFormWrapper}
                >
                  <img
                    alt="Uploaded file"
                    src={fileUrl}
                    ref={imageRef}
                    height="250px"
                    width="auto"
                  />
                </TransformComponent>
              </Box>
              <Controls {...utils} />
            </React.Fragment>
          )}
        </TransformWrapper>
      )}
    </>
  );

  return (
    <>
      <Box className={classes.mainBox}>
        <InputLabel className={classes?.inputTitle}>
          {label}
          {(image || oldUploadedFileUrl) && (
            <div>
              {!isDisabled && (
                <button
                  className={classes.imgButton}
                  onClick={handleClearImage}
                >
                  REMOVE
                </button>
              )}
            </div>
          )}
        </InputLabel>
        <Box display="flex">
          <Box className={classes.dropZoneOuterBox}>
            <label htmlFor="file" ref={fileInputRef}>
              <Dropzone
                accept={{
                  'image/': [...FILE_TYPE],
                }}
                onDrop={handleDrop}
                onDropRejected={handelRejection}
                maxFiles={maxFiles}
                maxSize={maxFileSizeInMb * 1024 * 1024}
                disabled={isDisabled}
              >
                {({ getRootProps, getInputProps }) => (
                  <div
                    {...getRootProps({
                      onClick: (event) => {
                        if (image || oldUploadedFileUrl) {
                          event.stopPropagation();
                        }
                      },
                    })}
                  >
                    <input {...getInputProps()} />
                    {!oldUploadedFileUrl ? (
                      <>
                        <FileUploadComponent
                          isLoading={isLoading}
                          fileUrl={image ? URL.createObjectURL(image) : null}
                          fileExtension={
                            image ? image.type.split('/')[1] : null
                          }
                          maxFileSizeInMb={maxFileSizeInMb}
                          handlePreview={handlePreview}
                          handleDownload={handleDownload}
                          classes={classes}
                        />
                      </>
                    ) : (
                      <>
                        <FileUploadComponent
                          isLoading={isLoading}
                          fileUrl={oldUploadedFileUrl}
                          fileExtension={fileExtension}
                          maxFileSizeInMb={maxFileSizeInMb}
                          handlePreview={handlePreview}
                          handleDownload={handleDownload}
                          classes={classes}
                        />
                      </>
                    )}
                  </div>
                )}
              </Dropzone>
            </label>
          </Box>
        </Box>
      </Box>

      <Modal open={openPreview} onClose={handleClose}>
        <Box className={classes.previewFullScreenBox}>
          <Grid md={12} className={classes.previewHeading}>
            <Grid md={2}>
              <Button
                className={classes.previewDownloadButton}
                onClick={handleDownload}
              >
                <img
                  src={downloadIcon}
                  className={classes.previewDownloadIcon}
                />
              </Button>
              <Button
                onClick={handleClose}
                className={classes.previewCloseButton}
              >
                <CloseIcon className={classes.iconSize} />
              </Button>
            </Grid>
          </Grid>

          <Grid container>
            <Grid item md={12} className={classes.previewFileTitle}>
              <Typography color="white">{imageName}</Typography>
            </Grid>
          </Grid>

          <Grid xs={12} className={classes.previewImageGrid}>
            {!oldUploadedFileUrl ? (
              <>
                <PreviewComponent
                  fileUrl={image ? URL.createObjectURL(image) : null}
                  fileExtension={image ? image.type.split('/')[1] : null}
                  handlePreview={handlePreview}
                  handleDownload={handleDownload}
                  classes={classes}
                />
              </>
            ) : (
              <>
                <PreviewComponent
                  fileUrl={oldUploadedFileUrl}
                  fileExtension={fileExtension}
                  handlePreview={handlePreview}
                  handleDownload={handleDownload}
                  classes={classes}
                />
              </>
            )}
          </Grid>
        </Box>
      </Modal>
    </>
  );
});

export default CustomFileUpload;
