import React, {
    useRef,
    useState,
} from 'react';

import {
    ChevronDownIcon,
    ChevronUpIcon,
    XIcon,
} from 'lucide-react';

import {
    DropdownMenu,
    DropdownMenuContent,
    DropdownMenuItem,
    DropdownMenuPortal,
    DropdownMenuSeparator,
    DropdownMenuSub,
    DropdownMenuSubContent,
    DropdownMenuSubTrigger,
    DropdownMenuTrigger,
} from '@/components/ui/dropdown-menu';
import {
    MobileLink,
    MobileListItem,
    MobileSheet,
    MobileToolbar,
    MobileToolbarPane,
} from '@/components/ui/mobile';
import { Skeleton } from '@/components/ui/skeleton';
import useAppConfigStore, { useAppConfig } from '@/stores/appConfig';

export type MenuData = {
    label?: React.ReactNode;
    type?: 'normal' | 'separator' | 'checkbox';
    icon?: string;
    tooltip?: string;
    click?: () => void;
    disabled?: boolean;
    checked?: boolean;
    key?: string;
    modifiers?: string;
    htmlIcon?: React.ReactNode;
    submenu?: MenuData[];
}

const MobileAccordionItem = (props: { depth: number, prefix?: React.ReactNode, title: React.ReactNode | undefined, children: React.ReactNode }) => {

    const [opened, setOpened] = useState(false);

    return <><MobileListItem

        dividers
        style={{
            paddingLeft: getDepthPadding(props.depth)
        }}
        header={props.prefix}
        title={props.title}
        chevron={false}
        media={opened ? <ChevronUpIcon /> : <ChevronDownIcon />}
        onClick={() => setOpened(!opened)}
    ></MobileListItem>
        {opened && <>
            {props.children}
        </>
        }
    </>
}


const getDepthPadding = (depth: number) => {
    return depth * 20;
}
const MenuLoadingSkeletons = () => (
    <div className="flex flex-col gap-1 p-1">
        <Skeleton className="h-8 w-full" />
        <Skeleton className="h-8 w-full" />
        <Skeleton className="h-8 w-full" />
    </div>
);

const AnyDropdownMenu = ({ menu, children, className, onOpen, loading }: { menu: MenuData[], children: React.ReactNode, className?: string, onOpen?: () => void, loading?: boolean }) => {

    const { isMobile } = useAppConfigStore();

    const [popoverOpened, setPopoverOpened] = useState(false);
    const popoverTargetRef = useRef<HTMLDivElement>(null);

    const currentMenu = menu;


    const DropdownMenuRender = ({ prefix, items, subMenu = false, depth }: { prefix?: React.ReactNode, items: MenuData[], subMenu?: boolean, depth: number }) => {

        const { isMobile } = useAppConfigStore();


        return items.map((item) => {
            if (item.type === 'separator') {
                if (isMobile) {
                    return null;
                }
                return <DropdownMenuSeparator />
            }
            if (item.submenu) {

                if (isMobile) {

                    if (item.disabled) {
                        return null;
                    }

                    return <MobileAccordionItem depth={depth} title={item.label} children={<DropdownMenuRender depth={depth + 1} prefix={item.label} items={item.submenu} subMenu={true} />} />




                }

                return <DropdownMenuSub>
                    <DropdownMenuSubTrigger>{item.label}</DropdownMenuSubTrigger>
                    <DropdownMenuPortal>
                        <DropdownMenuSubContent>
                            <DropdownMenuRender depth={depth} items={item.submenu} subMenu={true} />
                        </DropdownMenuSubContent>
                    </DropdownMenuPortal>
                </DropdownMenuSub>



            }


            if (isMobile) {

                if (item.disabled) {
                    return null;
                }

                return <MobileListItem




                    dividers
                    style={{
                        paddingLeft: getDepthPadding(depth)
                    }}
                    title={item.label}
                    header={prefix}
                    link
                    chevron={false}
                    onClick={() => {
                        if (item.disabled) {
                            return;
                        }
                        item.click?.();
                        setPopoverOpened(false);
                    }}
                    media={item.htmlIcon}
                />
            }

            return <DropdownMenuItem
                onClick={() => {
                    item.click?.()
                }}
            >
                {item.htmlIcon}
                {item.label}
            </DropdownMenuItem>

        })





    }




    if (isMobile) {


        return <>
            <div
                className={className}
                onClick={() => {
                    setPopoverOpened(true);
                    onOpen?.();
                }}
                ref={popoverTargetRef}
            >
                {children}
            </div>
            <MobileSheet
                className="pb-safe "
                opened={popoverOpened}
                onBackdropClick={() => setPopoverOpened(false)}
            >
                <div className='max-h-[80vh] overflow-y-auto '>
                    <MobileToolbar top className="justify-end ios:pt-4 sticky top-0 z-10">
                        <div className="ios:hidden" />
                        <MobileToolbarPane>
                            <MobileLink iconOnly onClick={() => setPopoverOpened(false)}>
                                <XIcon />
                            </MobileLink>
                        </MobileToolbarPane>
                    </MobileToolbar>


                    <ul>
                        {loading
                            ? <MenuLoadingSkeletons />
                            : <DropdownMenuRender depth={0} items={menu} subMenu={true} />
                        }
                    </ul>
                </div>
            </MobileSheet>
        </>




    }


    return <DropdownMenu onOpenChange={(open) => { if (open) onOpen?.(); }}>
        <DropdownMenuTrigger asChild>
            {children}
        </DropdownMenuTrigger>
        <DropdownMenuContent align="end" >
            {loading
                ? <MenuLoadingSkeletons />
                : <DropdownMenuRender depth={0} items={menu} />
            }
        </DropdownMenuContent>
    </DropdownMenu>

}


export default AnyDropdownMenu;