// material-ui
import { Box, Button, Grid, Typography } from '@mui/material';
import AwardForm from './AwardForm';
import { useContext, useEffect, useState } from 'react';
import * as React from 'react';
import axios from 'axios';
import { apiPath } from '../../auth/utils';
import {
  GET_APPLICATION_COMBO_PATH,
  GET_APPLICATION_PATH,
  GET_AWARD_FILE_PATH,
  GET_AWARD_PATH,
  GET_AWARD_STORAGE_SIZE,
  GET_AWARD_VIDEO_EXIST,
  GET_EVENT_COMBO_PATH,
  GET_EVENT_PATH,
  GET_SUB_DIVISION_COMBO_LIST,
  GET_THUMBNAIL_PATH,
  POST_AWARD_PATH
} from '../../utils/ApiPathConst';
import LoadingComponent from '../extra-pages/LoadingComponent';
import {
  GeneralConfirmWindow,
  GeneralTwoComboWindow,
  getObjectById,
  isUserDivisionIdInList,
  notifyDeleteError,
  notifyDeleteSuccess,
  notifyNoPermission,
  notifySaveSuccess
} from '../../utils/CommonFunction';
import FileRefCard from './FileRefCard';
import { LIONER_BUTTON_THEME, LIONER_LONG_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 [awardDetail, setAwardDetail] = useState({});
  const [subDivisionCombo, setSubDivisionCombo] = useState([]);
  const [refFileList, setRefFileList] = useState([]);
  const [refSubDivisionList, setRefSubDivisionList] = useState([]);
  const [thumbnailList, setThumbnailList] = useState([]);
  const [eventDetail, setEventDetail] = useState({});
  const [applicationDetail, setApplicationDetail] = useState({});
  const [usedFileSize, setUsedFileSize] = useState(0);
  const [videoCount, setVideoCount] = useState(0);
  //const [tagCombo, setTagCombo] = useState({});

  // ==============================|| 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 award.');
      setIsWindowOpen(false);
    } else {
      axios
        .delete(`${apiPath}${GET_AWARD_PATH}/${params.id}`)
        .then((response) => {
          if (response.status === 204) {
            notifyDeleteSuccess();
            setIsWindowOpen(false);
            returnSearchPage();
          }
        })
        .catch((error) => {
          console.log(error);
          return false;
        });
    }
  }
  // ==============================|| DELETE WINDOW RELATED ||============================== //

  // ==============================|| NEW WINDOW RELATED START ||============================== //
  const [isCopyWindowOpen, setIsCopyWindowOpen] = React.useState(false);
  const [eventList, setEventList] = useState([]);
  const [applicationList, setApplicationList] = useState([]);
  const [selectedEvent, setSelectedEvent] = useState(null);
  const [selectedApplication, setSelectedApplication] = useState(null);
  const [eventName, setEventName] = useState("");
  const [applicationName, setApplicationName] = useState("");

  const handleCopyClose = () => {
    setIsCopyWindowOpen(false);
  };

  function updateCopyData() {
    setIsCopyWindowOpen(false);
    navigate(`/award/maintain/-1/${selectedEvent.id}/${selectedApplication.id}?refId=${params.id}`);
  }

  const createNewAward = () => {
    setIsCopyWindowOpen(true);
  };
  // ==============================|| NEW WINDOW RELATED END ||============================== //

  function updateAwardDetail(applicationData) {
    setAwardDetail(applicationData);
  }

  useEffect(() => {
    if (refId !== null) {
      setIsEditing(true);
      setIsNewRecord(true);
      getAwardDetail(refId);
      getEventDetail();
      getApplicationDetail();
    } else if (params.id < 0) {
      if (!ability.can('EDIT', 'APPLICATION')) {
        notifyNoPermission();
        navigate('/');
      }
      setIsEditing(true);
      setIsNewRecord(true);
      getEventDetail();
      getApplicationDetail();
    } else {
      getAwardDetail(params.id);
    }
    getGroupList();
    getFileList();
    getApplicationCombo();
    getEventCombo();
  }, []);

  useEffect(() => {
    if(selectedEvent !== null && Object.keys(selectedEvent).length >= 0){
      getApplicationCombo(selectedEvent.id);
    }
  }, [selectedEvent]);


  useEffect(() => {
    if (Object.keys(subDivisionCombo).length > 0
        && !isObjEmpty(awardDetail)
        && (!isObjEmpty(thumbnailList) || refFileList.length === 0)
    ) {
      setOnReady(true);
    } else if (isNewRecord && Object.keys(eventDetail).length > 0
        && Object.keys(applicationDetail).length > 0
    ) {
      setOnReady(true);
    }
  }, [subDivisionCombo, applicationDetail, eventDetail, awardDetail, thumbnailList, refFileList]);

  function reloadData() {
    getAwardDetail(params.id);
    getGroupList();
    getFileList();
  }

  function reloadList() {
    getFileList();
  }

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

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

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

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

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

  function getApplicationDetail() {
    axios
      .get(`${apiPath}${GET_APPLICATION_PATH}/${params.applicationId}`)
      .then((response) => {
        if (response.status === 200) {
          setApplicationDetail(response.data.data);
        }
      })
      .catch((error) => {
        console.log(error);
        return false;
      });
  }

  function getEventDetail() {
    axios
      .get(`${apiPath}${GET_EVENT_PATH}/${params.eventId}`)
      .then((response) => {
        if (response.status === 200) {
          setEventDetail(response.data.data);
        }
      })
      .catch((error) => {
        console.log(error);
        return false;
      });
  }

  function getEventCombo() {
    axios
      .get(`${apiPath}${GET_EVENT_COMBO_PATH}`, {
        params: {
          userSubDivisionId: ability.can('EDIT', 'ALL_RECORD') ? null : localStorage.getItem('subDivisionId')
        }
      })
      .then((response) => {
        if (response.status === 200) {
          setEventList(response.data.records);
        }
      })
      .catch((error) => {
        console.log(error);
        return false;
      });
  }

  function getApplicationCombo(eventId) {
    axios
      .get(`${apiPath}${GET_APPLICATION_COMBO_PATH}`, {
        params: {
          eventId: eventId,
          userSubDivisionId: ability.can('EDIT', 'ALL_RECORD') ? null : localStorage.getItem('subDivisionId')
        }
      })
      .then((response) => {
        if (response.status === 200) {
          setApplicationList(response.data.records);
        }
      })
      .catch((error) => {
        console.log(error);
        return false;
      });
  }

  function getGroupList() {
    axios
      .get(`${apiPath}${GET_SUB_DIVISION_COMBO_LIST}`)
      .then((response) => {
        if (response.status === 200) {
          setSubDivisionCombo(response.data.records);
        }
      })
      .catch((error) => {
        console.log(error);
        return false;
      });
  }

  function getFileList() {
    axios
      .get(`${apiPath}${GET_AWARD_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 getAwardDetail(awardId) {
    axios
      .get(`${apiPath}${GET_AWARD_PATH}/${awardId}`)
      .then((response) => {
        if (response.status === 200) {
          setAwardDetail(response.data.data);
          setEventName(response.data.data.eventName);
          setApplicationName(response.data.data.applicationName);
          setRefSubDivisionList(response.data.subDivisionList);
        }
      })
      .catch((error) => {
        console.log(error);
        return false;
      });
  }

  useEffect(() => {
    const tempList = [];
    if (refFileList.length > 0) {
      // for(let i=0 ; i < refFileList.length ; i++){
      //     axios.get(`${apiPath}${GET_THUMBNAIL_PATH}/${refFileList[i].id}/${refFileList[i].skey}/${refFileList[i].filename}`,
      //         { responseType: 'blob' })
      //         .then((response) => {
      //             if (response.status === 200) {
      //                 const tempURL = URL.createObjectURL(new Blob([response.data],{type: refFileList[i].mimetype}));
      //                 if(getObjectById(thumbnailList,refFileList[i].filename) === null){
      //                     tempList.push({
      //                         "id": refFileList[i].id,
      //                         "fileId": refFileList[i].id,
      //                         "skey": refFileList[i].skey,
      //                         "key": refFileList[i].filename,
      //                         "mimetype": refFileList[i].mimetype.split('/')[0],
      //                         "remarks": refFileList[i].remarks,
      //                         "src": tempURL,
      //                         "fileSize": response.data.size,
      //                     });
      //                     setThumbnailList([...tempList]);
      //                 }
      //             }
      //         })
      //         .catch(error => {
      //             console.log(error);
      //             return false;
      //         });
      // }
      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_AWARD_STORAGE_SIZE}/${params.id}`)
      .then((response) => {
        if (response.status === 200) {
          setUsedFileSize(response.data.size);
        }
      })
      .catch((error) => {
        console.log(error);
        return false;
      });

    axios
      .get(`${apiPath}${GET_AWARD_VIDEO_EXIST}/${params.id}`)
      .then((response) => {
        if (response.status === 200) {
          setVideoCount(response.data.count);
        }
      })
      .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 ? 'New Award' : 'Maintain Award'}
                </Typography>
              </Box>
            </Grid>
          </Grid>
        </Grid>

        {/*row 1*/}
        <Grid item xs={12} md={12} lg={12}>
          <AwardForm
            eventName={eventName}
            applicationName={applicationName}
            eventDetail={eventDetail}
            applicationDetail={applicationDetail}
            awardDetail={awardDetail}
            updateAwardDetail={updateAwardDetail}
            setUserConfirm={setUserConfirm}
            setIsCollectData={setIsCollectData}
            isCollectData={isCollectData}
            isNewRecord={isNewRecord}
            refSubDivisionList={refSubDivisionList}
            isEditing={isEditing}
            usedFileSize={usedFileSize}
            videoCount={videoCount}
          />
        </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('DELETE', 'AWARD')}
                      onClick={handleDeleteClick}
                    >
                      Delete
                    </Button>
                    <GeneralConfirmWindow
                      isWindowOpen={isWindowOpen}
                      title={'Attention'}
                      //content={`Confirm to delete Award "${awardDetail.name}" ?`}
                      content={`Are you sure to delete this award?`}
                      onNormalClose={handleClose}
                      onConfirmClose={updateData}
                    />
                  </Grid>
                </Grid>
              </Grid>
              <Grid item sx={{ ml: 3, mr: 4, mt: { xs: 2, md: 0 } }}>
                <ThemeProvider theme={LIONER_LONG_BUTTON_THEME}>
                  <Button variant="contained" color="saveAs" onClick={createNewAward} disabled={isNewRecord}>
                    Copy as new
                  </Button>
                </ThemeProvider>
                <GeneralTwoComboWindow
                  isWindowOpen={isCopyWindowOpen}
                  title={'New Award'}
                  content={'Event'}
                  content2={'Application'}
                  comboList={eventList}
                  comboList2={applicationList}
                  setValueCallback={setSelectedEvent}
                  setValueCallback2={setSelectedApplication}
                  onNormalClose={handleCopyClose}
                  onConfirmClose={updateCopyData}
                />
              </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('EDIT', 'ALL_RECORD')
                          ? false
                          : !(
                              ability.can('EDIT', 'AWARD') &&
                              isUserDivisionIdInList(localStorage.getItem('subDivisionId'), refSubDivisionList)
                            )
                      }
                    >
                      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('EDIT', 'ALL_RECORD')
                  ? false
                  : !(
                      ability.can('EDIT', 'APPLICATION') &&
                      isUserDivisionIdInList(localStorage.getItem('subDivisionId'), refSubDivisionList)
                    )
              }
            />
            {/*<FilePreviewGrid fileList={thumbnailList}/>*/}
          </Grid>
        ) : (
          <Grid />
        )}
      </ThemeProvider>
    </Grid>
  );
};

export default ApplicationPanel;
