import {
    useImperativeHandle,
    useLayoutEffect,
    forwardRef,
    useEffect,
    useState,
    Fragment,
    useRef
} from "react";
import {
    Platform,
    Animated,
    Easing,
    View
} from "react-native";
import {
    type EmbeddedMenuButton as EmbeddedMenuButtonType
} from "./components/menuButton/type";
import {
    type IEmbeddedMenuRef
} from "./type";
import type IEmbeddedMenuProps from "./type";
import stylesheet, {
    useStyles
} from "./stylesheet";
import MenuButton from "./components/menuButton";
import {
    NCoreUIKitEmbeddedMenu,
    NCoreUIKitTheme
} from "../../core/hooks";
import type {
    RefForwardingComponent
} from "../../types";
import {
    PanelLeftClose,
    PanelLeftOpen
} from "lucide-react-native";
import {
    SafeAreaView
} from "react-native-safe-area-context";
import Seperator from "../seperator";
import SiteLogo from "../siteLogo";
import Button from "../button";

const Menu: RefForwardingComponent<IEmbeddedMenuRef, IEmbeddedMenuProps> = ({
    isWorkWithSafeAreaView = true,
    isWorkWithHeaderSpace = true,
    isWorkWithAnimation = true,
    renderHeader: RenderHeader,
    renderFooter: RenderFooter,
    isShowSiteLogo = true,
    close: closeAction,
    customLocalize,
    maxWidth = 300,
    minWidth = 75,
    siteLogoProps,
    headerSpace,
    customTheme,
    navigation,
    isCollapse,
    onClosed,
    onOpened,
    buttons,
    onClose,
    onOpen,
    style,
    id,
    ...props
}, ref) => {
    const {
        configs,
        colors,
        spaces
    } = NCoreUIKitTheme.useContext(customTheme);

    const [
        isActive,
        setIsActive
    ] = useState(false);

    const {
        headerContentContainer: headerContentContainerDynamicStyle,
        headerContainer: headerContainerDynamicStyle,
        collapseButton: collapseButtonDynamicStyle,
        seperator: seperatorDynamicStyle,
        container: containerDynamicStyle,
        siteLogo: siteLogoDynamicStyle
    } = useStyles({
        isCollapse: isActive,
        colors,
        spaces
    });

    const animatedX = useRef(new Animated.Value(!isCollapse ? minWidth : maxWidth)).current;

    useImperativeHandle(
        ref,
        () => ({
            close,
            open
        }),
        []
    );

    useEffect(() => {
        if(isCollapse !== undefined && isActive !== isCollapse) setIsActive(isCollapse);
    }, [isCollapse]);

    useLayoutEffect(() => {
        if(isActive) {
            if(onOpen) onOpen({
                id
            });

            if(Platform.OS !== "web") {
                if(onOpened) onOpened({
                    id
                });
            } else if(isWorkWithAnimation) {
                openAnimation();
            } else {
                animatedX.setValue(maxWidth);

                if(onOpened) onOpened({
                    id
                });
            }
        } else {
            if(onClose) onClose({
                id
            });

            if(isWorkWithAnimation && Platform.OS === "web") {
                closeAnimation();
            } else {
                animatedX.setValue(minWidth);

                if(onClosed) onClosed({
                    id
                });
            }
        }
    }, [
        isActive
    ]);

    const open = () => {
        NCoreUIKitEmbeddedMenu.open({
            id
        });
    };

    const close = () => {
        NCoreUIKitEmbeddedMenu.close({
            id
        });
    };

    const openAnimation = () => {
        Animated.timing(animatedX, {
            useNativeDriver: Platform.OS !== "web",
            easing: Easing.linear,
            toValue: maxWidth,
            duration: 300
        }).start(({
            finished
        }) => {
            if(finished) {
                if(onOpened) onOpened({
                    id
                });
            }
        });
    };

    const closeAnimation = () => {
        Animated.timing(animatedX, {
            useNativeDriver: Platform.OS !== "web",
            easing: Easing.linear,
            toValue: minWidth,
            duration: 300
        }).start(({
            finished
        }) => {
            if(finished) {
                if(onClosed) onClosed({
                    id
                });
            }
        });
    };

    const updateMenuButtonCollabs = ({
        depthMap,
        status
    }: {
        depthMap: Array<number>;
        status: boolean;
    }) => {
        const state = NCoreUIKitEmbeddedMenu.get({
            id
        });

        if(!state) {
            return;
        }

        const recursivelyCatch = (item: Array<EmbeddedMenuButtonType>, index = 0): Array<EmbeddedMenuButtonType> => {
            const tIndex = depthMap[index];

            return item.map((c_item, c_index) => {
                if(c_index !== tIndex) {
                    return c_item;
                }

                if(index === depthMap.length - 1) {
                    return {
                        ...c_item,
                        isCollapse: status
                    };
                }

                return {
                    ...c_item,
                    subButtons: recursivelyCatch(c_item.subButtons as Array<EmbeddedMenuButtonType>, index + 1)
                };
            });
        };

        const newButtons = recursivelyCatch(state.buttons);

        state.buttons = newButtons;

        NCoreUIKitEmbeddedMenu.update({
            menuData: state,
            id: id
        });
    };

    const renderToggleCollapseForCollabsed = () => {
        if(isActive) {
            return null;
        }

        return <Button
            isCustomPadding={true}
            spreadBehaviour="free"
            type="neutral"
            size="medium"
            icon={({
                color,
                size
            }) => {
                return <PanelLeftOpen
                    color={colors.content.icon[color]}
                    size={size * 2}
                />;
            }}
            style={{
                ...collapseButtonDynamicStyle
            }}
            onPress={() => {
                if(isActive) {
                    close();
                } else {
                    open();
                }
            }}
        />;
    };

    const renderToggleCollapseForExpended = () => {
        if(!isActive) {
            return null;
        }

        return <Button
            isCustomPadding={true}
            spreadBehaviour="free"
            type="neutral"
            size="medium"
            icon={({
                color,
                size
            }) => {
                return <PanelLeftClose
                    color={colors.content.icon[color]}
                    size={size * 2}
                />;
            }}
            style={{
                ...collapseButtonDynamicStyle
            }}
            onPress={() => {
                if(isActive) {
                    close();
                } else {
                    open();
                }
            }}
        />;
    };

    const renderHeader = () => {
        if(RenderHeader) {
            return <RenderHeader
                isCollapse={isActive}
                maxWidth={maxWidth}
                minWidth={minWidth}
            />;
        }

        return <View
            style={[
                stylesheet.headerContainer,
                headerContainerDynamicStyle
            ]}
        >
            {renderToggleCollapseForCollabsed()}
            <View
                style={[
                    stylesheet.headerContentContainer,
                    headerContentContainerDynamicStyle
                ]}
            >
                {isShowSiteLogo ? <SiteLogo
                    customLocalize={customLocalize}
                    customTheme={customTheme}
                    {...siteLogoProps}
                    title={isActive ? siteLogoProps?.title : undefined}
                    size={isActive ? siteLogoProps?.size : "small"}
                    style={[
                        siteLogoProps?.style,
                        siteLogoDynamicStyle
                    ]}
                /> : <View
                    style={{
                        flex: 1
                    }}
                />}
                {renderToggleCollapseForExpended()}
            </View>
            <Seperator
                style={[
                    stylesheet.seperator,
                    seperatorDynamicStyle
                ]}
            />
        </View>;
    };

    const renderButtons = () => {
        if(!buttons || !buttons.length) {
            return null;
        }

        return buttons.map((buttonItem, buttonIndex) => {
            return <MenuButton
                key={`embedded-menu-button-${id}-${buttonIndex}`}
                updateMenuButtonCollabs={updateMenuButtonCollabs}
                closeAction={closeAction}
                buttonIndex={buttonIndex}
                isMenuCollabs={isActive}
                depthMap={[buttonIndex]}
                buttonItem={buttonItem}
                navigation={navigation}
                openMenu={() => {
                    open();
                }}
                id={id}
            />;
        });
    };

    const renderFooter = () => {
        if(!RenderFooter) {
            return null;
        }

        return <RenderFooter
            isCollapse={isActive}
            maxWidth={maxWidth}
            minWidth={minWidth}
        />;
    };

    const renderSafeAreaContext = () => {
        if(!isWorkWithSafeAreaView) {
            return <Fragment>
                {isWorkWithHeaderSpace && (configs.headerSpace || headerSpace) ? <View
                    style={{
                        height: headerSpace ? headerSpace : configs.headerSpace,
                        width: "100%"
                    }}
                /> : null}
                {renderHeader()}
                <View
                    style={[
                        stylesheet.content
                    ]}
                >
                    {renderButtons()}
                </View>
                {renderFooter()}
            </Fragment>;
        }

        return <SafeAreaView
            style={[
                stylesheet.safeAreaView
            ]}
        >
            {renderHeader()}
            <View
                style={[
                    stylesheet.content
                ]}
            >
                {renderButtons()}
            </View>
            {renderFooter()}
        </SafeAreaView>;
    };

    const renderContent = () => {
        return <Animated.View
            {...props}
            style={[
                style,
                stylesheet.container,
                containerDynamicStyle,
                Platform.OS === "web" ? {
                    width: animatedX
                } : {
                    width: isActive ? maxWidth : minWidth
                }
            ]}
        >
            {renderSafeAreaContext()}
        </Animated.View>;
    };

    return renderContent();
};
export default forwardRef(Menu);
