// material-ui
import { Box, Button, Grid, Typography } from '@mui/material';
import AppreciationForm from './AppreciationForm';
import { useContext, useEffect, useState } from 'react';
import * as React from 'react';
import axios from 'axios';
import { apiPath } from '../../auth/utils';
import {
  GET_APPRECIATION_FILE_PATH,
  GET_APPRECIATION_LIST,
  GET_APPRECIATION_STORAGE_SIZE,
  GET_THUMBNAIL_PATH,
  UPDATE_APPRECIATION_PATH
} from '../../utils/ApiPathConst';
import LoadingComponent from '../extra-pages/LoadingComponent';
import {
  GeneralConfirmWindow,
  getObjectById,
  notifyDeleteError,
  notifyDeleteSuccess,
  notifyNoPermission,
  notifySaveSuccess
} from '../../utils/CommonFunction';
import FileRefCard from './FileRefCard';
import { LIONER_BUTTON_THEME } from '../../themes/colorConst';
import { useNavigate, useParams } from 'react-router-dom';
import { ThemeProvider } from '@emotion/react';
import UploadContext from '../../components/UploadProvider';
import AbilityContext from '../../components/AbilityProvider';
import { isObjEmpty } from '../../utils/Utils';

import { LIONER_FORM_THEME } from '../../themes/themeConst';
import { useLocation } from 'react-router';

// ==============================|| DASHBOARD - DEFAULT ||============================== //

const ApplicationPanel = () => {
  const params = useParams();
  const navigate = useNavigate();
  const { setIsUploading } = useContext(UploadContext);
  const [isEditing, setIsEditing] = useState(false);
  const ability = useContext(AbilityContext);
  const location = useLocation();
  const queryParams = new URLSearchParams(location.search);
  const refId = queryParams.get('refId');

  const [onReady, setOnReady] = useState(false);
  const [isCollectData, setIsCollectData] = useState(false);
  const [userConfirm, setUserConfirm] = useState(false);
  const [isNewRecord, setIsNewRecord] = useState(false);
  const [appreciationDetail, setAppreciationDetail] = useState({});
  const [refFileList, setRefFileList] = useState([]);
  const [refSubDivisionList, setRefSubDivisionList] = useState([]);
  const [thumbnailList, setThumbnailList] = useState([]);
  const [usedFileSize, setUsedFileSize] = useState(0);

  // ==============================|| DELETE WINDOW RELATED ||============================== //
  const [isWindowOpen, setIsWindowOpen] = React.useState(false);

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

  const handleDeleteClick = () => {
    setIsWindowOpen(true);
  };

  function updateData() {
    if (refFileList.length > 0) {
      notifyDeleteError('Delete restricted. Attachment exists in this appreciation record.');
      setIsWindowOpen(false);
    } else {
      axios
          .delete(`${apiPath}${GET_APPRECIATION_LIST}/${params.id}`)
          .then((response) => {
            if (response.status === 204) {
              notifyDeleteSuccess();
              setIsWindowOpen(false);
              returnSearchPage();
            }
          })
          .catch((error) => {
            console.log(error);
            return false;
          });
    }
  }
  // ==============================|| DELETE WINDOW RELATED ||============================== //

  function updateAppreciationDetail(applicationData) {
    setAppreciationDetail(applicationData);
  }

  useEffect(() => {
    if (refId !== null) {
      setIsEditing(true);
      setIsNewRecord(true);
      getAppreciationDetail(refId);
    } else if (params.id < 0) {
      if (!ability.can('MAINTAIN', 'APPRECIATION')) {
        notifyNoPermission();
        navigate('/');
      }
      setIsEditing(true);
      setIsNewRecord(true);
    } else {
      getAppreciationDetail(params.id);
    }
    getFileList();
  }, []);

  useEffect(() => {
    if (!isObjEmpty(appreciationDetail)
        && (!isObjEmpty(thumbnailList) || refFileList.length === 0)
    ) {
      setOnReady(true);
    } else if (isNewRecord) {
      setOnReady(true);
    }
  }, [appreciationDetail, thumbnailList, refFileList]);

  function reloadData() {
    getAppreciationDetail(params.id);
    getFileList();
  }

  function reloadList() {
    getFileList();
  }

  const updateIsEdit = () => {
    setIsEditing(!isEditing);
  };

  function returnSearchPage() {
    navigate('/appreciation');
  }

  const submitData = () => {
    setUserConfirm(true);
    setIsCollectData(!isCollectData);
  };

  useEffect(() => {
    if (userConfirm && onReady) {
      postAppreciation();
      //console.log(appreciationDetail);
    }
    setUserConfirm(false);
  }, [appreciationDetail]);

  function postAppreciation() {
    setIsEditing(false);
    setIsUploading(true);
    axios
        .post(`${apiPath}${UPDATE_APPRECIATION_PATH}`, appreciationDetail, {
          headers: {
            'Content-Type': 'multipart/form-data'
          }
        })
        .then((response) => {
          if (response.status === 200) {
            notifySaveSuccess();
            if (isNewRecord) {
              setIsUploading(false);
              navigate('/appreciation');
            } else {
              setIsUploading(false);
              reloadData();
            }
            setIsCollectData(!isCollectData);
          }
        })
        .catch((error) => {
          setIsUploading(false);
          notifyDeleteError('Server busy, please try again later.');
          console.log(error);
          return false;
        });
  }


  function getFileList() {
    axios
        .get(`${apiPath}${GET_APPRECIATION_FILE_PATH}/${params.id}`)
        .then((response) => {
          if (response.status === 200) {
            setRefFileList(response.data.records);
            if(response.data.records.length >0){
              setThumbnailList([]);
              setOnReady(false);
            }
          }
        })
        .catch((error) => {
          console.log(error);
          return false;
        });
  }

  function getAppreciationDetail(appreciationId) {
    axios
        .get(`${apiPath}${GET_APPRECIATION_LIST}/${appreciationId}`)
        .then((response) => {
          if (response.status === 200) {
            setAppreciationDetail(response.data.data);
            setRefSubDivisionList(response.data.subDivisionList);
          }
        })
        .catch((error) => {
          console.log(error);
          return false;
        });
  }

  useEffect(() => {
    const tempList = [];
    if (refFileList.length > 0) {
      const promises = refFileList.reduce((accumulator, refFile) => {
        const promise = axios
            .get(`${apiPath}${GET_THUMBNAIL_PATH}/${refFile.id}/${refFile.skey}/${refFile.filename}`, { responseType: 'blob' })
            .then((response) => {
              if (response.status === 200) {
                const tempURL = URL.createObjectURL(new Blob([response.data], { type: refFile.mimetype }));
                if (getObjectById(thumbnailList, refFile.filename) === null) {
                  const thumbnail = {
                    id: refFile.id,
                    fileId: refFile.id,
                    skey: refFile.skey,
                    key: refFile.filename + refFile.id,
                    filename: refFile.filename,
                    mimetype: refFile.mimetype.split('/')[0],
                    remarks: refFile.remarks,
                    src: tempURL,
                    fileSize: response.data.size
                  };
                  return thumbnail;
                }
              }
            })
            .catch((error) => {
              console.log(error);
              // create a empty thumbnail object instead of block the form load
              const thumbnail = {
                id: refFile.id,
                fileId: refFile.id,
                skey: refFile.skey,
                key: refFile.filename + refFile.id,
                filename: refFile.filename,
                mimetype: refFile.mimetype.split('/')[0],
                remarks: refFile.remarks,
                fileSize: 0
              };
              return thumbnail;
            });

        accumulator.push(promise);
        return accumulator;
      }, []);

      Promise.all(promises)
          .then((thumbnails) => {
            const filteredThumbnails = thumbnails.filter((thumbnail) => thumbnail !== false);
            const arrCopy = Array.from(filteredThumbnails);
            arrCopy.sort((a, b) => a.key.localeCompare(b.key));
            setThumbnailList([...arrCopy]);
          })
          .catch((error) => {
            console.log(error);
          });
    } else {
      setThumbnailList(tempList);
    }

    axios
        .get(`${apiPath}${GET_APPRECIATION_STORAGE_SIZE}/${params.id}`)
        .then((response) => {
          if (response.status === 200) {
            setUsedFileSize(response.data.size);
          }
        })
        .catch((error) => {
          console.log(error);
          return false;
        });

  }, [refFileList]);

  return !onReady ? (
      <LoadingComponent />
  ) : (
      <Grid container rowSpacing={3} columnSpacing={2.75}>
        <ThemeProvider theme={LIONER_FORM_THEME}>
          <Grid item xs={12} md={12} lg={12}>
            <Grid container justifyContent="flex-start" alignItems="center">
              <Grid item xs={3} sx={{ mt: -1, mb: -2.25 }}>
                <Box sx={{ display: 'flex', alignItems: 'center' }}>
                  <Typography align="center" variant="h5">
                    {isNewRecord ? 'Maintain Appreciation Record' : 'Maintain Appreciation Record'}
                  </Typography>
                </Box>
              </Grid>
            </Grid>
          </Grid>

          {/*row 1*/}
          <Grid item xs={12} md={12} lg={12}>
            <AppreciationForm
                appreciationDetail={appreciationDetail}
                updateAppreciationDetail={updateAppreciationDetail}
                setUserConfirm={setUserConfirm}
                setIsCollectData={setIsCollectData}
                isCollectData={isCollectData}
                isNewRecord={isNewRecord}
                refSubDivisionList={refSubDivisionList}
                isEditing={isEditing}
                usedFileSize={usedFileSize}
                recordId={params.id}
            />
          </Grid>

          {/*row 2*/}
          {isEditing ? (
              <Grid container maxWidth justifyContent="space-between" sx={{ mt: 2 }}>
                <ThemeProvider theme={LIONER_BUTTON_THEME}>
                  <Grid item sx={{ mr: 3, mt: { xs: 2, md: 0 } }}>
                    <Grid container>
                      <Grid item sx={{ ml: 3, mr: 1.5, mb: 1 }}>
                        <Button variant="contained" type="submit" color="save" onClick={submitData}>
                          Save
                        </Button>
                      </Grid>
                      <Grid item sx={{ ml: 1.5, mr: 1.5, mb: 1 }}>
                        <Button variant="contained" type="submit" color="cancel" onClick={returnSearchPage}>
                          Cancel
                        </Button>
                      </Grid>
                      <Grid item sx={{ ml: { xs: 1.5, md: 1.5, lg: 1.5 }, mr: 3 }}>
                        <Button
                            variant="contained"
                            type="submit"
                            color="delete"
                            disabled={isNewRecord || !ability.can('MAINTAIN', 'APPRECIATION')}
                            onClick={handleDeleteClick}
                        >
                          Delete
                        </Button>
                        <GeneralConfirmWindow
                            isWindowOpen={isWindowOpen}
                            title={'Attention'}
                            //content={`Confirm to delete Award "${appreciationDetail.name}" ?`}
                            content={`Are you sure to delete this appreciation?`}
                            onNormalClose={handleClose}
                            onConfirmClose={updateData}
                        />
                      </Grid>
                    </Grid>
                  </Grid>
                </ThemeProvider>
              </Grid>
          ) : (
              <Grid container maxWidth justifyContent="space-between" sx={{ ml: 2, mr: 2 }}>
                <ThemeProvider theme={LIONER_BUTTON_THEME}>
                  <Grid item>
                    <Grid container>
                      <Grid item sx={{ ml: 1, mr: 3, mb: 1, mt: 2 }}>
                        <Button
                            variant="contained"
                            color="save"
                            onClick={updateIsEdit}
                            disabled={!ability.can('MAINTAIN', 'APPRECIATION')}
                        >
                          Edit
                        </Button>
                      </Grid>
                    </Grid>
                  </Grid>
                  <Grid item></Grid>
                </ThemeProvider>
              </Grid>
          )}

          {/*row 3*/}
          {params.id > 0 ? (
              <Grid sx={{ mt: -2 }} item xs={12} md={12} lg={12}>
                <FileRefCard
                    thumbnailList={thumbnailList}
                    applicationId={params.id}
                    reloadList={reloadList}
                    canEdit={!ability.can('MAINTAIN', 'APPRECIATION')}
                />
              </Grid>
          ) : (
              <Grid />
          )}
        </ThemeProvider>
      </Grid>
  );
};

export default ApplicationPanel;
