"use client";

import React, { createContext, FC, useContext, useState } from "react";
import drawerRegistry from "@/drawers/drawersRegistry";
import {
    DrawerKey,
    DrawersStackState,
    OpenDrawerParams,
} from "@/drawers/types";

type DrawersContextState = {
    stack: DrawersStackState[];
    openDrawer: <TKey extends DrawerKey>(
        params: OpenDrawerParams<TKey>
    ) => void;
    closeDrawer: (key?: DrawerKey) => void;
};

const DrawersContext = createContext<DrawersContextState | undefined>(
    undefined
);

const useDrawersContextState = () => {
    const [stack, setStack] = useState<DrawersStackState[]>([]);

    const openDrawer = <TKey extends DrawerKey>(
        params: OpenDrawerParams<TKey>
    ) => {
        setStack(prev => {
            const filtered = prev.filter(d => d.key !== params.key);
            return [...filtered, { ...params, opened: false }];
        });

        setTimeout(() => {
            setStack(prev =>
                prev.map(d =>
                    d.key === params.key ? { ...d, opened: true } : d
                )
            );
        }, 10);
    };

    const closeDrawer = (key?: DrawerKey) => {
        setStack(prev =>
            prev.map(d => (d.key === key ? { ...d, opened: false } : d))
        );

        setTimeout(() => {
            setStack(prev =>
                key ? prev.filter(d => d.key !== key) : prev.slice(0, -1)
            );
        }, 300);
    };

    return {
        stack,
        openDrawer,
        closeDrawer,
    };
};

type BoardsContextProviderProps = {
    children: React.ReactNode;
};

export const DrawersContextProvider: FC<BoardsContextProviderProps> = ({
    children,
}) => {
    const state = useDrawersContextState();

    return (
        <DrawersContext.Provider value={state}>
            {children}

            {state.stack.map(({ key, props, onClose, opened }) => {
                const Component = drawerRegistry[key];
                return (
                    <Component
                        key={key}
                        opened={opened || false}
                        onClose={() => {
                            state.closeDrawer(key);
                            onClose && onClose();
                        }}
                        props={props}
                    />
                );
            })}
        </DrawersContext.Provider>
    );
};

export const useDrawersContext = () => {
    const context = useContext(DrawersContext);
    if (!context) {
        throw new Error(
            "useDrawersContext must be used within a DrawersContextProvider"
        );
    }
    return context;
};
