// #region Imports
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
    var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
    if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
    else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
    return c > 3 && r && Object.defineProperty(target, key, r), r;
};
var __metadata = (this && this.__metadata) || function (k, v) {
    if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
};
import { Attribute } from '../../../Decorators/AttributeDecorator';
import { Component } from '../../../Decorators/ComponentDecorator';
import { CustomElement } from '../../Abstracts/CustomElement';
import { regionElementTemplate } from './RegionElementTemplate';
import { RegionViewElement } from './RegionViewElement';
import { Themeable } from '../../../Behaviors/Themeable';
import { regionElementCosmopolitanStyle } from './Themes/RegionElement.Cosmopolitan';
import { regionElementJoyStyle } from './Themes/RegionElement.Joy';
import { regionElementMemphisStyle } from './Themes/RegionElement.Memphis';
// #endregion
/**
 * Region - A container that hosts multiple view definitions with exclusive activation.
 *
 * Manages the lifecycle of views within it, ensuring only one view is instantiated and rendered at a time.
 * Views are lazily instantiated when activated and cleanly destroyed when deactivated,
 * providing efficient memory usage and proper lifecycle management for complex multi-view layouts.
 *
 * Perfect for wizards, steppers, tabbed interfaces, or any scenario requiring mutually exclusive view states
 * without manual DOM manipulation or conditional rendering logic in templates.
 *
 * @name RegionElement
 * @element mosaik-region
 * @category Grouping
 *
 * @slot default - Contains mosaik-region-view definitions to be managed by the region
 *
 * @csspart host - The container element that renders the active view's content
 *
 * @fires activeChanged - Fired when the active view changes, with detail { active: string, previous?: string }
 *
 * @dependency RegionViewElement - View definition component
 *
 * @example
 * ```html
 * <!-- Basic region with navigation -->
 * <mosaik-region id="wizard" active="step1">
 *   <mosaik-region-view name="step1" default>
 *     <div>Welcome to Step 1</div>
 *   </mosaik-region-view>
 *   <mosaik-region-view name="step2">
 *     <div>Proceed to Step 2</div>
 *   </mosaik-region-view>
 *   <mosaik-region-view name="step3">
 *     <div>Final Step</div>
 *   </mosaik-region-view>
 * </mosaik-region>
 *
 * <script>
 *   const region = document.getElementById('wizard');
 *   region.activate('step2'); // Switch to step 2
 * </script>
 * ```
 *
 * @example
 * ```html
 * <!-- Tabbed interface -->
 * <mosaik-region active="overview">
 *   <mosaik-region-view name="overview" default>
 *     <my-overview-component></my-overview-component>
 *   </mosaik-region-view>
 *   <mosaik-region-view name="details">
 *     <my-details-component></my-details-component>
 *   </mosaik-region-view>
 *   <mosaik-region-view name="settings">
 *     <my-settings-component></my-settings-component>
 *   </mosaik-region-view>
 * </mosaik-region>
 *
 * <mosaik-button-group>
 *   <mosaik-button onclick="document.querySelector('mosaik-region').activate('overview')">Overview</mosaik-button>
 *   <mosaik-button onclick="document.querySelector('mosaik-region').activate('details')">Details</mosaik-button>
 *   <mosaik-button onclick="document.querySelector('mosaik-region').activate('settings')">Settings</mosaik-button>
 * </mosaik-button-group>
 * ```
 *
 * @public
 */
let RegionElement = class RegionElement extends Themeable(CustomElement) {
    // #region Fields
    _viewDefinitions;
    _active;
    _currentActiveName;
    _hostContainer;
    _isInitialized;
    // #endregion
    // #region Ctor
    /**
     * @public
     */
    constructor() {
        super();
        this._active = '';
        this._currentActiveName = null;
        this._hostContainer = null;
        this._isInitialized = false;
        this._viewDefinitions = new Map();
    }
    // #endregion
    // #region Properties
    /**
     * Returns the `{@link is}` property.
     * The `{@link is}` property represents natural name of this element.
     *
     * @public
     * @static
     * @readonly
     */
    static get is() {
        return 'mosaik-region';
    }
    /**
     * The name of the currently active view.
     *
     * @public
     */
    get active() {
        return this._active;
    }
    set active(value) {
        const oldValue = this._active;
        this._active = value;
        this.requestUpdate('active', oldValue);
    }
    // #endregion
    // #region Methods
    /**
     * @public
     * @override
     */
    connectedCallback() {
        super.connectedCallback();
        if (!this._isInitialized) {
            this.collectViewDefinitions();
            this.determineInitialActive();
            this._isInitialized = true;
        }
    }
    /**
     * @public
     * @override
     */
    firstUpdated(changedProperties) {
        super.firstUpdated(changedProperties);
        // Get the host container reference
        this._hostContainer = this.shadowRoot?.querySelector('[part="host"]') ?? null;
        // Wait for all child views to be ready before rendering
        void this.waitForViewsAndRender();
    }
    /**
     * Waits for all child RegionViewElements to complete their firstUpdated
     * and capture their templates before rendering the active view.
     *
     * @private
     */
    async waitForViewsAndRender() {
        // Wait for all view elements to complete their update cycle
        const viewElements = Array.from(this._viewDefinitions.values());
        await Promise.all(viewElements.map((view) => view.updateComplete));
        // Now render the active view
        if (this._active) {
            this.renderActiveView();
        }
    }
    /**
     * @public
     * @override
     */
    updated(changedProperties) {
        super.updated(changedProperties);
        if (changedProperties.has('active')) {
            this.renderActiveView();
        }
    }
    /**
     * Activates a view by name.
     *
     * @param name - The name of the view to activate
     * @public
     */
    activate(name) {
        this.active = name;
    }
    /**
     * Collects all mosaik-region-view children and builds the view definitions map.
     *
     * @private
     */
    collectViewDefinitions() {
        const viewElements = this.querySelectorAll(':scope > mosaik-region-view');
        this._viewDefinitions.clear();
        viewElements.forEach((view) => {
            const name = view.name;
            if (!name) {
                console.warn('mosaik-region-view requires a unique name attribute', view);
                return;
            }
            if (this._viewDefinitions.has(name)) {
                console.warn(`mosaik-region: duplicate view name "${name}" detected, using first occurrence`, this);
                return;
            }
            this._viewDefinitions.set(name, view);
        });
        if (this._viewDefinitions.size === 0) {
            console.warn('mosaik-region: no valid view definitions found', this);
        }
    }
    /**
     * Determines the initial active view based on the active attribute, default attribute, or first view.
     *
     * @private
     */
    determineInitialActive() {
        // If active is already set and valid, use it
        if (this._active && this._viewDefinitions.has(this._active)) {
            return;
        }
        // Look for a view with default attribute
        for (const [name, view] of this._viewDefinitions) {
            if (view.default) {
                this._active = name;
                return;
            }
        }
        // Fall back to the first view
        const firstView = Array.from(this._viewDefinitions.keys())[0];
        if (firstView) {
            this._active = firstView;
        }
    }
    /**
     * Renders the currently active view by cloning its template content.
     *
     * @private
     */
    renderActiveView() {
        if (!this._hostContainer) {
            return;
        }
        const previousActive = this._currentActiveName;
        // Clear the current view (triggers disconnectedCallback on child components)
        while (this._hostContainer.firstChild) {
            this._hostContainer.removeChild(this._hostContainer.firstChild);
        }
        // Validate and render the new active view
        const viewDefinition = this._viewDefinitions.get(this._active);
        if (!viewDefinition) {
            const availableViews = Array.from(this._viewDefinitions.keys()).join(', ');
            console.warn(`mosaik-region: active view "${this._active}" not found. Available views: ${availableViews || 'none'}`, this);
            // Fallback to first view if current active is invalid
            const fallbackView = Array.from(this._viewDefinitions.keys())[0];
            if (fallbackView && fallbackView !== this._active) {
                this._active = fallbackView;
                this.renderActiveView();
            }
            return;
        }
        // Clone the template content and append to host
        const template = viewDefinition.getTemplate();
        if (template) {
            const clone = template.content.cloneNode(true);
            this._hostContainer.appendChild(clone);
        }
        this._currentActiveName = this._active;
        // Dispatch active-changed event
        this._dispatchActiveChangedEvent(previousActive);
    }
    /**
     * Dispatches the active-changed event.
     *
     * @param previousActive - The previously active view name
     * @private
     */
    _dispatchActiveChangedEvent(previousActive) {
        const detail = {
            active: this._active,
            previous: previousActive
        };
        this.dispatchEvent(new CustomEvent('activeChanged', {
            bubbles: true,
            composed: true,
            detail
        }));
    }
};
__decorate([
    Attribute({
        type: String,
        useDefault: true
    }),
    __metadata("design:type", String),
    __metadata("design:paramtypes", [String])
], RegionElement.prototype, "active", null);
RegionElement = __decorate([
    Component({
        selector: 'mosaik-region',
        template: regionElementTemplate,
        themes: {
            joy: regionElementJoyStyle,
            memphis: regionElementMemphisStyle,
            cosmopolitan: regionElementCosmopolitanStyle
        },
        imports: [
            RegionViewElement
        ]
    }),
    __metadata("design:paramtypes", [])
], RegionElement);
export { RegionElement };
//# sourceMappingURL=RegionElement.js.map