/*!
 * Built with Stencil
 * By PostNord.
 */
import { h, Host, forceUpdate, } from "@stencil/core";
import { uuidv4 } from "../../../../globals/helpers";
import { chevron_down, arrow_left, arrow_right } from "pn-design-assets/pn-assets/icons.js";
/**
 * @deprecated This component will be removed in v8. Please use the `pn-tablist` instead.
 * @see {@link https://portal.postnord.com/web-components/?path=/docs/components-navigation-tablist--docs Use `pn-tablist` instead.}
 *
 * @slot dropdown-item - Place your `pn-page-nav-dropdown-item` components here.
 */
export class PnPageNav {
    mo;
    navContainer;
    navWrapper;
    navItems = [];
    dropdownButton;
    dropdownEl;
    dropdownItems;
    dropdownEls;
    eventHandler = this.keyboardEvents.bind(this);
    globalEventHandler = this.globalEvents.bind(this);
    activeBg;
    hoverBg;
    scrollRegistered = false;
    hostElement;
    currentSelection;
    showScrollArrows = false;
    showLeftArrow = false;
    showRightArrow = false;
    dropdownOpen = false;
    dropdownLinks = [];
    dropdownActive = false;
    /** Currently active menu item value */
    value;
    /** Pass a string which will be the text on the dropdown button. */
    dropdown = false;
    /** Set a unique HTML ID. */
    navid = `pn-page-nav-${uuidv4()}`;
    /** Emits the value of the selected item. */
    navchange;
    changeHandler({ target }) {
        this.currentSelection = target.closest('pn-page-nav-item');
        if (target.value)
            this.value = target.value;
        if (this.dropdownOpen)
            this.dropdownOpen = false;
    }
    handleResize() {
        this.rerender();
    }
    valueHandler() {
        if (!this.value)
            this.currentSelection = null;
        this.calcHighlight(this.currentSelection, this.activeBg);
        this.navchange.emit(this.value);
        if (!this.dropdownActive)
            return;
        this.isDropdownItemActive();
    }
    dropdownHandler() {
        if (this.dropdownOpen) {
            requestAnimationFrame(() => {
                this.addGlobalEventListeners();
            });
            return;
        }
        this.removeGlobalEventListeners();
    }
    /* ---------------------------------------LIFECYCLE--------------------------------------- */
    componentWillLoad() {
        if (!this.dropdown)
            return;
        this.dropdownEls = Array.from(this.hostElement.querySelectorAll('pn-page-nav-dropdown-item'));
        if (this.dropdownEls.length) {
            this.dropdownActive = true;
            this.initiateDropdown();
        }
    }
    componentDidLoad() {
        if (this.mo)
            this.mo.disconnect();
        this.mo = new MutationObserver(() => {
            forceUpdate(this.hostElement);
            this.setActiveNavItem();
            this.rerender();
        });
        this.mo.observe(this.hostElement, { childList: true, subtree: true });
        this.navWrapper = this.hostElement.querySelector('.pn-page-nav');
        this.navContainer = this.hostElement.querySelector('.pn-page-nav-items');
        this.activeBg = this.hostElement.querySelector('.pn-pn-active');
        this.hoverBg = this.hostElement.querySelector('.pn-pn-hover');
        this.hostElement.addEventListener('mouseover', ({ target }) => this.calcHighlight(target, this.hoverBg));
        this.setActiveNavItem();
        this.rerender();
    }
    /* ---------------------------------------/LIFECYCLE--------------------------------------- */
    setActiveNavItem() {
        this.navItems = Array.from(this.hostElement.querySelectorAll('pn-page-nav-item'));
        this.navItems.forEach(navItemEl => {
            if (this.value === navItemEl.value) {
                /** @ts-ignore This component will be removed soon, no need to deal with this. */
                this.currentSelection = navItemEl;
            }
            else {
                navItemEl.removeAttribute('selected');
            }
            navItemEl
                .querySelector('a')
                .addEventListener('focus', ({ target }) => this.calcHighlight(target, this.hoverBg));
        });
        /* -----------------dropdown------------------ */
        if (!this.dropdownActive)
            return;
        this.dropdownItems = Array.from(this.hostElement.querySelectorAll('.pn-page-nav-dropdown-item'));
        //Check active state on each item
        this.isDropdownItemActive();
        //Store all values to check if dropdown button should be active
        this.dropdownLinks = this.dropdownItems.map((el, i) => {
            el.setAttribute('data-index', `${i}`);
            return el.closest('pn-page-nav-dropdown-item').value;
        });
        /* -----------------/dropdown------------------ */
    }
    rerender() {
        requestAnimationFrame(() => {
            this.calcHighlight(this.currentSelection, this.activeBg);
            this.scrollArrowRender();
        });
    }
    /*---------------------------------------HIGHLIGHT LOGIC-------------------------------------------*/
    calcHighlight(el, bgEl) {
        if (!el?.closest('pn-page-nav-item')) {
            bgEl?.classList.add('hidden');
            return;
        }
        if (bgEl)
            bgEl.classList.remove('hidden');
        const elRect = el.closest('pn-page-nav-item').getBoundingClientRect();
        const { left: hostLeft } = this.navContainer.getBoundingClientRect();
        const { left: navLeft, height: navHeight, width: navWidth } = elRect;
        const offset = navLeft - hostLeft + this.navContainer.scrollLeft;
        bgEl.style.setProperty('transform', `translate(${offset}px, -50%`);
        bgEl.style.setProperty('width', `${navWidth}px`);
        bgEl.style.setProperty('height', `${navHeight}px`);
    }
    /*---------------------------------------/HIGHLIGHT LOGIC-------------------------------------------*/
    /*---------------------------------------SCROLL ARROW LOGIC-------------------------------------------*/
    scrollArrowRender() {
        if (!this.navWrapper)
            return;
        if (this.navWrapper.scrollWidth > this.navWrapper.clientWidth) {
            this.showScrollArrows = true;
            if (!this.scrollRegistered) {
                this.navWrapper.addEventListener('scroll', this.scrollArrowRender.bind(this));
                this.scrollRegistered = true;
            }
            const amountScrolled = Math.round(this.navWrapper.scrollWidth - this.navWrapper.scrollLeft);
            const distanceToEnd = amountScrolled - this.navWrapper.clientWidth;
            const distanceToStart = this.navWrapper.scrollLeft;
            this.showLeftArrow = distanceToStart > 0;
            this.showRightArrow = distanceToEnd > 0;
            return;
        }
        this.showLeftArrow = false;
        this.showRightArrow = false;
        this.showScrollArrows = false;
    }
    scroll(val) {
        let amount = this.navWrapper.scrollLeft + val;
        this.navWrapper.scroll({
            left: amount,
            behavior: 'smooth',
        });
    }
    scrollArrowClasses() {
        let classNames = 'pn-pn-arrows ';
        if (this.showLeftArrow)
            classNames += 'pn-pn-left-visible ';
        if (this.showRightArrow)
            classNames += 'pn-pn-right-visible ';
        return classNames;
    }
    /*---------------------------------------/SCROLL ARROW LOGIC-------------------------------------------*/
    /* ---------------------------------------DROPDOWN LOGIC--------------------------------------- */
    initiateDropdown() {
        requestAnimationFrame(() => {
            this.dropdownButton = this.hostElement.querySelector('.pn-page-nav-dropdown-button');
            this.dropdownEl = this.hostElement.querySelector('.pn-page-nav-dropdown');
            this.addDropdownEventListeners();
        });
    }
    toggleDropdown() {
        this.dropdownOpen = !this.dropdownOpen;
    }
    isDropdownItemActive() {
        this.dropdownEls.forEach(el => {
            if (el.value && this.value === el.value) {
                el.setAttribute('active', 'true');
                return;
            }
            el.removeAttribute('active');
        });
    }
    /* -----------------events------------------ */
    /* -----------------temporary events------------------ */
    addDropdownEventListeners() {
        this.hostElement.addEventListener('keydown', this.eventHandler);
        this.hostElement.addEventListener('click', this.eventHandler);
    }
    addGlobalEventListeners() {
        const root = this.hostElement.getRootNode();
        root.addEventListener('focusin', this.globalEventHandler);
        root.addEventListener('keydown', this.globalEventHandler);
        root.addEventListener('click', this.globalEventHandler);
    }
    removeGlobalEventListeners() {
        const root = this.hostElement.getRootNode();
        root.removeEventListener('focusin', this.globalEventHandler);
        root.removeEventListener('keydown', this.globalEventHandler);
        root.removeEventListener('click', this.globalEventHandler);
    }
    /* -----------------/temporary events------------------ */
    /* -----------------Open dropdown with keyboard------------------ */
    keyboardEvents(e) {
        const target = e.composedPath()[0];
        // As long as the dropdown is closed, we only want it to react to keyboard input
        // is the user has focus on the button
        if (e.type === 'keydown') {
            if (!this.dropdownOpen && target === this.dropdownButton && ['ArrowUp', 'ArrowDown'].includes(e.code)) {
                this.dropdownOpen = true;
                requestAnimationFrame(() => {
                    this.focusNextDropdownItem();
                });
            }
        }
    }
    /* -----------------/Open dropdown with keyboard------------------ */
    globalEvents(e) {
        const target = e.composedPath()[0];
        if (e.type === 'keydown' && e.code === 'Escape') {
            this.dropdownOpen = false;
            this.dropdownButton.focus();
        }
        if (e.code === 'ArrowDown')
            this.focusNextDropdownItem();
        if (e.code === 'ArrowUp')
            this.focusPrevDropdownItem();
        if ((e.type === 'click' || e.type === 'focusin') && !this.dropdownEl.contains(target)) {
            this.dropdownOpen = false;
        }
    }
    /* -----------------/events------------------ */
    /* -----------------focusing------------------ */
    focusNextDropdownItem() {
        const { activeElement } = this.hostElement.getRootNode();
        if (!activeElement.classList.contains('pn-page-nav-dropdown-item')) {
            this.dropdownItems[0].focus();
            return;
        }
        // focus next item
        const index = parseInt(activeElement.getAttribute('data-index'));
        if (index < this.dropdownItems.length - 1) {
            this.dropdownItems[index + 1].focus();
        }
    }
    focusPrevDropdownItem() {
        const { activeElement } = this.hostElement.getRootNode();
        if (!activeElement.classList.contains('dropdown-item')) {
            this.dropdownItems[this.dropdownItems.length - 1].focus();
        }
        // focus previous item
        const index = parseInt(activeElement.getAttribute('data-index'));
        if (index > 0) {
            this.dropdownItems[index - 1].focus();
            return;
        }
        this.dropdownButton.focus();
    }
    /* -----------------/focusing------------------ */
    dropdownButtonClasses() {
        let classList = 'pn-page-nav-dropdown-button ';
        if (this.dropdownLinks.includes(this.value))
            classList += 'pn-page-nav-dropdown-active ';
        return classList;
    }
    dropdownClasses() {
        let classList = 'pn-page-nav-dropdown ';
        if (this.dropdownOpen)
            classList += 'pn-page-nav-dropdown-open ';
        return classList;
    }
    /* ---------------------------------------/DROPDOWN LOGIC--------------------------------------- */
    render() {
        return (h(Host, { key: 'f76a115ccea11e238d2aee5288b06675abc80b8a' }, h("div", { key: '453102a432daf9b567be4f5dc415bab34b48bc84', class: "pn-page-nav-wrapper" }, h("nav", { key: '9207ade4b4d6cea4c22622c91988eef2b3c812bc', class: "pn-page-nav" }, this.dropdownActive && (h("button", { key: '3365178312cfe2b9d48fccbc794d2a8a857ed6f0', type: "button", class: this.dropdownButtonClasses(), onClick: () => this.toggleDropdown(), "aria-controls": "page-nav-dropdown", "aria-expanded": `${this.dropdownOpen}` }, this.dropdown, h("pn-icon", { key: '460172b12b334e96920d185dcbc868acafc0cdcc', icon: chevron_down, color: "white", small: true }), h("div", { key: 'f16219e3070e00ebd1ab143b8803a94c44e242bc', class: "pn-page-nav-divider" }))), h("ul", { key: '560ef88c95269f29b1f76ee65e3a2541fc2482ce', class: "pn-page-nav-items" }, h("slot", { key: '7b1cfc89976421963cc19f958f21e29bfc796621' }), h("li", { key: '7df00d0a42fc3f48f82afdb0bbbf943229604293', class: "pn-pn-bg pn-pn-active", role: "presentation" }), h("li", { key: '68fd6cc6f9dfcb834c62105f81ff2e21b332be94', class: "pn-pn-bg pn-pn-hover", role: "presentation" }))), this.showScrollArrows && (h("div", { key: 'ba26546a6fa3f750a5314dd80f80e1487b4962ec', class: this.scrollArrowClasses() }, h("button", { key: '57b43598cb3288b068c3583c822be35418b28e91', class: "pn-pn-arrow-left", onClick: () => this.scroll(-120), tabindex: "-1" }, h("pn-icon", { key: 'b812b5b471ba0982be6cb3bcacc84bb2f52fa0e3', icon: arrow_left, color: "white" })), h("button", { key: '70d5bffed71999aaf154f88590378496d79e7f55', class: "pn-pn-arrow-right", onClick: () => this.scroll(120), tabindex: "-1" }, h("pn-icon", { key: 'a2d4319bab3a80b092321873ff66e4b421f14743', icon: arrow_right, color: "blue700" }))))), this.dropdownActive && (h("ul", { key: '1e2a73e7b4d523f3feba0dc18ccc14871b551862', id: this.navid, class: this.dropdownClasses() }, h("slot", { key: '20f647483c10a84de4bf2f40126b83b65b61b99f', name: "dropdown-item" })))));
    }
    static get is() { return "pn-page-nav"; }
    static get originalStyleUrls() {
        return {
            "$": ["pn-page-nav.scss"]
        };
    }
    static get styleUrls() {
        return {
            "$": ["pn-page-nav.css"]
        };
    }
    static get properties() {
        return {
            "value": {
                "type": "string",
                "mutable": true,
                "complexType": {
                    "original": "string",
                    "resolved": "string",
                    "references": {}
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": "Currently active menu item value"
                },
                "getter": false,
                "setter": false,
                "reflect": false,
                "attribute": "value"
            },
            "dropdown": {
                "type": "any",
                "mutable": false,
                "complexType": {
                    "original": "string | boolean",
                    "resolved": "boolean | string",
                    "references": {}
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": "Pass a string which will be the text on the dropdown button."
                },
                "getter": false,
                "setter": false,
                "reflect": false,
                "attribute": "dropdown",
                "defaultValue": "false"
            },
            "navid": {
                "type": "string",
                "mutable": false,
                "complexType": {
                    "original": "string",
                    "resolved": "string",
                    "references": {}
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": "Set a unique HTML ID."
                },
                "getter": false,
                "setter": false,
                "reflect": false,
                "attribute": "navid",
                "defaultValue": "`pn-page-nav-${uuidv4()}`"
            }
        };
    }
    static get states() {
        return {
            "currentSelection": {},
            "showScrollArrows": {},
            "showLeftArrow": {},
            "showRightArrow": {},
            "dropdownOpen": {},
            "dropdownLinks": {},
            "dropdownActive": {}
        };
    }
    static get events() {
        return [{
                "method": "navchange",
                "name": "navchange",
                "bubbles": true,
                "cancelable": true,
                "composed": true,
                "docs": {
                    "tags": [],
                    "text": "Emits the value of the selected item."
                },
                "complexType": {
                    "original": "string",
                    "resolved": "string",
                    "references": {}
                }
            }];
    }
    static get elementRef() { return "hostElement"; }
    static get watchers() {
        return [{
                "propName": "value",
                "methodName": "valueHandler"
            }, {
                "propName": "dropdownOpen",
                "methodName": "dropdownHandler"
            }];
    }
    static get listeners() {
        return [{
                "name": "itemselection",
                "method": "changeHandler",
                "target": undefined,
                "capture": false,
                "passive": false
            }, {
                "name": "resize",
                "method": "handleResize",
                "target": "window",
                "capture": false,
                "passive": true
            }];
    }
}
