'use client'

import {Box, Button, Drawer, styled} from "@mui/material";
import {Form, Formik} from "formik";
import useTableSetting from "@/lib/hooks/useTableSetting";
import {useEffect, useRef, useState} from "react";
import FilterHeader from "@/core/components/DataTable/filter/FilterHeader";
import * as Yup from "yup";
import FilterBodyField from "@/core/components/DataTable/filter/FilterBodyField";
import {toast} from "react-toastify";
import AskForKeep from "@/core/components/NotificationDesign/AskForKeep";
import useDataTable from "@/lib/hooks/useDataTable";

const ScrollBox = styled(Box)({
    flexGrow: 1,
    overflowY: 'scroll',
    maxWidth: "450px",
    '::-webkit-scrollbar': {
        width: '5px',
    },
    '::-webkit-scrollbar-track': {
        boxShadow: 'inset 0 0 5px #fff',
        borderRadius: '5px',
    },
    '::-webkit-scrollbar-thumb': {
        background: '#155175',
        borderRadius: '0px',
    }
});

function FilterBody({columns, drawerState, setDrawerState, user_id, page_name, table_name}) {
    const {settingStore, filterAction} = useTableSetting();
    const [initialValues, setInitialValues] = useState({});
    const [validationSchema, setValidationSchema] = useState({});
    const {filterData, setFilterData} = useDataTable();
    const filterDataRef = useRef(filterData);
    useEffect(() => {
        filterDataRef.current = filterData;
    }, [filterData]);

    useEffect(() => {
        const values = columns.reduce((acc, column) => {
            if (!column.enableColumnFilter) return acc;
            const filter = settingStore?.[user_id]?.[page_name]?.[table_name]?.['filters']?.find((filter) => filter.id === column.id);
            if (column.datatype === 'array') {
                acc[column.id] = {
                    id: column.id,
                    value: filter?.value || [],
                    filterFn: filter?.fn || column._filterFn,
                    datatype: column.datatype
                };
            } else if (column._filterFn === "between") {
                acc[column.id] = {
                    id: column.id,
                    value: filter?.value || ["", ""],
                    filterFn: filter?.fn || column._filterFn,
                    datatype: column.datatype
                };
            } else {
                acc[column.id] = {
                    id: column.id,
                    value: filter?.value || '',
                    filterFn: filter?.fn || column._filterFn,
                    datatype: column.datatype
                };
            }
            return acc;
        }, {});
        setInitialValues(Object.keys(filterData).length !== 0 ? filterData : values);
    }, [columns, settingStore, user_id, page_name, table_name, filterData]);


    useEffect(() => {
        const generatedSchema = Yup.object().shape(
            Object.keys(initialValues).reduce((acc, key) => {
                const initialValue = initialValues[key];
                if (initialValue.filterFn === "between") {
                    acc[key] = Yup.object().shape({
                        value: Yup.array()
                            .of(Yup.string().nullable())
                            .test({
                                test(value, ctx) {
                                    const [start, end] = value || ["", ""];
                                    if (initialValue.datatype === "numeric" && parseInt(end, 10) <= parseInt(start, 10)) {
                                        return ctx.createError({
                                            message: `مقدار وارده باید بیشتر از (${start}) باشد`,
                                        });
                                    } else if ((start && !end) || (!start && end)) {
                                        return ctx.createError({
                                            message: "این بخش را تکمیل نمایید",
                                        });
                                    }
                                    return true;
                                },
                            }),
                    });
                }
                return acc;
            }, {})
        );

        setValidationSchema(generatedSchema);
    }, [initialValues]);


    const handleSubmit = (values, {setSubmitting}) => {
        toast.dismiss({containerId: "filtering"});
        setDrawerState(false);
        setFilterData(values);
        toast(<AskForKeep onSaveFilter={onSaveFilter}/>, {
            containerId: "filtering",
            className: "filter-toast",
            position: "bottom-left",
            draggable: true,
            autoClose: false,
        });
        setSubmitting(false);
    };

    const onSaveFilter = () => {
        const currentFilterData = filterDataRef.current;
        const arrayOfObjects = Object.keys(currentFilterData).map(key => {
            const value = currentFilterData[key].value;
            if (value !== "" &&
                !(Array.isArray(value) && (value.length === 0 || (value.length === 2 && value[0] === "" && value[1] === "")))) {
                return currentFilterData[key];
            }
        }).filter(Boolean);
        filterAction(user_id, page_name, table_name, arrayOfObjects, columns)
        toast.dismiss({containerId: "filtering"});
    };

    return (
        <Drawer open={drawerState} onClose={() => setDrawerState(false)}
                sx={{overflowY: "hidden", display: "flex", flexDirection: "column", height: "100%"}}>
            <FilterHeader setDrawerState={setDrawerState}/>
            {Object.keys(initialValues).length > 0 && (
                <ScrollBox>
                    <Formik
                        initialValues={initialValues}
                        onSubmit={handleSubmit}
                        validationSchema={validationSchema}
                    >
                        {
                            ({
                                 values,
                                 handleChange,
                                 handleBlur,
                                 setFieldValue,
                                 errors,
                                 touched,
                                 isSubmitting,
                                 isValid,
                                 dirty,
                                 resetForm
                             }) => (
                                <Form>
                                    <Box sx={{px: 1, py: 2}}>
                                        {
                                            columns.map((column) => (
                                                column.enableColumnFilter && (
                                                    <FilterBodyField
                                                        key={column.id}
                                                        column={column}
                                                        filterParameters={values[column.id]}
                                                        handleChange={handleChange}
                                                        handleBlur={handleBlur}
                                                        setFieldValue={setFieldValue}
                                                        resetForm={resetForm}
                                                        errors={errors}
                                                        touched={touched}
                                                    />
                                                )
                                            ))
                                        }
                                    </Box>
                                    <Box sx={{
                                        display: 'flex',
                                        justifyContent: 'center',
                                        alignItems: 'center',
                                        pb: 2
                                    }}>
                                        <Button
                                            type="submit"
                                            variant="contained"
                                            size="large"
                                            disabled={isSubmitting || !isValid || !dirty}
                                            sx={{
                                                px: 8,
                                                boxShadow: "rgba(0, 0, 0, 0.23) 0px 6px 6px, rgba(0, 0, 0, 0.19) 10px 0px 20px",
                                                backgroundColor: "#155175", ':hover': {
                                                    backgroundColor: "#155175",
                                                }
                                            }}>
                                            اعمال فیلتر
                                        </Button>
                                    </Box>
                                </Form>
                            )}
                    </Formik>
                </ScrollBox>
            )}
        </Drawer>
    );
}

export default FilterBody;