
import { OUTPUT_DATE_FORMAT } from "@/app/utils/formatUtil";
import { Check, SwapHoriz, Add } from "@mui/icons-material";
import { Box, Button, Card, FormHelperText, Modal, Stack, 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 INPUT_HEIGHT = "5rem";
const ICON_COL_WIDTH = 48;

const iconColumnSx = {
    width: ICON_COL_WIDTH,
    minWidth: ICON_COL_WIDTH,
    height: INPUT_HEIGHT,
    display: "flex",
    alignItems: "center",
    justifyContent: "center",
    flexShrink: 0,
};

const columnSx = {
    flex: { sm: "1 1 22%" },
    minWidth: { sm: 180 },
    width: { xs: "100%", sm: "auto" },
};

const shelfColumnSx = {
    flex: { sm: "1 1 28%" },
    minWidth: { sm: 200 },
    width: { xs: "100%", sm: "auto" },
};

const rowSx = {
    display: "flex",
    flexDirection: { xs: "column", sm: "row" },
    gap: { xs: 2, sm: 2 },
    overflowX: { sm: "auto" },
};

const defaultModalFieldSx = {
    width: "100%",
    "& .MuiInputBase-root": {
        height: INPUT_HEIGHT,
    },
    "& .MuiInputBase-input": {
        height: "100%",
        boxSizing: "border-box",
        padding: "0.75rem 2.75rem 0.75rem 0.75rem",
        fontSize: { xs: 22, sm: 26 },
        "&::placeholder": {
            fontSize: { xs: 20, sm: 24 },
            opacity: 0.55,
        },
    },
    "& .MuiInputLabel-root": {
        display: "none",
    },
};

const hiddenPickerLabelProps = {
    shrink: true,
    sx: { display: "none" },
};

const FieldLabel: React.FC<{ children: React.ReactNode; sx?: object }> = ({ children, sx }) => (
    <Typography
        component="div"
        sx={{
            fontWeight: 600,
            fontSize: { xs: "0.95rem", sm: "1.05rem" },
            lineHeight: 1.4,
            color: "text.secondary",
            ...sx,
        }}
    >
        {children}
    </Typography>
);

const CalculateExpiryDateModal: React.FC<Props> = ({
    open,
    onClose,
    onSubmit,
    textfieldSx,
}) => {
    const { t, i18n: { language }, } = useTranslation("purchaseOrder");
    const fieldSx = {
        ...(textfieldSx ?? defaultModalFieldSx),
        "& .MuiInputLabel-root": { display: "none" },
        "& .MuiInputBase-input::placeholder": {
            fontSize: { xs: 20, sm: 24 },
            opacity: 0.55,
        },
    };

    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
                sx={{
                    position: "fixed",
                    top: "50%",
                    left: "50%",
                    transform: "translate(-50%, -50%)",
                    width: { xs: "96%", sm: "94%", md: "92%" },
                    minWidth: { sm: 640, md: 820 },
                    maxWidth: 1100,
                    maxHeight: "90vh",
                    overflowY: "auto",
                    overflowX: "visible",
                }}
            >
                <Box
                    sx={{
                        display: "block",
                        "flex-direction": "column",
                        padding: { xs: 3, sm: 4 },
                        height: "100%",
                        width: "100%",
                        overflow: "visible",
                        "& .actions": {
                            color: "text.secondary",
                        },
                        "& .header": {
                        },
                        "& .textPrimary": {
                            color: "text.primary",
                        },
                    }}
                >
                    <LocalizationProvider
                        dateAdapter={AdapterDayjs}
                        adapterLocale={`${language}-hk`}
                    >
                        <Stack sx={{ mb: 1 }}>
                            <Typography
                                variant="h6"
                                component="h2"
                                sx={{ fontWeight: "bold", mb: 2, fontSize: { xs: "1.25rem", sm: "1.5rem" } }}
                            >
                                {t("Fill in Expiry Date")}
                            </Typography>
                        </Stack>
                        <Box sx={{ overflow: "visible" }}>
                            {/* Label row */}
                            <Box sx={{ ...rowSx, mb: 0.75 }}>
                                <Box sx={columnSx}>
                                    <FieldLabel>{t("productionDate")}</FieldLabel>
                                </Box>
                                <Box sx={{ width: ICON_COL_WIDTH, flexShrink: 0, display: { xs: "none", sm: "block" } }} aria-hidden />
                                <Box sx={shelfColumnSx}>
                                    <Box sx={{ display: "flex", gap: 2 }}>
                                        <FieldLabel sx={{ flex: 1, textAlign: "center" }}>年</FieldLabel>
                                        <FieldLabel sx={{ flex: 1, textAlign: "center" }}>月</FieldLabel>
                                        <FieldLabel sx={{ flex: 1, textAlign: "center" }}>日</FieldLabel>
                                    </Box>
                                </Box>
                                <Box sx={{ width: ICON_COL_WIDTH, flexShrink: 0, display: { xs: "none", sm: "block" } }} />
                                <Box sx={columnSx}>
                                    <FieldLabel>{t("expiryDate")}</FieldLabel>
                                </Box>
                            </Box>

                            {/* Input row — icons align with fields only */}
                            <Box sx={{ ...rowSx, alignItems: { xs: "stretch", sm: "center" } }}>
                                <Box sx={columnSx}>
                                    <DatePicker
                                        sx={fieldSx}
                                        label=" "
                                        value={productionDate ? dayjs(productionDate) : null}
                                        format={OUTPUT_DATE_FORMAT}
                                        onChange={(date) => {
                                            if (!date) {
                                                setProductionDate(undefined);
                                            } else {
                                                setProductionDate(date);
                                            }
                                            calculateDates(date, "productionDate");
                                        }}
                                        slotProps={{
                                            textField: {
                                                fullWidth: true,
                                                InputLabelProps: hiddenPickerLabelProps,
                                                error: errors.productionDate.length > 0,
                                            },
                                        }}
                                    />
                                </Box>
                                <Box sx={iconColumnSx}>
                                    <Add sx={{ fontSize: "2rem", color: "secondary.main" }} />
                                </Box>
                                <Box sx={shelfColumnSx}>
                                    <ShelfLifeInput
                                        sx={fieldSx}
                                        value={shelfLife}
                                        label={t("shelfLife")}
                                        showHelperText={false}
                                        externalLabels
                                        inputsOnly
                                        onChange={(value) => {
                                            const val = value == 0 ? undefined : value;
                                            setShelfLife(val);
                                            calculateDates(val, "shelfLife");
                                        }}
                                    />
                                </Box>
                                <Box sx={iconColumnSx}>
                                    <SwapHoriz sx={{ fontSize: "2rem", color: "secondary.main" }} />
                                </Box>
                                <Box sx={{ ...columnSx, minWidth: { sm: 200 } }}>
                                    <DatePicker
                                        sx={fieldSx}
                                        label=" "
                                        format={OUTPUT_DATE_FORMAT}
                                        value={expiryDate ? dayjs(expiryDate) : null}
                                        onChange={(date) => {
                                            if (!date) {
                                                setExpiryDate(undefined);
                                            } else {
                                                setExpiryDate(date);
                                                calculateDates(date, "expiryDate");
                                            }
                                        }}
                                        slotProps={{
                                            textField: {
                                                fullWidth: true,
                                                InputLabelProps: hiddenPickerLabelProps,
                                                error: errors.expiryDate.length > 0,
                                            },
                                        }}
                                        disabled
                                    />
                                </Box>
                            </Box>

                            {/* Helper / error row */}
                            <Box sx={{ ...rowSx, mt: 0.75, alignItems: "flex-start" }}>
                                <Box sx={columnSx}>
                                    {errors.productionDate && (
                                        <FormHelperText error>{errors.productionDate}</FormHelperText>
                                    )}
                                </Box>
                                <Box sx={{ width: ICON_COL_WIDTH, flexShrink: 0, display: { xs: "none", sm: "block" } }} />
                                <Box sx={shelfColumnSx}>
                                    <Typography
                                        component="div"
                                        sx={{
                                            fontSize: { xs: "0.95rem", sm: "1.05rem" },
                                            whiteSpace: "nowrap",
                                            color: "text.secondary",
                                            width: { sm: "33%" },
                                        }}
                                    >
                                        {t("shelfLife")}:{" "}
                                        <Box component="span" sx={{ color: "error.main", fontWeight: 600 }}>
                                            {shelfLife ?? 0} 日
                                        </Box>
                                    </Typography>
                                </Box>
                                <Box sx={{ width: ICON_COL_WIDTH, flexShrink: 0, display: { xs: "none", sm: "block" } }} />
                                <Box sx={columnSx}>
                                    {errors.expiryDate && (
                                        <FormHelperText error>{errors.expiryDate}</FormHelperText>
                                    )}
                                </Box>
                            </Box>
                        </Box>
                        <Stack
                            direction="row"
                            justifyContent="flex-end"
                            spacing={2}
                            sx={{ mt: 2 }}
                        >
                            <Button
                                name="submit"
                                variant="contained"
                                startIcon={<Check sx={{ fontSize: "1.75rem" }} />}
                                disabled={expiryDate === undefined || hasError}
                                onClick={handleSubmit}
                                sx={{
                                    minHeight: "3.5rem",
                                    px: 3,
                                    fontSize: { xs: "1rem", sm: "1.25rem" },
                                }}
                            >
                                {t("confirm expiry date")}
                            </Button>
                        </Stack>
                    
                    </LocalizationProvider>
                </Box>
            </Card>
        </Modal>
    )
}

export default CalculateExpiryDateModal;