import { UmbControllerBase } from '../../../../libs/class-api/index.js';
import { UmbExtensionsManifestInitializer, createExtensionElement } from '../../../../libs/extension-api/index.js';
import { umbExtensionsRegistry } from '../../extension-registry/index.js';
import { UmbArrayState, UmbObjectState, UmbStringState } from '../../../../libs/observable-api/index.js';
export class UmbCollectionViewManager extends UmbControllerBase {
    #views;
    #currentView;
    #routes;
    #rootPathName;
    #defaultViewAlias;
    #viewsOverride;
    constructor(host) {
        super(host);
        this.#views = new UmbArrayState([], (x) => x.alias);
        this.views = this.#views.asObservable();
        this.#currentView = new UmbObjectState(undefined);
        this.currentView = this.#currentView.asObservable();
        this.#routes = new UmbArrayState([], (x) => x.path);
        this.routes = this.#routes.asObservable();
        this.#rootPathName = new UmbStringState('');
        this.rootPathName = this.#rootPathName.asObservable();
        // TODO: hack - we need to figure out how to get the "parent path" from the router
        setTimeout(() => {
            const currentUrl = new URL(window.location.href);
            this.#rootPathName.setValue(currentUrl.pathname.substring(0, currentUrl.pathname.lastIndexOf('/')));
        }, 100);
    }
    setConfig(config) {
        this.#defaultViewAlias = config.defaultViewAlias;
        this.#viewsOverride = config.viewsOverride;
        this.#observeViews(config.manifestFilter);
    }
    // Views
    /**
     * Sets the current view.
     * @param {ManifestCollectionView} view
     * @memberof UmbCollectionContext
     */
    setCurrentView(view) {
        this.#currentView.setValue(view);
    }
    /**
     * Returns the current view.
     * @returns {ManifestCollectionView}
     * @memberof UmbCollectionContext
     */
    getCurrentView() {
        return this.#currentView.getValue();
    }
    #observeViews(filter) {
        return new UmbExtensionsManifestInitializer(this, umbExtensionsRegistry, 'collectionView', filter ?? null, (manifestInitializer) => {
            let manifests = manifestInitializer.map((view) => view.manifest);
            // Reorder and filter to match the `viewsOverride` array order
            if (this.#viewsOverride?.length) {
                manifests = this.#viewsOverride
                    .map((override) => manifests.find((m) => m.alias === override.collectionView))
                    .filter((m) => m !== undefined);
            }
            this.#views.setValue(manifests);
            this.#createRoutes(manifests);
        });
    }
    #createRoutes(views) {
        let routes = [];
        if (views && views.length > 0) {
            // find the default view from the config. If it doesn't exist, use the first view
            const firstOverrideView = this.#viewsOverride?.length
                ? views.find((view) => view.alias === this.#viewsOverride[0].collectionView)
                : null;
            const defaultView = firstOverrideView ?? views.find((view) => view.alias === this.#defaultViewAlias);
            const fallbackView = defaultView ?? views[0];
            routes = views.map((view) => {
                return {
                    path: `${view.meta.pathName}`,
                    component: () => createExtensionElement(view),
                    setup: () => {
                        this.setCurrentView(view);
                    },
                };
            });
            if (routes.length > 0) {
                routes.push({
                    unique: fallbackView.alias,
                    path: '',
                    component: () => createExtensionElement(fallbackView),
                    setup: () => {
                        this.setCurrentView(fallbackView);
                    },
                });
                routes.push({
                    path: `**`,
                    component: async () => (await import('../../router/index.js')).UmbRouteNotFoundElement,
                });
            }
        }
        this.#routes.setValue(routes);
    }
}
