import React, {
    forwardRef,
    useEffect,
    useImperativeHandle,
    useMemo,
    useRef,
    useState,
} from 'react';

import _ from 'lodash';
import {
    FunnelX,
    XIcon,
} from 'lucide-react';

import { rpc } from '@/api/request';
import { StructureType } from '@/api/types';
import CollectionFields from '@/components/CollectionFields/CollectionFields';
import { Button } from '@/components/ui/button';
import {
    Empty,
    EmptyDescription,
    EmptyHeader,
    EmptyMedia,
    EmptyTitle,
} from '@/components/ui/empty';
import {
    MobileLink,
    MobileNavbar,
    MobilePage,
    MobilePopup,
} from '@/components/ui/mobile';
import { SystemWindowDialog } from '@/components/ui/system-window-dialog';
import { toast } from '@/componentsRoot/ToastRoot';
import { Lang } from '@/lang/Lang';
import useAppConfigStore from '@/stores/appConfig';

import { flatFilterStructure } from '../../utils';
import AddFilterButton from './components/AddFilterButton';
import ApplyFilterButton from './components/ApplyFilterButton';
import ClearFilterButton from './components/ClearFilterButton';

export type TableFilterDialogRef = {
    open: () => void;
    close: () => void;
}

type TableFilterDialogProps = {
    structure?: StructureType | null;
    onApply: (filterStructureData: StructureType[], values: any) => void;
    initialFilter?: any;
}


const TableFilterDialog = forwardRef<TableFilterDialogRef, TableFilterDialogProps>(({ structure, onApply, initialFilter }, ref) => {
    const { isMobile } = useAppConfigStore();
    const [isOpen, setIsOpen] = useState(false);

    const [filterStructure, setFilterStructure] = useState<StructureType | null>(null);

    const [filterStructureData, setFilterStructureData] = useState<StructureType[]>([]);

    const valuesRef = useRef<any>({});


    useImperativeHandle(ref, () => ({
        open: () => {

            setIsOpen(true);
        },
        close: () => {
            setIsOpen(false);
        }
    }));

    const currentStructure = useMemo(() => {
        return structure ?? null;
    }, [structure]);


    const recoverFilterStructure = (structure: StructureType) => {

        console.log('TableFilterDialog =====> recoverFilterStructure: ' + JSON.stringify(initialFilter));
        if (initialFilter) {

            let flatFilters = flatFilterStructure({
                structure: structure,
            })
            console.log('TableFilterDialog =====> flatFilters: ' + JSON.stringify(flatFilters));
            let _filterStructureData: StructureType[] = [];
            _.map(flatFilters, (filter) => {
                if (initialFilter[filter.key ?? '']) {
                    console.log('TableFilterDialog =====> filter: ' + JSON.stringify(filter));
                    _filterStructureData.push(filter);
                }
            })
            setFilterStructureData(_filterStructureData);
            valuesRef.current = initialFilter;
        } else {
            console.log('TableFilterDialog =====> no initialFilter');
        }

    }

    useEffect(() => {
        if (currentStructure?.collection) {
            rpc.filter({ collection: currentStructure.collection! }).then((data) => {
                if (data?.result) {
                    setFilterStructure(data.result ?? null);
                    console.log('TableFilterDialog =====> data.result: ' + JSON.stringify(data.result));
                    recoverFilterStructure(data.result ?? null);


                }
            });
        }
    }, [currentStructure?.collection]);


    const applyFilter = () => {
        if (filterStructureData.length === 0) {
            toast.error(Lang.key('please_add_filter'));
            return;
        }

        onApply(filterStructureData, valuesRef.current);
        handleClose();
    }






    const removeFilter = (index: number, item: StructureType) => {

        if (item.key) {
            delete valuesRef.current[item.key];
        }

        setFilterStructureData((prev) => {
            return [...prev.slice(0, index), ...prev.slice(index + 1)];
        });
    }

    const FilterElements = () => {



        if (filterStructureData.length === 0) {
            return <Empty>
                <EmptyHeader>
                    <EmptyMedia variant="icon">
                        <FunnelX />
                    </EmptyMedia>
                    <EmptyTitle>{Lang.key('no_filters_title')}</EmptyTitle>
                    <EmptyDescription>
                        {Lang.key('no_filters_description')}
                    </EmptyDescription>
                </EmptyHeader>
            </Empty>
        }



        return <>



            {filterStructureData.map((filterStructureItem, index) => {
                return <div className='flex items-center'>
                    <div className='flex-1'>
                        <CollectionFields
                            inline
                            noPaddingBottom structure={filterStructureItem} valuesRef={valuesRef} />
                    </div>
                    {isMobile ? <MobileLink
                        className='px-2'
                        onClick={() => {
                            removeFilter(index, filterStructureItem);



                        }}>

                        <XIcon />

                    </MobileLink> : <Button variant="ghost"
                        className='mt-3'
                        size="icon-sm" onClick={() => {
                            removeFilter(index, filterStructureItem);
                        }}>
                        <XIcon />
                    </Button>}
                </div>
            })}




        </>
    }

    const clearFilter = () => {
        setFilterStructureData([]);
        valuesRef.current = {};

        onApply([], {});
        handleClose();
    }




    const onAddFilter = (structure: StructureType) => {
        setFilterStructureData((prev) => {
            return [...prev, structure];
        });
    }

    const handleClose = () => {
        setIsOpen(false);
    };

    if (!isOpen) return null;

    if (!currentStructure || !currentStructure.items) return null;

    if (isMobile) {
        return <MobilePopup opened={isOpen} onBackdropClick={handleClose}>
            <MobilePage>
                <MobileNavbar
                    title={Lang.key('filter')}
                    right={<MobileLink onClick={handleClose}><XIcon /></MobileLink>}
                />
                <div className='px-2'>
                    <FilterElements />
                </div>


                <AddFilterButton
                    onSelect={onAddFilter}
                    structure={filterStructure}
                />


                <ClearFilterButton
                    onClick={() => {
                        clearFilter();
                    }}
                    disabled={filterStructureData.length === 0}
                />

                <ApplyFilterButton
                    onClick={() => {
                        applyFilter();
                    }}
                    disabled={filterStructureData.length === 0}
                />





            </MobilePage>
        </MobilePopup>
    }

    return (<>


        <SystemWindowDialog
            open={isOpen}
            onOpenChange={(val) => {
                if (!val) {
                    handleClose();
                }
            }}
            title={Lang.key('filter')}
            width="80vw"
            height="min(70vh, 600px)"
            allowFullscreen
            footer={
                <div className='flex justify-between w-full'>
                    <div className='flex items-center gap-2'>
                        <AddFilterButton
                            onSelect={onAddFilter}
                            structure={filterStructure}
                        />
                        <ClearFilterButton
                            onClick={() => {
                                clearFilter();
                            }}
                            disabled={filterStructureData.length === 0}
                        />
                    </div>
                    <div className='flex items-center gap-2'>
                        <ApplyFilterButton
                            onClick={() => {
                                applyFilter();
                            }}
                            disabled={filterStructureData.length === 0}
                        />
                        <Button variant="outline" onClick={handleClose}>{Lang.key('close')}</Button>
                    </div>
                </div>
            }
        >
            <div className='min-h-[20vh] overflow-y-auto'>
                <FilterElements />
            </div>
        </SystemWindowDialog>
    </>
    );
});

TableFilterDialog.displayName = 'TableFilterDialog';

export default TableFilterDialog;