
import { OUTPUT_DATE_FORMAT } from "@/app/utils/formatUtil";
import { Check, SwapHoriz, Add } from "@mui/icons-material";
import { Box, Button, Card, Grid, Modal, Stack, TextField, Typography } from "@mui/material";
import { DatePicker, DateTimePicker, LocalizationProvider } from "@mui/x-date-pickers";
import { AdapterDayjs } from "@mui/x-date-pickers/AdapterDayjs";
import dayjs, { Dayjs } from "dayjs";
import React, { useCallback, useEffect, useMemo, useState } from "react";
import { useTranslation } from "react-i18next";
import { msg } from "../Swal/CustomAlerts";
import ShelfLifeInput from "./ShelfLifeInput";

interface Props {
    open: boolean;
    onClose: () => void;
    onSubmit: (result: Dayjs) => void;
    textfieldSx?: any;
}

type EntryError =
    {
    productionDate: string,
    expiryDate: string,
    shelfLife: string,
    }

const CalculateExpiryDateModal: React.FC<Props> = ({
    open,
    onClose,
    onSubmit,
    textfieldSx,
}) => {
    const { t, i18n: { language }, } = useTranslation("purchaseOrder");

    const [productionDate, setProductionDate] = useState<Dayjs>();
    const [shelfLife, setShelfLife] = useState<number>();
    const [expiryDate, setExpiryDate] = useState<Dayjs>();
    const [errors, setErrors] = useState<EntryError>({ productionDate: "", expiryDate: "", shelfLife: "" });

    const onModalClose = useCallback(() => {
        setProductionDate(undefined);
        setExpiryDate(undefined);
        setShelfLife(undefined);
        onClose();
    }, [])

    const handleSubmit = useCallback(() => {
        if (expiryDate) {
            onSubmit(expiryDate);
        }
        onModalClose();
    }, [onModalClose, expiryDate])

    const hasError = useMemo(() => {
        return Object.values(errors).some(err => err.length > 0);
    }, [errors])

    // Validation
    useEffect(() => {
        let err = { productionDate: "", expiryDate: "", shelfLife: "" };

        // Check Expiry Date
        if (expiryDate !== undefined) {
            // Check Validity (If allow input for Expiry Date)
            // if (!expiryDate.isValid()) { err = ({...err, expiryDate: t("Invalid Date")}); } else
            // Check date logic
            if (shelfLife === undefined && productionDate && expiryDate.isBefore(productionDate)) {
                err = ({...err, expiryDate: t("Expiry Date cannot be earlier than Production Date")});
            }
        }

        // Check Production Date
        if (productionDate !== undefined) {
            // Check Validity
            if (!productionDate.isValid()) { err = ({...err, productionDate: t("Invalid Date")}); }
            // Check date logic
            else if (shelfLife === undefined && expiryDate && productionDate.isAfter(expiryDate)) {
                err = ({...err, productionDate: t("Production Date must be earlier than Expiry Date")});
            }
        }

        // Check Shelf Life
        // if (shelfLife === undefined) {
        //     err = ({...err, shelfLife: t("Shelf Life must be greater than 0")});
        // }
        
        setErrors(err);
    }, [expiryDate, productionDate, shelfLife]);

    const calculateDates = useCallback((value: Dayjs | number | null = null,
            valueType: "productionDate" | "shelfLife" | "expiryDate" | undefined = undefined) => {

        let pd = productionDate;
        let ed = expiryDate;
        let sl = shelfLife;

        if (value !== null && value !== undefined) {
            if (dayjs.isDayjs(value)) {
                if (valueType == "expiryDate") {
                    ed = value;
                } else {
                    pd = value;
                }
            } else if (!isNaN(value)) {
                sl = value;
            } else {
                console.log("%c Invalid input value for calculation", "color:red", value);
                return;
            }
        } else {
            if (valueType !== undefined) {
                ed = undefined; // Clear Expiry Date if fields are cleared
                switch (valueType) {
                    case "productionDate": pd = undefined; break;
                    case "shelfLife": sl = undefined; break;
                    // case "expiryDate": ed = undefined; break;
                    default: console.log("%c Invalid value type for calculation", "color:red", valueType); return;
                }
            }
        }

        if (pd && ed && sl !== undefined) { // If all values are set
            if (valueType == "expiryDate") {    // If updating Expiry Date -> Change Production Date
                const result = ed.add(sl * -1, "day");
                setProductionDate(result);
            } else {    // If not updating Expiry Date -> Change Expiry Date
                const result = pd.add(sl, "day");
                setExpiryDate(result);
            }

        } else if (pd && sl !== undefined) { // Set Expiry Date
            const result = pd.add(sl, "day");
            if (result.isValid()) { setExpiryDate(result); }
        } else if (sl !== undefined && ed) {  // Set Production Date
            const result = ed.add(sl * -1, "day");
            if (result.isValid()) { setProductionDate(result); }
        } else if (pd && ed) {  // Set Shelf Life
            const result = ed.diff(pd, "day");
            if (!isNaN(result) && result > 0) { setShelfLife(result); }
        } else {
            setExpiryDate(undefined);
        }
    }, [productionDate, shelfLife, expiryDate]);

    useEffect(() => {
        if (!open) return;
        const today = dayjs();
        // only set if different to avoid loop
        setProductionDate(prev => (prev && prev.isSame(today, "day") ? prev : today));
        if (shelfLife !== undefined) {
            setExpiryDate(today.add(shelfLife, "day"));
        }
    }, [open, shelfLife]);

    return (
        <Modal
            open={open}
            onClose={onModalClose}
        >
            <Card
                style={{
                    flex: 10,
                    marginBottom: "20px",
                    width: "80%",
                    // height: "80%",
                    position: "fixed",
                    top: "50%",
                    left: "50%",
                    transform: "translate(-50%, -50%)",
                }}
            >
                <Box
                    sx={{
                        display: "block",
                        "flex-direction": "column",
                        padding: "20px",
                        height: "100%", //'30rem',
                        width: "100%",
                        "& .actions": {
                            color: "text.secondary",
                        },
                        "& .header": {
                        },
                        "& .textPrimary": {
                            color: "text.primary",
                        },
                    }}
                >
                    <LocalizationProvider
                        dateAdapter={AdapterDayjs}
                        adapterLocale={`${language}-hk`}
                    >
                        <Stack sx={{mb: 1}}>
                            <Typography variant="h4" component="h2" sx={{ fontWeight: 'bold', mb: 2 }}>
                            {t("Fill in Expiry Date")}
                            </Typography>
                        </Stack>
                        <Stack>
                            <Grid
                                container
                                justifyContent="flex-start"
                                alignItems="flex-start"
                                spacing={2}
                            >
                                <Grid item xs={2.5}>
                                    <DatePicker
                                        sx={textfieldSx}
                                        label={t("productionDate")}
                                        value={productionDate ? dayjs(productionDate) : null}
                                        format={OUTPUT_DATE_FORMAT}
                                        onChange={(date) => {
                                            if (!date) {
                                                setProductionDate(undefined);
                                            } else {
                                                setProductionDate(date);
                                            }
                                            calculateDates(date, "productionDate");
                                        }}
                                        slotProps={{
                                            textField: {
                                              error: errors.productionDate.length > 0,
                                              helperText: errors.productionDate,
                                            },
                                        }}
                                    />
                                </Grid>
                                <Grid item xs={0.5} sx={{
                                        display: 'flex',
                                        justifyContent: 'center',
                                        alignItems: 'center',
                                        height: '100%',
                                    }}>
                                    <Add sx={{
                                        fontSize: '60px', color:'secondary.main',
                                        transform: 'translate(10%, 15%)',
                                        }}/>
                                </Grid>
                                <Grid item xs={4}>
                                    <ShelfLifeInput
                                        sx={textfieldSx}
                                        value={shelfLife}
                                        label={t("shelfLife")}
                                        onChange={(value) => {
                                            const val = value == 0 ? undefined : value;
                                            setShelfLife(val);
                                            calculateDates(val, "shelfLife");
                                        }}
                                    />
                                </Grid>

                                <Grid item xs={1} sx={{
                                        display: 'flex',
                                        justifyContent: 'center',
                                        alignItems: 'center',
                                        height: '100%',
                                    }}>
                                    <SwapHoriz sx={{fontSize: '80px', color:'secondary.main'}}/>
                                </Grid>
                                <Grid item xs={4}>
                                    <DatePicker
                                        sx={textfieldSx}
                                        label={t("expiryDate")}
                                        format={OUTPUT_DATE_FORMAT}
                                        value={expiryDate ? dayjs(expiryDate) : null}
                                        onChange={(date) => {
                                            if (!date) {
                                                setExpiryDate(undefined);
                                            } else {
                                                setExpiryDate(date);
                                                calculateDates(date, "expiryDate");
                                            }
                                        }}
                                        slotProps={{
                                            textField: {
                                              error: errors.expiryDate.length > 0,
                                              helperText: errors.expiryDate,
                                            },
                                        }}
                                        disabled={true}
                                    />
                                </Grid>
                            </Grid>
                        </Stack>
                        <Stack
                            direction="row"
                            justifyContent="flex-end"
                            spacing={2}
                            sx={{ mt: 2 }}
                        >
                            <Button
                                name="submit"
                                variant="contained"
                                startIcon={<Check />}
                                sx={{fontSize: '24px'}}
                                disabled={expiryDate === undefined || hasError}
                                onClick={handleSubmit}
                            >
                                {t("confirm expiry date")}
                            </Button>
                        </Stack>
                    
                    </LocalizationProvider>
                </Box>
            </Card>
        </Modal>
    )
}

export default CalculateExpiryDateModal;