// material-ui
import {
    Grid, TextField, Typography
} from '@mui/material';
import MainCard from "../../components/MainCard";
import * as React from "react";
import {useForm} from "react-hook-form";
import {useEffect, useState} from "react";
import LoadingComponent from "../extra-pages/LoadingComponent";
import {Dashboard} from "@uppy/react";
import Uppy, { debugLogger } from '@uppy/core';
//import ThumbnailGenerator from '@uppy/thumbnail-generator';
import {useParams} from "react-router-dom";
// Don't forget the CSS: core and the UI components + plugins you are using.
import '@uppy/core/dist/style.min.css';
import '@uppy/dashboard/dist/style.min.css';
import '@uppy/webcam/dist/style.min.css';
//import * as XLSX from 'xlsx';
import {
    convertXmlToObject,
    getComboValueByIdList,
    getComboValueByLabel,
    getDeletedRecordWithRefList,
    getIdList, getNewRecordWithRefList, isOptionEqualToValue, isStringEmptyAfterTrim
} from "../../utils/CommonFunction";
import Autocomplete from "@mui/material/Autocomplete";
import axios from "axios";
import {apiPath} from "../../auth/utils";
import {
    CHECK_APPLICATION_DUPLICATE,
    GET_LDAP_USER_LIST, GET_SUB_DIVISION_COMBO_LIST,
    GET_TAG_COMBO_LIST
} from "../../utils/ApiPathConst";
import {GENERAL_RED_COLOR} from "../../themes/colorConst";
import {isObjEmpty} from "../../utils/Utils";
import {APPLICATION_STATUS_COMBO} from "../../utils/ComboConst";
import {parseString} from "xml2js";
import Qs from "qs";
import {CARD_MAX_WIDTH} from "../../themes/themeConst";
import {useLocation} from "react-router";

const uppyDashboard = new Uppy({
        autoProceed: true,
        logger: debugLogger,
        hideUploadButton: true,
        restrictions: {
            maxFileSize: 512 * 1024 * 1024, // 512 MB in bytes
        },
    })
        //.use(ThumbnailGenerator, {thumbnailWidth: 200})
        //.use(XHR, { endpoint: 'https://your-domain.com/upload' })
        ;

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

const ApplicationForm = ({eventDetail, applicationDetail, updateApplicationDetail,
                          isNewRecord, isCollectData, eventName,
                          refTagList, refSubDivisionList,
                          setIsCollectData, setUserConfirm, isEditing,
                          usedFileSize,videoCount,responseError
}) => {
    const params = useParams();
    const [onReady, setOnReady] = useState(false);
    const [errors, setErrors] = useState({});
    const [fileErrors, setFileErrors] = useState({});
    const location = useLocation();
    const queryParams = new URLSearchParams(location.search);
    const refId = queryParams.get("refId");

    const {register, getValues, setValue} = useForm();
    const [selectedStatus, setSelectedStatus] = useState(null);
    const [selectedOfficer, setSelectedOfficer] = useState(null);
    const [selectedSubDivision, setSelectedSubDivision] = useState([]);
    const [selectedTags, setSelectedTags] = useState([]);

    const [subDivisionList, setSubDivisionList] = useState([]);
    const [tagList, setTagList] = useState([]);
    const [isTagFetched, setIsTagFetched] = useState(false);
    const [refApplication, setRefApplication] = useState(null);

    const [lotusNoteUserList, setLotusNoteUserList] = useState([])
    const handleLocationCodeChange = (event, value) => {
        setSelectedOfficer({
            label: value,
        });
        if (value.length >2 && !value.includes("(")) {
            fetchLotusUserList(value, false);
        } else {
            setLotusNoteUserList(lotusNoteUserList);
        }
    };
    // Function to fetch user name options based on locationCode
    const fetchLotusUserList = async (input, isInit) => {
        try {
            axios.get(`${apiPath}${GET_LDAP_USER_LIST}`,{
                params:{
                    "EMSDlotus": input,
                }
            })
                .then((response) => {
                    if (response.status === 200) {
                        let xml = response.data;
                        parseString(xml, function (err, result) {
                            if(!isObjEmpty(refApplication) && isInit){
                                setSelectedOfficer({
                                    label: applicationDetail.responsibleOfficer,
                                });
                            }
                            setLotusNoteUserList(convertXmlToObject(result.RECORDS.RECORD));
                        });

                    }
                })
                .catch(error => {
                    console.log(error);
                    return false;
                });
        } catch (error) {
            console.error('Error fetching user name options:', error);
        }
    };

    uppyDashboard.on('file-added', (/*file*/) => {
        uppyDashboard.setOptions({
            hideUploadButton: true,
        });
    });

    useEffect(()=>{
        //if combo list ready
        if (isTagFetched && subDivisionList.length >0) {
            setRefApplication(applicationDetail);
        }
    },[subDivisionList,isTagFetched]);

    useEffect(()=>{
        //if ref data ready
        if (!isObjEmpty(refApplication)) {
            uppyDashboard.cancelAll()
            if(refId !== null){
                setValue("name", refApplication.name);
                setValue("description", refApplication.description);
            }
            //const locationCode = refApplication.responsibleOfficer.split('(')[1].replace(')','');
            fetchLotusUserList( refApplication.responsibleOfficer, true);
            setSelectedTags(getComboValueByIdList(tagList,refTagList));
            setSelectedSubDivision(getComboValueByIdList(subDivisionList,refSubDivisionList));
            setSelectedStatus(getComboValueByLabel(APPLICATION_STATUS_COMBO,refApplication.status));
        }
    },[refApplication]);

    useEffect(()=>{
        //if form data ready
        if(
            !isObjEmpty(applicationDetail) &&
            subDivisionList.length > 0 &&
            !isObjEmpty(selectedStatus) &&
            !isObjEmpty(selectedOfficer)
        ){
            setOnReady(true);
        }
        else if(params.id <0 && refId === null){
            setOnReady(true);
        }
    },[subDivisionList,applicationDetail, selectedStatus, selectedOfficer]);

    useEffect(()=>{
        if(!isObjEmpty(applicationDetail)){
                axios.get(`${apiPath}${GET_SUB_DIVISION_COMBO_LIST}`,{
                // axios.get(`${apiPath}${GET_SUB_DIVISION_COMBO_FOR_APPLICATION_LIST}`,{
                // params: {
                //     //"eventId": applicationDetail.eventId
                // },
                paramsSerializer: function (params) {
                    return Qs.stringify(params, { arrayFormat: 'repeat' });
                },
            })
                .then((response) => {
                    if (response.status === 200) {
                        setSubDivisionList(response.data.records);
                    }
                })
                .catch(error => {
                    console.log(error);
                    return false;
                });
        }
        else if(isNewRecord){
            axios.get(`${apiPath}${GET_SUB_DIVISION_COMBO_LIST}`,{
            // axios.get(`${apiPath}${GET_SUB_DIVISION_COMBO_FOR_APPLICATION_LIST}`,{
            //     params: {
            //         "eventId": params.eventId
            //     },
                paramsSerializer: function (params) {
                    return Qs.stringify(params, { arrayFormat: 'repeat' });
                },
            })
                .then((response) => {
                    if (response.status === 200) {
                        setSubDivisionList(response.data.records);
                    }
                })
                .catch(error => {
                    console.log(error);
                    return false;
                });
        }
    },[applicationDetail])

    useEffect(() => {
        uppyDashboard.cancelAll();
        //if state data are ready and assign to different field
        axios.get(`${apiPath}${GET_TAG_COMBO_LIST}`)
            .then((response) => {
                if (response.status === 200) {
                    setIsTagFetched(true);
                    setTagList(response.data.records);
                }
            })
            .catch(error => {
                console.log(error);
                return false;
            });

        if(isNewRecord && refId === null){
            setOnReady(true);
        }
    }, []);

    useEffect(() => {
        //upload latest data to parent
        if(isCollectData){
            const values = getValues();
            const uploadFileList = [];
            const fileList = uppyDashboard.getFiles();

            const files = uppyDashboard.getFiles();
            if(files.length > 0) {
                for (const file of fileList) {
                    uploadFileList.push(file.data);
                }
            }

            // console.log(usedFileSize);
            // console.log(videoCount);
            let totalSize = files.reduce((total, file) => total + file.size, 0);
            totalSize = totalSize/1024/1024;
            const videoFiles = files.filter(file =>
                file.type.startsWith('video/') || /\.(mp4|mov|avi|mkv)$/i.test(file.name)
            );
            const videoAttachCount = videoFiles.length;
            const formErrors = {};

            const fileErrors = {};
            if(totalSize + usedFileSize > 100.0){
                formErrors.fileSize = '-The total size of attachments exceeds the limit. Please notice that the size of the attachment is limited to 100MB per application and 500MB per award. You can only attach ' + Math.floor(100-usedFileSize) + " MB file more.";
                fileErrors.fileSize = '-The total size of attachments exceeds the limit. Please notice that the size of the attachment is limited to 100MB per application and 500MB per award. You can only attach ' + Math.floor(100-usedFileSize) + " MB file more.";

            }
            if(videoCount >= 1 && videoAttachCount >= 1){
                formErrors.fileRef = '-Total number of videos exceeds the limit, please delete existing uploaded video, or stop uploading new videos.';
                fileErrors.fileRef = '-Total number of videos exceeds the limit, please delete existing uploaded video, or stop uploading new videos.';
            }
            if(videoAttachCount>1){
                formErrors.fileRef = '-Total number of videos exceeds the limit, please delete existing uploaded video, or stop uploading new videos.';
                fileErrors.fileRef = '-Total number of videos exceeds the limit, please delete existing uploaded video, or stop uploading new videos.';
            }

            if (isStringEmptyAfterTrim(values.name)) {
                formErrors.name = 'Application Name is required';
            }

            if (selectedStatus == null){
                formErrors.status = 'Status is required';
            }

            if (selectedOfficer == null){
                formErrors.officer = 'Officer is required';
            }

            if (selectedSubDivision.length <= 0){
                formErrors.subDivision = 'Sub-Division is required';
            }

            setFileErrors(fileErrors);
            setErrors(formErrors);

            if (Object.keys(formErrors).length === 0) {
                axios.get(`${apiPath}${CHECK_APPLICATION_DUPLICATE}`,
                    {
                        params: {
                            "name": values.name,
                            "id": params.id,
                            "eventId": isNewRecord? params.eventId : refApplication.eventId,
                        },
                    })
                    .then((response) => {
                        if (response.status === 200) {
                            const formErrors = {};
                            if(response.data.isTaken){
                                formErrors.name = 'Application name must be unique.';
                                setErrors(formErrors);
                                setIsCollectData(false);
                                setUserConfirm(false);
                            }
                            else if(!response.data.isTaken){
                                if (Object.keys(formErrors).length === 0) {
                                    let formData = new FormData();
                                    formData.append("id", isNewRecord ? params.id : refApplication.id);
                                    formData.append("eventId", isNewRecord ? params.eventId : refApplication.eventId);
                                    formData.append("eventName", values.eventName);
                                    formData.append("description", values.description === null ? "" : values.description.trim());
                                    formData.append("name", values.name.trim());
                                    formData.append("responsibleOfficer", selectedOfficer == null ? "" : selectedOfficer.label.trim());
                                    formData.append("status", selectedStatus == null ? "" : selectedStatus.label);
                                    formData.append("subDivisionIdList", isNewRecord ? getIdList(selectedSubDivision) : selectedSubDivision == null ? [] : getNewRecordWithRefList(refSubDivisionList,getIdList(selectedSubDivision)));
                                    formData.append("subDivisionRemoveIdList", isNewRecord ? [] : selectedSubDivision == null ? [] : getDeletedRecordWithRefList(refSubDivisionList,getIdList(selectedSubDivision)));
                                    formData.append("tagIdList", isNewRecord ? (selectedTags === null ? [] : getIdList(selectedTags)) : (selectedTags === null ? [] : getNewRecordWithRefList(refTagList,getIdList(selectedTags))));
                                    formData.append("tagRemoveIdList", isNewRecord? [] : selectedTags == null ? [] : getDeletedRecordWithRefList(refTagList,getIdList(selectedTags)));
                                    for (const file of uploadFileList) {
                                        formData.append("files",file);
                                    }
                                    updateApplicationDetail(formData);
                                }
                            }
                        }
                    })
                    .catch(error => {
                        console.log(error);
                        return true;
                    });
            }
            else if(isCollectData){
                setUserConfirm(false);
                setIsCollectData(false);
            }
        }
    }, [isCollectData]);

    useEffect(() => {
        setErrors(responseError);
    }, [responseError]);

    return (
        !onReady ?
            <LoadingComponent/>
            :
            <MainCard elevation={0}
                      content={false}
                      sx={{width:CARD_MAX_WIDTH}}
            >
                <Typography variant="h5" sx={{mt: 3, ml: 3, mb: 1}}>
                    Information
                </Typography>

                <form>
                    <Grid container>
                        <Grid item xs={12} s={12} md={12} lg={8} sx={{mt:1, ml: 3, mr: 3, mb: 3}}>
                            <Grid container alignItems={"flex-start"}>
                                <Grid item xs={4} s={4} md={4} lg={2.7}
                                      sx={{ml: 3, mr: 3, display: 'flex', alignItems: 'center'}}>
                                    <Typography variant="lionerSize" component="span">
                                    Event Name:
                                    </Typography>
                                </Grid>

                                <Grid item xs={7} s={7} md={7} lg={8}>
                                    <Typography variant="lionerSize" component="span">
                                    {isNewRecord? eventDetail.name : eventName}
                                    </Typography>
                                </Grid>
                            </Grid>
                        </Grid>

                        <Grid item xs={12} s={12} md={12} lg={5.5} sx={{ml: 3, mr: 3, mb: 3}}>
                            <Grid container alignItems={"flex-start"}>
                                <Grid item xs={4} s={4} md={4} lg={4}
                                      sx={{ml: 3, mr: 3, mt:1, display: 'flex', alignItems: 'flex-start'}}>
                                    <Typography variant="body1" component="span">
                                        <Typography variant="lionerSize" component="span">
                                            Application Name:
                                        </Typography>
                                        <Typography sx={{ color: GENERAL_RED_COLOR }} component="span">*</Typography>
                                    </Typography>
                                </Grid>

                                <Grid item xs={7} s={7} md={7} lg={6}>
                                    <TextField
                                        fullWidth
                                        {...register("name",
                                            {
                                                value: applicationDetail.name,
                                            })}
                                        id='applicationName'
                                        required
                                        error={!!errors.name}
                                        helperText={errors.name}
                                        disabled={!isEditing}
                                        inputProps={{maxLength: 500, style: {fontSize: '1.1rem'}}}
                                        InputProps={{
                                            style: { minHeight:'42.5px', maxHeight: '50vh' },
                                        }}
                                        multiline
                                        maxRows={3}
                                        autoComplete="off"
                                    />
                                </Grid>
                            </Grid>
                        </Grid>

                        <Grid item xs={12} s={12} md={12} lg={5.5} sx={{ml: 3, mr: 3, mb: 3}}>
                            <Grid container alignItems={"flex-start"}>
                                <Grid item xs={4} s={4} md={4} lg={4}
                                      sx={{ml: 3, mr: 3, mt:1, display: 'flex', alignItems: 'flex-start'}}>
                                    <Typography variant="lionerSize" component="span">
                                        Application Description:
                                    </Typography>
                                </Grid>

                                <Grid item xs={7} s={7} md={7} lg={6}>
                                    <TextField
                                        fullWidth
                                        {...register("description",
                                            {
                                                value: applicationDetail.description,
                                            })}
                                        id='applicationDesc'
                                        required
                                        disabled={!isEditing}
                                        inputProps={{maxLength: 500, style: {fontSize: '1.1rem'}}}
                                        InputProps={{
                                            style: { minHeight:'42.5px', maxHeight: '50vh' },
                                        }}
                                        multiline
                                        maxRows={10}
                                        autoComplete="off"
                                    />
                                </Grid>
                            </Grid>
                        </Grid>

                        <Grid item xs={12} s={12} md={12} lg={5.5} sx={{ml: 3, mr: 3, mb: 3}}>
                            <Grid container alignItems={"flex-start"}>
                                <Grid item xs={4} s={4} md={4} lg={4}
                                      sx={{ml: 3, mr: 3, mt:1, display: 'flex', alignItems: 'flex-start'}}>
                                    <Typography variant="body1" component="span">
                                        <Typography variant="lionerSize" component="span">
                                            Status:
                                        </Typography>
                                        <Typography sx={{ color: GENERAL_RED_COLOR }} component="span">*</Typography>
                                    </Typography>
                                </Grid>

                                <Grid item xs={7} s={7} md={7} lg={6}>
                                    <Autocomplete
                                        disablePortal
                                        id="status-combo"
                                        size="small"
                                        value={selectedStatus === null? null : selectedStatus}
                                        options={APPLICATION_STATUS_COMBO}
                                        onChange={(event, newValue) => {
                                            setSelectedStatus(newValue);
                                        }}
                                        disabled={!isEditing}
                                        renderInput={(params) =>
                                            <TextField
                                                error={!!errors.status}
                                                helperText={errors.status}
                                                {...params}
                                                disabled={!isEditing}
                                            />}
                                        isOptionEqualToValue={isOptionEqualToValue}

                                    />
                                </Grid>
                            </Grid>
                        </Grid>

                        <Grid item xs={12} s={12} md={12} lg={5.5} sx={{ml: 3, mr: 3, mb: 3}}>
                            <Grid container alignItems={"center"}>
                                <Grid item xs={4} s={4} md={4} lg={4}
                                      sx={{ml: 3, mr: 3, display: 'flex', alignItems: 'center'}}>
                                    <Typography variant="body1" component="span">
                                        <Typography variant="lionerSize" component="span">
                                            Responsible Officer:
                                        </Typography>
                                        <Typography sx={{ color: GENERAL_RED_COLOR }} component="span">*</Typography>
                                    </Typography>
                                </Grid>

                                <Grid item xs={7} s={7} md={7} lg={6}>
                                    <Autocomplete
                                        disablePortal
                                        id="lotus-note-combo"
                                        value={selectedOfficer === null ? null : selectedOfficer}
                                        options={lotusNoteUserList}
                                        size="small"
                                        freeSolo
                                        onInputChange={handleLocationCodeChange}
                                        onChange={(event, newValue) => {
                                            setSelectedOfficer(newValue);
                                            // if(lotusNoteUserList.length >0){
                                            //     if(newValue !== null){
                                            //         if(getComboValueByLabel(lotusNoteUserList, newValue.label) !== null){
                                            //             setSelectedOfficer(newValue);
                                            //         }
                                            //     }
                                            //     else{
                                            //         setSelectedOfficer(null);
                                            //     }
                                            // }
                                        }}
                                        disabled={!isEditing}
                                        renderInput={(params) =>
                                            <TextField
                                                error={!!errors.officer}
                                                helperText={errors.officer}
                                                {...params}
                                                disabled={!isEditing}
                                                InputProps={{
                                                    ...params.InputProps,
                                                    inputProps: {
                                                        ...params.inputProps,
                                                        maxLength: 100
                                                    }
                                                }}
                                            />}
                                        //isOptionEqualToValue={isOptionEqualToValue}
                                    />
                                </Grid>
                            </Grid>
                        </Grid>

                        <Grid item xs={12} s={12} md={12} lg={5.5} sx={{ml: 3, mr: 3, mb: 3}}>
                            <Grid container alignItems={"flex-start"}>
                                <Grid item xs={4} s={4} md={4} lg={4}
                                      sx={{ml: 3, mr: 3, mt:1, display: 'flex', alignItems: 'flex-start'}}>
                                    <Typography variant="body1" component="span">
                                        <Typography variant="lionerSize" component="span">
                                            Sub-Divisions:
                                        </Typography>
                                        <Typography sx={{ color: GENERAL_RED_COLOR }} component="span">*</Typography>
                                    </Typography>
                                </Grid>

                                <Grid item xs={7} s={7} md={7} lg={6}>
                                    <Autocomplete
                                        multiple
                                        id="sub-division-demo"
                                        disablePortal
                                        size="small"
                                        options={subDivisionList}
                                        value={selectedSubDivision === null? [] : selectedSubDivision}
                                        getOptionLabel={(option) => option.label}
                                        onChange={(event, newValue) => {
                                            setSelectedSubDivision(newValue);
                                        }}
                                        disabled={!isEditing}
                                        renderInput={(params) => (
                                            <TextField
                                                error={!!errors.subDivision}
                                                helperText={
                                                    errors.subDivision ? (
                                                        <Typography component="div" color="error">
                                                            {errors.subDivision.split("\n").map((line, index) => {
                                                                return (
                                                                    <Typography key={index} >
                                                                        {line}
                                                                    </Typography>
                                                                )
                                                            })}
                                                        </Typography>
                                                    ) : null
                                                }
                                                {...params}
                                                placeholder=""
                                                disabled={!isEditing}
                                            />
                                        )}
                                        isOptionEqualToValue={isOptionEqualToValue}
                                    />
                                </Grid>
                            </Grid>
                        </Grid>

                        <Grid item xs={12} s={12} md={12} lg={5.5} sx={{ml: 3, mr: 3, mb: 3}}>
                            <Grid container alignItems={"flex-start"}>
                                <Grid item xs={4} s={4} md={4} lg={4}
                                      sx={{ml: 3, mr: 3, mt:1, display: 'flex', alignItems: 'flex-start'}}>
                                    <Typography variant="lionerSize" component="span">
                                        Tags:
                                    </Typography>
                                </Grid>

                                <Grid item xs={7} s={7} md={7} lg={6}>
                                    <Autocomplete
                                        multiple
                                        id="tag-multi-combo"
                                        disablePortal
                                        size="small"
                                        options={tagList}
                                        value={selectedTags === null? [] : selectedTags}
                                        getOptionLabel={(option) => option.label}
                                        onChange={(event, newValue) => {
                                            setSelectedTags(newValue);
                                        }}
                                        disabled={!isEditing}
                                        renderInput={(params) => (
                                            <TextField
                                                {...params}
                                                placeholder=""
                                                disabled={!isEditing}
                                            />
                                        )}
                                        isOptionEqualToValue={isOptionEqualToValue}
                                    />
                                </Grid>
                            </Grid>
                        </Grid>

                        {
                            isEditing ?
                                <Grid item xs={12} s={12} md={12} lg={12} sx={{ml:3,mr:3,mb:3}}>
                                    {
                                        fileErrors.fileSize ?
                                            <div>
                                                <Typography variant="lionerSize" sx={{ color: GENERAL_RED_COLOR, ml:1 }} component="span">{fileErrors.fileSize}</Typography>
                                            </div>
                                            :
                                            undefined
                                    }
                                    {
                                        fileErrors.fileRef ?
                                            <div>
                                                <Typography variant="lionerSize" sx={{ color: GENERAL_RED_COLOR, ml:1 }} component="span">{fileErrors.fileRef}</Typography>
                                            </div>
                                            :
                                            undefined
                                    }
                                    <div>
                                        <Typography variant="lionerSize" sx={{ml:1}}>
                                            You may upload supplementary material for record, including relevant photos or document
                                        </Typography>
                                    </div>
                                    <Dashboard
                                        uppy={uppyDashboard}
                                        hideUploadButton={true}
                                        width="100%"
                                        height="30vh"
                                    />
                                </Grid>
                                :
                                undefined
                        }

                    </Grid>
                </form>
            </MainCard>
    );
};

export default ApplicationForm;
