// #region Imports
// #endregion
/**
 * Provides an abstraction over `window.location` that automatically adapts
 * to the currently active routing strategy (hash vs. path-based routing).
 *
 * This class is designed to be framework-agnostic but works best within the
 * `mosaik-router` ecosystem. It allows consistent access to routing-relevant
 * values such as pathname, search parameters, and origin – regardless of how
 * routing is implemented.
 *
 * @example
 * const location = new RouterLocation(() => router.useHash);
 * const path = location.pathname;
 * const query = location.search;
 *
 * @public
 */
export class RouterLocation {
    // #region Fields
    /**
     * A resolver function that determines whether hash-based routing is active.
     * This allows the location behavior to dynamically respond to runtime configuration.
     */
    _useHashFn;
    // #endregion
    // #region Ctor
    /**
     * Constructs a new instance of the `RouterLocation` class.
     *
     * @param useHashFn - A function that returns the current value of `useHash` routing mode.
     */
    constructor(useHashFn) {
        this._useHashFn = useHashFn;
    }
    // #endregion
    // #region Properties
    /**
     * Gets the current full document location URL.
     */
    get href() {
        return window.location.href;
    }
    /**
     * Gets the normalized pathname of the application route.
     * Automatically strips the hash prefix if `useHash` mode is active.
     */
    get pathname() {
        if (this._useHashFn()) {
            const hash = window.location.hash; // e.g. "#/support#tab"
            const secondHashIndex = hash.indexOf('#', 1);
            const routePart = secondHashIndex === -1 ? hash : hash.substring(0, secondHashIndex);
            return routePart.startsWith('#') ? routePart.substring(1) : routePart;
        }
        return window.location.pathname;
    }
    /**
     * Gets the normalized search string (query parameters) for the current route.
     */
    get search() {
        return window.location.search;
    }
    /**
     * Gets the app-level route, which combines `pathname` and `search`.
     */
    get route() {
        return this.pathname + this.search;
    }
    /**
     * Gets the raw hash string (including the `#`).
     * Note: when using hash-based routing, this should be ignored in favor of `pathname`.
     */
    get hash() {
        if (this._useHashFn()) {
            const hash = window.location.hash;
            const secondHashIndex = hash.indexOf('#', 1);
            return secondHashIndex === -1 ? '' : hash.substring(secondHashIndex + 1);
        }
        return window.location.hash.startsWith('#') ? window.location.hash.substring(1) : '';
    }
    /**
     * Gets the hostname (e.g. "localhost").
     */
    get hostname() {
        return window.location.hostname;
    }
    /**
     * Gets the full origin (e.g. "http://localhost:8080").
     */
    get origin() {
        return window.location.origin;
    }
    /**
     * Gets the host (hostname + port).
     */
    get host() {
        return window.location.host;
    }
    /**
     * Gets the port number (e.g. "8080").
     */
    get port() {
        return window.location.port;
    }
    /**
     * Gets the protocol used (e.g. "http:").
     */
    get protocol() {
        return window.location.protocol;
    }
    // #endregion
    // #region Methods
    /**
     * Navigates programmatically to a new route.
     * Uses `hash` or `history.pushState` depending on the routing strategy.
     *
     * @param path - The route path to navigate to.
     */
    navigate(path) {
        if (this._useHashFn()) {
            window.location.hash = `#${path}`;
        }
        else {
            window.history.pushState({}, '', path);
        }
    }
}
/**
 * Service locator for accessing the current `RouterLocation` instance globally.
 * Intended for use in scenarios where dependency injection is not available.
 *
 * @example
 * const currentPath = RouterLocationServiceLocator.current.pathname;
 *
 * @public
 */
export class RouterLocationServiceLocator {
    /**
     * Internal storage for the registered location instance.
     */
    static _current = null;
    /**
     * Gets the globally registered `RouterLocation` instance.
     * Throws an error if not set.
     */
    static get current() {
        if (!RouterLocationServiceLocator.isSet()) {
            throw new Error('\'RouterLocation\' not set.');
        }
        // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
        return RouterLocationServiceLocator._current;
    }
    /**
     * Returns whether a `RouterLocation` instance is registered.
     */
    static isSet() {
        return RouterLocationServiceLocator._current !== null;
    }
    /**
     * Registers the current `RouterLocation` instance.
     *
     * @param current - The location instance to register globally.
     */
    static set(current) {
        RouterLocationServiceLocator._current = current;
    }
}
/**
 * @public
 */
RouterLocationServiceLocator.set(new RouterLocation(() => false));
//# sourceMappingURL=RouterLocation.js.map