import { AnyAction } from '@reduxjs/toolkit'
import { EnhancedStore } from "@reduxjs/toolkit/src/configureStore";

import $flow, { commandBases } from '@appsflow/core';

import Controller from "../controller";
import { CommandRoute } from "../command-bases/route";
import { routesSlice } from "../store";

export class Routes extends $flow.managers().Commands {
    public currentRoute: { [ key: string ]: string } = {};

    private store: EnhancedStore<any, AnyAction, []>;

    constructor( store: any ) {
        super();

        this.store = store;
    }

    static getName() {
        return 'Flow/Redux/Managers/Routes';
    }

    async to( route: string, args = {} ) {
        return await super.run( route, args );
    }

    register( commands: Array<typeof commandBases.CommandPublic>, controller: Controller ) {
        const wrappedRoutes = commands.map( ( command ) => {
            const CommandRouteClass = class extends CommandRoute{}; // Unique class each iteration.

            CommandRouteClass.setCommand( command );
            CommandRouteClass.setController( controller );

            return CommandRouteClass;
        } )

        return super.register( wrappedRoutes, controller );
    }

    protected attachCurrent( command: CommandRoute, args: any = {} ) {
        super.attachCurrent( command, args );

        // // TODO: Not the best way to do it, by using namespace, namespace should the name of the controller.
        // // And route simple name.
        // const fullName = command.getName(),
        //     splitElement = fullName.split( '/' ),
        //     namespace = splitElement[ 0 ],
        //     name = splitElement[ 1 ];
        //
        // this.currentRoute[ namespace ] = name;
        //
        // // @ts-ignore
        // this.store.dispatch( routesSlice.actions.set( JSON.parse( this.currentRoute ) ) );
    }
}

let routes: Routes | undefined = undefined;

export function getRoutes() {
    if ( routes ) {
        return routes;
    }

    // @ts-ignore
    routes = new Routes( globalThis.$flow.redux.store );

    // @ts-ignore
    globalThis.$flow.redux.routes = routes;

    return routes;
}

export default Routes;
