import { Host, h, } from "@stencil/core";
import { DEVICE_SIZES, getCurrentDeviceSize, getBrandForegroundAppearance, getNavItemParentDetails, } from "../../utils/helpers";
import chevronIcon from "../../assets/chevron-icon.svg";
export class NavigationGroup {
    constructor() {
        this.allGroupedNavigationItems = [];
        this.DYNAMIC_GROUPED_LINKS_HEIGHT_MS = 100;
        this.IC_NAVIGATION_ITEM = "ic-navigation-item";
        this.mouseGate = false;
        this.nodeName = "IC-NAVIGATION-GROUP";
        this.GROUPED_LINKS_WRAPPER_CLASS = ".grouped-links-wrapper";
        this.deviceSize = DEVICE_SIZES.XL;
        this.dropdownOpen = false;
        this.expanded = true;
        this.focusStyle = getBrandForegroundAppearance();
        this.inTopNavSideMenu = false;
        /**
         *  If `true`, the group will be expandable when in an ic-side-navigation component, or, when in an ic-top-navigation component, in the side menu displayed at small screen sizes.
         */
        this.expandable = false;
        /**
         * Sets the theme color to the dark or light theme color. "inherit" will set the color based on the system settings or ic-theme component.
         */
        this.theme = "inherit";
        this.sideNavExpandHandler = (event) => {
            var _a;
            this.isSideNavExpanded = event.detail.sideNavExpanded;
            const linkWrapper = (_a = this.el.shadowRoot) === null || _a === void 0 ? void 0 : _a.querySelector(this.GROUPED_LINKS_WRAPPER_CLASS);
            if (!linkWrapper)
                return;
            if (this.isSideNavExpanded) {
                if (this.expanded && this.expandedNavItemsHeight) {
                    this.setGroupedLinksElementHeight(linkWrapper, this.expandedNavItemsHeight);
                }
                else if (this.expanded) {
                    setTimeout(() => {
                        this.expandedNavItemsHeight = this.getNavigationChildItemsHeight();
                        this.setGroupedLinksElementHeight(linkWrapper, this.expandedNavItemsHeight);
                    }, this.DYNAMIC_GROUPED_LINKS_HEIGHT_MS);
                }
            }
            else {
                if (this.expanded && this.collapsedNavItemsHeight) {
                    this.setGroupedLinksElementHeight(linkWrapper, this.collapsedNavItemsHeight);
                }
                else if (this.expanded) {
                    setTimeout(() => {
                        this.collapsedNavItemsHeight = this.getNavigationChildItemsHeight();
                        this.setGroupedLinksElementHeight(linkWrapper, this.collapsedNavItemsHeight);
                    }, this.DYNAMIC_GROUPED_LINKS_HEIGHT_MS);
                }
            }
        };
        this.topNavResizedHandler = ({ detail, }) => {
            var _a;
            const { size } = detail;
            if (size !== this.deviceSize) {
                this.deviceSize = size;
                this.inTopNavSideMenu =
                    size <=
                        (((_a = this.parentEl) === null || _a === void 0 ? void 0 : _a.customMobileBreakpoint) || DEVICE_SIZES.L);
            }
        };
        this.setGroupedNavItemTabIndex = (tabIndexValue) => {
            this.el
                .querySelectorAll(this.IC_NAVIGATION_ITEM)
                .forEach((navigationItem) => {
                var _a;
                const navItem = ((_a = navigationItem.shadowRoot) === null || _a === void 0 ? void 0 : _a.querySelector("a")) ||
                    navigationItem.querySelector("a");
                if (navItem) {
                    navItem.setAttribute("tabindex", tabIndexValue);
                }
            });
        };
        this.toggleGroupedLinkWrapperHeight = (wrapper, expanded) => {
            if (!wrapper)
                return;
            if (expanded) {
                if (this.isSideNavExpanded) {
                    this.setGroupedLinksElementHeight(wrapper, this.expandedNavItemsHeight);
                }
                else {
                    this.setGroupedLinksElementHeight(wrapper, this.collapsedNavItemsHeight);
                }
                this.setGroupedNavItemTabIndex("0");
            }
            else {
                wrapper.style.setProperty("--navigation-child-items-height", "0");
                this.setGroupedNavItemTabIndex("-1");
            }
        };
        this.toggleExpanded = () => {
            var _a;
            this.expanded = !this.expanded;
            const linkWrapper = (_a = this.el.shadowRoot) === null || _a === void 0 ? void 0 : _a.querySelector(this.GROUPED_LINKS_WRAPPER_CLASS);
            this.toggleGroupedLinkWrapperHeight(linkWrapper, this.expanded);
        };
        this.handleClick = (ev) => {
            if (this.navigationType === "top" && ev.detail) {
                this.toggleDropdown();
            }
            else {
                this.toggleExpanded();
            }
        };
        this.handleBlur = (ev) => {
            const target = ev.relatedTarget;
            if (!this.el.contains(target)) {
                this.hideDropdown();
            }
        };
        this.handleTopNavKeydown = (ev) => {
            if (ev.key === " " || ev.key === "Enter") {
                this.toggleDropdown();
            }
            else if (!this.inTopNavSideMenu && ev.key === "Escape") {
                this.hideDropdown();
            }
        };
        this.handleKeydown = (ev) => {
            if (ev.key === "Enter" || ev.key === " " || ev.key === "Escape") {
                switch (this.navigationType) {
                    case "top":
                        this.handleTopNavKeydown(ev);
                        break;
                    case "side":
                        this.toggleExpanded();
                        ev.preventDefault();
                        break;
                    default:
                        this.toggleExpanded();
                        break;
                }
            }
        };
        this.handleMouseLeave = (ev) => {
            const relTarget = ev.relatedTarget;
            this.mouseGate = false;
            if (!this.el.contains(relTarget) &&
                relTarget !== this.dropdown &&
                document.activeElement !== this.el &&
                !this.el.contains(document.activeElement) &&
                (relTarget === null || relTarget === void 0 ? void 0 : relTarget.nodeName) === this.nodeName &&
                this.dropdownOpen === true) {
                this.mouseGate = true;
                this.hideDropdown();
            }
            else if (!this.el.contains(relTarget) &&
                relTarget !== this.dropdown &&
                !this.el.contains(document.activeElement)) {
                this.mouseGate = false;
                setTimeout(() => {
                    this.dropdownOpen ? this.hideDropdown() : null;
                }, 500);
            }
        };
        this.handleMouseEnter = (ev) => {
            const relTarget = ev.relatedTarget;
            document.addEventListener("keydown", this.handleKeydown);
            if ((relTarget === null || relTarget === void 0 ? void 0 : relTarget.nodeName) === this.nodeName && this.mouseGate === true) {
                this.showDropdown();
            }
            else if (this.dropdownOpen === false &&
                relTarget !== null &&
                this.mouseGate === false) {
                this.mouseGate = true;
                setTimeout(() => {
                    this.mouseGate && this.showDropdown();
                }, 500);
            }
        };
        this.renderDropdownGroupedLinks = () => (h("div", { class: {
                ["navigation-group-dropdown"]: !this.inTopNavSideMenu,
                ["navigation-group-dropdown-side-menu"]: this.inTopNavSideMenu,
                ["selected"]: this.dropdownOpen && !this.inTopNavSideMenu,
            }, onMouseLeave: !this.inTopNavSideMenu ? this.handleMouseLeave : undefined, ref: (el) => (this.dropdown = el) }, h("nav", { class: {
                ["navigation-group-dropdown-items"]: !this.inTopNavSideMenu,
            }, "aria-labelledby": "nav-group-title" }, h("ul", null, h("slot", null)))));
        this.renderGroupedLinks = () => (h("ul", { class: "grouped-links-wrapper" }, h("slot", null)));
        /**
         * Gets the total height of navigation links to improve
         * smoothness of expand/collapse animations
         */
        this.getNavigationChildItemsHeight = () => {
            let navigationChildItemsHeight = 0;
            this.allGroupedNavigationItems.forEach((navItem) => {
                navigationChildItemsHeight += navItem.offsetHeight;
            });
            return `${navigationChildItemsHeight}px`;
        };
        this.setInitialGroupedLinksWrapperHeight = () => {
            var _a;
            const linkWrapper = (_a = this.el.shadowRoot) === null || _a === void 0 ? void 0 : _a.querySelector(this.GROUPED_LINKS_WRAPPER_CLASS);
            if (!linkWrapper)
                return;
            if (!this.isSideNavExpanded &&
                !this.collapsedNavItemsHeight &&
                this.expanded) {
                this.collapsedNavItemsHeight = this.getNavigationChildItemsHeight();
                this.setGroupedLinksElementHeight(linkWrapper, this.collapsedNavItemsHeight);
            }
            if (this.isSideNavExpanded && this.expanded) {
                this.expandedNavItemsHeight = this.getNavigationChildItemsHeight();
                this.setGroupedLinksElementHeight(linkWrapper, this.expandedNavItemsHeight);
            }
        };
        this.renderGroupTitleText = () => (h("ic-typography", { id: "nav-group-title", variant: this.navigationType === "side" ? "caption" : "label" }, this.label));
        this.renderNavigationItems = () => {
            if (this.dropdownOpen || (this.inTopNavSideMenu && !this.expandable)) {
                return this.renderDropdownGroupedLinks();
            }
            if (this.navigationType !== "top") {
                return this.renderGroupedLinks();
            }
            return null;
        };
    }
    disconnectedCallback() {
        var _a, _b;
        if (this.navigationType === "side") {
            (_a = this.parentEl) === null || _a === void 0 ? void 0 : _a.removeEventListener("icSideNavExpanded", this.sideNavExpandHandler);
        }
        else if (this.navigationType === "top") {
            (_b = this.parentEl) === null || _b === void 0 ? void 0 : _b.removeEventListener("icTopNavResized", this.topNavResizedHandler);
        }
    }
    componentWillLoad() {
        var _a, _b;
        this.deviceSize = getCurrentDeviceSize();
        const { navType, parent } = getNavItemParentDetails(this.el);
        this.navigationType = navType;
        this.parentEl = parent;
        if (this.navigationType === "side") {
            (_a = this.parentEl) === null || _a === void 0 ? void 0 : _a.addEventListener("icSideNavExpanded", this.sideNavExpandHandler);
        }
        else if (this.navigationType === "top") {
            (_b = this.parentEl) === null || _b === void 0 ? void 0 : _b.addEventListener("icTopNavResized", this.topNavResizedHandler);
            if (this.deviceSize <=
                this.parentEl.customMobileBreakpoint)
                this.inTopNavSideMenu = true;
        }
    }
    componentDidLoad() {
        this.allGroupedNavigationItems = Array.from(this.el.querySelectorAll(this.IC_NAVIGATION_ITEM));
        /**
         * debounce is required as the incorrect height was retrieved instantly after
         * componentDidLoad is invoked.
         */
        setTimeout(() => this.setInitialGroupedLinksWrapperHeight(), this.DYNAMIC_GROUPED_LINKS_HEIGHT_MS);
    }
    childBlurHandler() {
        this.hideDropdown();
    }
    handleNavigationGroupOpened(event) {
        if (event.detail.source !== this.el) {
            this.hideDropdown();
        }
    }
    navItemClickHandler() {
        this.hideDropdown();
    }
    brandChangeHandler(ev) {
        this.focusStyle = ev.detail.mode;
    }
    /**
     * Sets focus on the nav item.
     */
    async setFocus() {
        if (this.groupEl) {
            this.groupEl.focus();
        }
    }
    toggleDropdown() {
        this.dropdownOpen = !this.dropdownOpen;
        this.inTopNavSideMenu &&
            this.navigationGroupExpanded.emit({ expanded: this.dropdownOpen });
    }
    showDropdown() {
        if (!this.dropdownOpen) {
            this.navigationGroupOpened.emit({
                source: this.el,
            });
            this.toggleDropdown();
        }
    }
    hideDropdown() {
        document.removeEventListener("keydown", this.handleKeydown);
        if (this.dropdownOpen) {
            this.toggleDropdown();
        }
    }
    setGroupedLinksElementHeight(groupedNavItemWrapper, height) {
        groupedNavItemWrapper.style.setProperty("--navigation-child-items-height", height);
    }
    render() {
        const { dropdownOpen, expanded, inTopNavSideMenu, expandable } = this;
        const navGroupTitleClassNames = {
            ["navigation-group"]: true,
            [this.focusStyle]: !inTopNavSideMenu,
            ["navigation-group-side-menu-collapsed"]: inTopNavSideMenu && !!expandable && !dropdownOpen,
            ["navigation-group-side-menu-expanded"]: inTopNavSideMenu && !!expandable && dropdownOpen,
            ["selected"]: dropdownOpen && !inTopNavSideMenu,
        };
        const isSideNav = this.navigationType === "side";
        const isTopNav = this.navigationType === "top";
        const ariaExpanded = (isSideNav && expanded) || (isTopNav && dropdownOpen);
        return (h(Host, { key: 'd89ce479bb2f5142a2ef6dd2284229a73367c916', class: {
                ["in-side-menu"]: inTopNavSideMenu,
                "ic-navigation-group-expanded": expanded,
                "ic-navigation-group-collapsed": !expanded,
                ["ic-navigation-group-side-nav"]: isSideNav,
                [`ic-theme-${this.theme}`]: this.theme !== "inherit",
                ["ic-navigation-group-expandable"]: !!expandable,
            }, role: "listitem" }, this.expandable || (!inTopNavSideMenu && isTopNav) ? (h("button", { onMouseEnter: !inTopNavSideMenu && isTopNav ? this.handleMouseEnter : undefined, onMouseLeave: isTopNav ? this.handleMouseLeave : undefined, onBlur: this.handleBlur, onClick: this.handleClick, onKeyDown: this.handleKeydown, class: navGroupTitleClassNames, ref: (el) => (this.groupEl = el), "aria-expanded": `${ariaExpanded}`, "aria-haspopup": `${!inTopNavSideMenu && isTopNav}` }, this.renderGroupTitleText(), isSideNav && expandable && (h("div", { class: {
                "chevron-toggle-icon-wrapper": true,
                "chevron-toggle-icon-closed": expanded,
            }, innerHTML: chevronIcon })))) : isSideNav && !this.isSideNavExpanded ? null : (h("div", { class: navGroupTitleClassNames }, this.renderGroupTitleText())), this.renderNavigationItems()));
    }
    static get is() { return "ic-navigation-group"; }
    static get encapsulation() { return "shadow"; }
    static get delegatesFocus() { return true; }
    static get originalStyleUrls() {
        return {
            "$": ["ic-navigation-group.css"]
        };
    }
    static get styleUrls() {
        return {
            "$": ["ic-navigation-group.css"]
        };
    }
    static get properties() {
        return {
            "expandable": {
                "type": "boolean",
                "mutable": false,
                "complexType": {
                    "original": "boolean",
                    "resolved": "boolean | undefined",
                    "references": {}
                },
                "required": false,
                "optional": true,
                "docs": {
                    "tags": [],
                    "text": "If `true`, the group will be expandable when in an ic-side-navigation component, or, when in an ic-top-navigation component, in the side menu displayed at small screen sizes."
                },
                "getter": false,
                "setter": false,
                "attribute": "expandable",
                "reflect": false,
                "defaultValue": "false"
            },
            "label": {
                "type": "string",
                "mutable": false,
                "complexType": {
                    "original": "string",
                    "resolved": "string",
                    "references": {}
                },
                "required": true,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": "The label to display on the group."
                },
                "getter": false,
                "setter": false,
                "attribute": "label",
                "reflect": false
            },
            "theme": {
                "type": "string",
                "mutable": false,
                "complexType": {
                    "original": "IcThemeMode",
                    "resolved": "\"dark\" | \"inherit\" | \"light\" | undefined",
                    "references": {
                        "IcThemeMode": {
                            "location": "import",
                            "path": "../../utils/types",
                            "id": "src/utils/types.ts::IcThemeMode"
                        }
                    }
                },
                "required": false,
                "optional": true,
                "docs": {
                    "tags": [],
                    "text": "Sets the theme color to the dark or light theme color. \"inherit\" will set the color based on the system settings or ic-theme component."
                },
                "getter": false,
                "setter": false,
                "attribute": "theme",
                "reflect": false,
                "defaultValue": "\"inherit\""
            }
        };
    }
    static get states() {
        return {
            "deviceSize": {},
            "dropdownOpen": {},
            "expanded": {},
            "focusStyle": {},
            "inTopNavSideMenu": {},
            "navigationType": {},
            "parentEl": {},
            "isSideNavExpanded": {}
        };
    }
    static get events() {
        return [{
                "method": "navigationGroupOpened",
                "name": "navigationGroupOpened",
                "bubbles": true,
                "cancelable": true,
                "composed": true,
                "docs": {
                    "tags": [{
                            "name": "internal",
                            "text": "Emitted when a navigation group is opened - when within an ic-top-navigation at large screen sizes."
                        }],
                    "text": ""
                },
                "complexType": {
                    "original": "IcNavigationOpenEventDetail",
                    "resolved": "IcNavigationOpenEventDetail",
                    "references": {
                        "IcNavigationOpenEventDetail": {
                            "location": "import",
                            "path": "./ic-navigation-group.types",
                            "id": "src/components/ic-navigation-group/ic-navigation-group.types.ts::IcNavigationOpenEventDetail"
                        }
                    }
                }
            }, {
                "method": "navigationGroupExpanded",
                "name": "navigationGroupExpanded",
                "bubbles": true,
                "cancelable": true,
                "composed": true,
                "docs": {
                    "tags": [{
                            "name": "internal",
                            "text": "Emitted when a navigation group is expanded - when within an ic-top-navigation at small screen sizes."
                        }],
                    "text": ""
                },
                "complexType": {
                    "original": "IcNavigationExpandEventDetail",
                    "resolved": "IcNavigationExpandEventDetail",
                    "references": {
                        "IcNavigationExpandEventDetail": {
                            "location": "import",
                            "path": "./ic-navigation-group.types",
                            "id": "src/components/ic-navigation-group/ic-navigation-group.types.ts::IcNavigationExpandEventDetail"
                        }
                    }
                }
            }];
    }
    static get methods() {
        return {
            "setFocus": {
                "complexType": {
                    "signature": "() => Promise<void>",
                    "parameters": [],
                    "references": {
                        "Promise": {
                            "location": "global",
                            "id": "global::Promise"
                        }
                    },
                    "return": "Promise<void>"
                },
                "docs": {
                    "text": "Sets focus on the nav item.",
                    "tags": []
                }
            }
        };
    }
    static get elementRef() { return "el"; }
    static get listeners() {
        return [{
                "name": "childBlur",
                "method": "childBlurHandler",
                "target": undefined,
                "capture": false,
                "passive": false
            }, {
                "name": "navigationGroupOpened",
                "method": "handleNavigationGroupOpened",
                "target": "document",
                "capture": false,
                "passive": false
            }, {
                "name": "navItemClicked",
                "method": "navItemClickHandler",
                "target": undefined,
                "capture": false,
                "passive": false
            }, {
                "name": "brandChange",
                "method": "brandChangeHandler",
                "target": "document",
                "capture": false,
                "passive": false
            }];
    }
}
//# sourceMappingURL=ic-navigation-group.js.map
