import { __decorate } from 'tslib';
import SgdsElement from '../../base/sgds-element.js';
import { html } from 'lit';
import { property, query, state } from 'lit/decorators.js';
import { classMap } from 'lit/directives/class-map.js';
import { watch } from '../../utils/watch.js';
import { waitForEvent } from '../../utils/event.js';
import { stopAnimations, animateTo, shimKeyframesHeightAuto } from '../../utils/animate.js';
import { setDefaultAnimation, getAnimation } from '../../utils/animation-registry.js';
import { LG_BREAKPOINT, MD_BREAKPOINT } from '../../utils/breakpoints.js';
import { SgdsIcon } from '../Icon/sgds-icon.js';
import css_248z from './subnav.js';
import css_248z$1 from '../../css/grid.js';
import { HasSlotController } from '../../utils/slot.js';

const VALID_KEYS = ["Enter", " "];
/**
 * @summary This component provides secondary navigation within a specific section or page. It typically appears below the main navigation and offers context-specific links or actions to help users explore related content.
 *
 * @event sgds-show - Emitted on show. Only for collapsed menu.
 * @event sgds-after-show - Emitted on show after animation has completed. Only for collapsed menu.
 * @event sgds-hide - Emitted on hide. Only for collapsed menu.
 * @event sgds-after-hide - Emitted on hide after animation has completed. Only for collapsed menu.
 *
 * @slot default - Default slot of SgdsSubnav. Pass in SgdsSubnavItem elements here.
 * @slot header - Slot for rendering the sub-navigation header or section title.
 * @slot actions - Slot for inserting contextual action elements such as buttons, filters, or other controls aligned with the sub-navigation.
 *
 */
class SgdsSubnav extends SgdsElement {
    constructor() {
        super(...arguments);
        /** Used only for SSR to indicate the presence of the `actions` slot. */
        this.hasActionsSlot = false;
        this.isCollapsed = false;
        this.isMenuOpen = false;
        this.hasSlotController = new HasSlotController(this, "actions");
        this._handleResize = async () => {
            this.isCollapsed = window.innerWidth < LG_BREAKPOINT;
            await this.updateComplete;
            if (!this.isCollapsed) {
                this.isMenuOpen = false;
            }
            this._updateMobileLayout();
        };
        this._updateMobileLayout = () => {
            if (!this.nav || !this.headerContainer || !this.mobileActions || !this.mobileNav)
                return;
            if (this.isCollapsed) {
                const { top: subnavTop } = this.nav.getBoundingClientRect();
                const headerHeight = this.headerContainer.clientHeight;
                const actionsButtonHeight = this.mobileActions.clientHeight;
                const offset = window.innerWidth >= MD_BREAKPOINT && window.innerWidth < LG_BREAKPOINT
                    ? subnavTop + headerHeight
                    : subnavTop + headerHeight + actionsButtonHeight;
                this.mobileNav.style.maxHeight = `calc(100dvh - ${offset}px)`;
                this.style.minHeight = `${this.nav.clientHeight}px`;
                this.nav.style.position = "absolute";
            }
            else {
                this.mobileNav.style.maxHeight = "none";
                this.style.minHeight = "auto";
                this.nav.style.position = "relative";
            }
        };
        this._toggleMenu = () => {
            var _a;
            if (this.isMenuOpen) {
                this.hide();
            }
            else {
                document.querySelector("body").style.overflow = "hidden";
                this.show();
            }
            (_a = this.toggler) === null || _a === void 0 ? void 0 : _a.focus();
        };
    }
    connectedCallback() {
        super.connectedCallback();
        // this._handleResize();
        window.addEventListener("resize", this._handleResize);
        window.addEventListener("click", (event) => this._handleClickOutOfElement(event, this.navGroup));
    }
    disconnectedCallback() {
        super.disconnectedCallback();
        window.removeEventListener("resize", this._handleResize);
        window.removeEventListener("click", (event) => this._handleClickOutOfElement(event, this.navGroup));
    }
    firstUpdated(changedProperties) {
        super.firstUpdated(changedProperties);
        this._handleResize();
    }
    updated() {
        if (!this.hasActionsSlot)
            this.hasActionsSlot = this.hasSlotController.test("actions");
    }
    _handleClickOutOfElement(e, self) {
        if (!e.composedPath().includes(self) && !e.composedPath().includes(this.toggler)) {
            this.hide();
        }
    }
    async _onKeyboardToggle(event) {
        if (!VALID_KEYS.includes(event.key))
            return;
        event.preventDefault();
        this._toggleMenu();
    }
    /** Shows the menu. For when subnav is in the collapsed form */
    async show() {
        if (this.isMenuOpen) {
            return;
        }
        this.isMenuOpen = true;
        return waitForEvent(this, "sgds-after-show");
    }
    /** Hide the menu. For when subnav is in the collapsed form */
    async hide() {
        if (!this.isMenuOpen) {
            return;
        }
        this.isMenuOpen = false;
        document.querySelector("body").style.removeProperty("overflow");
        return waitForEvent(this, "sgds-after-hide");
    }
    async _animateToShow() {
        const sgdsShow = this.emit("sgds-show", { cancelable: true });
        if (sgdsShow.defaultPrevented) {
            this.isMenuOpen = false;
            return;
        }
        await stopAnimations(this.mobileNav);
        if (this.isCollapsed) {
            this.mobileNav.style.display = "flex";
        }
        const { keyframes, options } = getAnimation(this, "subnav.show");
        await animateTo(this.mobileNav, shimKeyframesHeightAuto(keyframes, this.mobileNav.scrollHeight), options);
        this.emit("sgds-after-show");
    }
    async _animateToHide() {
        const slHide = this.emit("sgds-hide", { cancelable: true });
        if (slHide.defaultPrevented) {
            this.isMenuOpen = true;
            return;
        }
        await stopAnimations(this.mobileNav);
        const { keyframes, options } = getAnimation(this, "subnav.hide");
        await animateTo(this.mobileNav, shimKeyframesHeightAuto(keyframes, this.mobileNav.scrollHeight), options);
        if (this.isCollapsed) {
            this.mobileNav.style.display = "none";
        }
        this.emit("sgds-after-hide");
    }
    async handleOpenChange() {
        if (this.isMenuOpen) {
            // Show
            this._animateToShow();
        }
        else {
            // Hide
            this._animateToHide();
        }
    }
    async handleCollapsedChange() {
        await this.updateComplete;
        this.mobileNav.style.display = this.isCollapsed ? "none" : "flex";
    }
    render() {
        return html `
      <nav aria-label="Sub navigation">
        <div
          class=${classMap({
            "sgds-container": true,
            subnav: true,
            collapsed: !this.isMenuOpen
        })}
        >
          <div class="header-container">
            <slot name="header"></slot>
            <sgds-icon
              class="subnav-toggler"
              name="chevron-down"
              tabindex="0"
              @click=${this._toggleMenu}
              @keydown=${this._onKeyboardToggle}
              aria-label="Toggle sub navigation"
              aria-expanded=${this.isMenuOpen}
            ></sgds-icon>
          </div>
          <div class="subnav-nav-group">
            <div class="subnav-nav">
              <slot></slot>
            </div>
            <div
              class="${classMap({
            "subnav-actions": true,
            "no-actions": !this.hasActionsSlot
        })}"
            >
              <slot name="actions"></slot>
            </div>
          </div>
        </div>
      </nav>
    `;
    }
}
SgdsSubnav.styles = [...SgdsElement.styles, css_248z, css_248z$1];
/** @internal */
SgdsSubnav.dependencies = {
    "sgds-icon": SgdsIcon
};
__decorate([
    property({ type: Boolean })
], SgdsSubnav.prototype, "hasActionsSlot", void 0);
__decorate([
    query("nav")
], SgdsSubnav.prototype, "nav", void 0);
__decorate([
    query(".subnav-nav")
], SgdsSubnav.prototype, "mobileNav", void 0);
__decorate([
    query(".header-container")
], SgdsSubnav.prototype, "headerContainer", void 0);
__decorate([
    query(".subnav-toggler")
], SgdsSubnav.prototype, "toggler", void 0);
__decorate([
    query(".subnav-nav-group")
], SgdsSubnav.prototype, "navGroup", void 0);
__decorate([
    query(".subnav-actions")
], SgdsSubnav.prototype, "mobileActions", void 0);
__decorate([
    state()
], SgdsSubnav.prototype, "isCollapsed", void 0);
__decorate([
    state()
], SgdsSubnav.prototype, "isMenuOpen", void 0);
__decorate([
    watch("isMenuOpen", { waitUntilFirstUpdate: true })
], SgdsSubnav.prototype, "handleOpenChange", null);
__decorate([
    watch("isCollapsed", { waitUntilFirstUpdate: true })
], SgdsSubnav.prototype, "handleCollapsedChange", null);
setDefaultAnimation("subnav.show", {
    keyframes: [
        { height: "0", opacity: "0" },
        { height: "auto", opacity: "1" }
    ],
    options: { duration: 200, easing: "ease-in-out" }
});
setDefaultAnimation("subnav.hide", {
    keyframes: [
        { height: "auto", opacity: "1" },
        { height: "0", opacity: "0" }
    ],
    options: { duration: 200, easing: "ease-in-out" }
});

export { SgdsSubnav, SgdsSubnav as default };
//# sourceMappingURL=sgds-subnav.js.map
