import {
    type ReactNode
} from "react";
import {
    StyleSheet,
    View
} from "react-native";
import {
    type EmbeddedMenuContextType,
    type EmbeddedMenuDataType
} from "../types/embeddedMenu";
import NCoreContext, {
    type ConfigType
} from "ncore-context";
import EmbeddedMenu from "../components/embeddedMenu";
import {
    uuid
} from "../utils";

const stylesheet = StyleSheet.create({
    wrapper: {
        flexDirection: "row",
        flex: 1
    }
});

class NCoreUIKitEmbeddedMenu extends NCoreContext<EmbeddedMenuContextType, ConfigType<EmbeddedMenuContextType>> {
    constructor({
        data = []
    }: {
        data?: Array<EmbeddedMenuDataType>
    }) {
        super({
            get: () => undefined,
            unload: () => "",
            update: () => {},
            close: () => {},
            load: () => "",
            open: () => {},
            data: data
        }, {
            key: "NCoreUIKit-MenuContext"
        });
    };

    load = (menuData: EmbeddedMenuDataType) => {
        const currentData = this.state.data;

        const menuID = menuData.id ? menuData.id : uuid();

        currentData.push({
            ...menuData,
            id: menuID
        });

        this.setState({
            data: currentData
        });

        return menuID;
    };

    get = ({
        index,
        id
    }: {
        index?: number;
        id?: string;
    }) => {
        const currentData = this.state.data;

        if(id) {
            const currentIndex = currentData.findIndex(cI => cI.id === id);

            return currentData[currentIndex];
        }

        if(index) {
            return currentData[index];
        }

        return undefined;
    };

    update = ({
        menuData,
        index,
        id
    }: {
        menuData: EmbeddedMenuDataType;
        index?: number;
        id?: string;
    }) => {
        const currentData = this.state.data;

        if(id) {
            const currentIndex = currentData.findIndex(cI => cI.id === id);

            currentData[currentIndex] = menuData;
        }

        if(index) {
            currentData[index] = menuData;
        }

        this.setState({
            data: currentData
        });
    };

    open = (props?: {
        index?: number;
        id?: string;
    }) => {
        const currentData = this.state.data;

        if (props && props.id) {
            const keyIndex = currentData.findIndex((menu) => menu.id === props.id);

            if (keyIndex !== -1) {
                currentData[keyIndex]!.isCollapse = true;

                this.setState({
                    data: currentData
                });
            }

            return;
        }

        if (props && props.index !== undefined && currentData[props.index]) {
            currentData[props.index!]!.isCollapse = true;

            this.setState({
                data: currentData
            });

            return;
        }
    };

    close = (props?: {
        index?: number;
        id?: string;
    }) => {
        const currentData = this.state.data;

        if (props && props.id) {
            const keyIndex = currentData.findIndex((menu) => menu.id === props.id);

            if (keyIndex !== -1) {
                currentData[keyIndex]!.isCollapse = false;

                this.setState({
                    data: currentData
                });
            }

            return;
        }

        if (props && props.index !== undefined && currentData[props.index]) {
            currentData[props.index!]!.isCollapse = false;

            this.setState({
                data: currentData
            });

            return;
        }
    };

    unload = (props?: {
        index?: number;
        id?: string;
    }) => {
        const currentData = this.state.data;

        if (props && props.id) {
            const keyIndex = currentData.findIndex((menu) => menu.id === props.id);

            if (keyIndex !== -1) {
                currentData.splice(keyIndex, 1);

                this.setState({
                    data: currentData
                });
            }

            return;
        }

        if (props && props.index !== undefined) {
            currentData.splice(props.index, 1);

            this.setState({
                data: currentData
            });

            return;
        }

        currentData.pop();

        this.setState({
            data: currentData
        });
    };

    Render = ({
        headerSpace,
        navigation,
        children,
        index,
        id
    }: {
        navigation: NCoreUIKit.Navigation;
        children?: ReactNode;
        headerSpace?: number;
        index?: number;
        id?: string;
    }) => {
        const {
            data
        } = this.useContext();

        const renderMenu = ({
            currentMenu
        }: {
            currentMenu: EmbeddedMenuDataType;
        }) => {
            return <EmbeddedMenu
                {...currentMenu}
                key={`NCoreUIKit-Menu-${currentMenu.id}`}
                id={currentMenu.id as string}
                headerSpace={headerSpace}
                close={() => {
                    if(currentMenu.isAutoClosed) {
                        this.close({
                            id: currentMenu.id,
                            index: index
                        });
                    }
                }}
                onClosed={() => {
                    if(currentMenu.onClosed) {
                        currentMenu.onClosed({
                            id: currentMenu.id
                        });
                    }

                    if(currentMenu.isAutoClosedOnClosed === undefined || currentMenu.isAutoClosedOnClosed === true) {
                        this.close({
                            id: currentMenu.id,
                            index: index
                        });
                    }
                }}
                navigation={navigation}
            />;
        };

        if(id || index) {
            const currentMenu = data.find((dItem, dIndex) => {
                if(id) {
                    return dItem.id === id;
                } else {
                    return dIndex === index;
                }
            });

            if(!currentMenu) {
                return null;
            }

            if(children) {
                return <View
                    style={stylesheet.wrapper}
                >
                    {renderMenu({
                        currentMenu
                    })}
                    {children}
                </View>;
            }

            return renderMenu({
                currentMenu
            });
        }

        return null;
    };
}
export default NCoreUIKitEmbeddedMenu;
