import { createContextFactory } from "@devowl-wp/utils";

import { OptionStore } from "./option.js";
import { TreeStore } from "./tree.js";

import type { Context, FC, PropsWithChildren } from "react";

/**
 * A collection of all available stores which gets available
 * through the custom hook useStores in your function components.
 *
 * @see https://mobx.js.org/best/store.html#combining-multiple-stores
 */
class RootStore {
    private static me: RootStore;

    public optionStore: OptionStore;

    public treeStore: TreeStore;

    private contextMemo: {
        StoreContext: Context<RootStore>;
        StoreProvider: FC<PropsWithChildren>;
        useStores: () => RootStore;
    };

    public get context() {
        return this.contextMemo
            ? this.contextMemo
            : (this.contextMemo = createContextFactory(this as unknown as RootStore));
    }

    private constructor() {
        this.optionStore = new OptionStore(this);
        this.treeStore = new TreeStore(this);
    }

    public static get StoreProvider() {
        return RootStore.get.context.StoreProvider;
    }

    public static get get() {
        return RootStore.me ? RootStore.me : (RootStore.me = new RootStore());
    }
}

const useStores = () => RootStore.get.context.useStores();

export { RootStore, useStores };
