// #region Imports
/**
 * Represents a single route entry with path matching, component resolution,
 * nested children, and guard support.
 *
 * @public
 */
export class Route {
    // #region Fields
    /**
     * The path pattern for this route.
     *
     * @public
     * @readonly
     */
    path;
    /**
     * The component to render when this route matches.
     *
     * Supports three forms:
     * - A tag-name string (e.g. `'my-page'`)
     * - An `HTMLElement` constructor
     * - A lazy-loading function returning a `Promise<HTMLElementConstructor>`
     *
     * @public
     * @readonly
     */
    component;
    /**
     * Nested child routes.
     *
     * @public
     */
    children = [];
    /**
     * Guard functions executed before the route is entered.
     * All guards must return `true` for navigation to proceed.
     *
     * @public
     */
    beforeEnter = [];
    /**
     * The compiled `URLPattern` instance derived from the route's `path`.
     *
     * @public
     * @readonly
     */
    urlPattern;
    _parent = null;
    // #endregion
    // #region Ctor
    /**
     * Creates a new `Route` instance.
     *
     * @param path - The URL path pattern.
     * @param component - The component to render when matched.
     *
     * @public
     */
    constructor(path, component) {
        this.path = path;
        this.component = component;
        this.urlPattern = new URLPattern(this.path, window.location.origin);
    }
    // #endregion
    // #region Methods
    /**
     * Assigns a parent route for hierarchical resolution.
     *
     * @param parent - The parent `Route` instance.
     *
     * @public
     */
    setParent(parent) {
        this._parent = parent;
    }
    /**
     * Tests whether the given `path` matches this route's URL pattern.
     *
     * @param path - The pathname to test.
     * @returns `true` if the path matches.
     *
     * @public
     */
    match(path) {
        return this.urlPattern.test(window.location.origin + path);
    }
    /**
     * Recursively resolves all `beforeEnter` guards for this route
     * and its parent chain.
     *
     * @param router - The guard context providing navigation helpers.
     * @returns `true` if all guards pass.
     *
     * @public
     */
    async resolveRecursiveGuard(router) {
        if (!this.beforeEnter.length) {
            return Promise.resolve(true);
        }
        const guards = this.beforeEnter.map((guard) => guard(router));
        const results = await Promise.all(guards);
        const parentGuardResult = this._parent
            ? await this._parent.resolveRecursiveGuard(router)
            : true;
        return results.every((result) => result) && parentGuardResult;
    }
    /**
     * Resolves the component (including lazy-loaded modules) and, when a
     * parent exists, nests the result inside the parent component using the
     * Chain of Responsibility pattern.
     *
     * @param component - Optional factory returning the pre-resolved child element.
     * @returns The resolved `HTMLElement` (possibly wrapped in parent elements).
     *
     * @public
     */
    async resolve(component) {
        let resolvedComponent = component ? component() : null;
        if (!resolvedComponent) {
            resolvedComponent = (await this.resolveComponent(this.component));
        }
        if (this._parent) {
            const parent = (await this.resolveComponent(this._parent.component));
            const child = resolvedComponent;
            parent.appendChild(child);
            return this._parent.resolve(() => parent);
        }
        return resolvedComponent;
    }
    /**
     * Resolves a single component reference to an `HTMLElement` instance.
     *
     * @param component - Tag name, constructor, or lazy-loader.
     *
     * @private
     */
    async resolveComponent(component) {
        // Resolve by tag name.
        if (typeof component === 'string') {
            return document.createElement(component);
        }
        // Resolve a custom-element constructor.
        if (typeof component === 'function' && component.prototype instanceof HTMLElement) {
            return new component();
        }
        // Resolve a lazy-loaded module.
        const Module = await component();
        return new Module();
    }
}
//# sourceMappingURL=Route.js.map