import { h, Fragment } from "@stencil/core";
export class TreeViewItem {
    constructor() {
        this.expanded = false;
        this.initiallyExpanded = false;
        this.disableItem = false;
        this.initiallySelected = false;
        this.hasChildren = false;
        this.isChecked = false;
        this.partialChecked = false;
        this.level = 0;
        this.disableAllItems = false;
        this.expandAllItems = false;
        this.suppressExpandEvents = false;
        this.findChildren = () => Array.from(this.host.children)
            .filter((child) => child instanceof HTMLElement && child.tagName === 'IFX-TREE-VIEW-ITEM');
        this.calculateNodeLevel = () => {
            let level = 0, parent = this.host.parentElement;
            while (parent) {
                if (parent.tagName === 'IFX-TREE-VIEW-ITEM')
                    level++;
                parent = parent.parentElement;
            }
            return level;
        };
        this.handleStateChange = (event) => {
            if (this.disabled)
                return;
            event.stopPropagation();
            this.updateCheckState(event.detail.checked);
        };
        this.handleCheckboxChange = (event) => {
            var _a, _b;
            if (this.disabled)
                return;
            this.updateCheckState((_b = (_a = event.detail) === null || _a === void 0 ? void 0 : _a.checked) !== null && _b !== void 0 ? _b : !this.isChecked);
        };
        this.handleHeaderClick = ({ target }) => {
            if (this.disabled)
                return;
            if (!target.closest('.tree-item__checkbox-container, .tree-item__chevron-container')) {
                if (this.hasChildren) {
                    const newCheckedState = !this.isChecked;
                    this.updateCheckState(newCheckedState);
                    const affectedItems = newCheckedState
                        ? this.expandOrCollapseAllDescendants(true)
                        : this.expandOrCollapseAllDescendants(false);
                    this.ifxTreeViewItemExpandChange.emit({
                        expanded: newCheckedState,
                        affectedItems,
                        component: this
                    });
                }
                else {
                    this.updateCheckState(!this.isChecked);
                }
            }
        };
        this.toggleExpand = () => {
            if (this.disabled || !this.hasChildren)
                return;
            this.expanded = !this.expanded;
        };
        this.handleKeyDown = (event) => {
            var _a, _b, _c, _d, _e, _f;
            const allItems = Array.from(((_a = this.host.closest('ifx-tree-view')) === null || _a === void 0 ? void 0 : _a.querySelectorAll('ifx-tree-view-item')) || []);
            const visibleItems = allItems.filter(item => {
                var _a, _b;
                let parent = (_a = item.parentElement) === null || _a === void 0 ? void 0 : _a.closest('ifx-tree-view-item');
                while (parent) {
                    const parentCmp = parent;
                    if (!(parentCmp.expandAllItems || parentCmp.expanded))
                        return false;
                    parent = (_b = parent.parentElement) === null || _b === void 0 ? void 0 : _b.closest('ifx-tree-view-item');
                }
                return true;
            });
            const currentIndex = visibleItems.findIndex(el => el === this.host);
            const focusLabelIcon = (el) => el === null || el === void 0 ? void 0 : el.focus();
            switch (event.key) {
                case 'ArrowDown': {
                    event.preventDefault();
                    for (let i = currentIndex + 1; i < visibleItems.length; i++) {
                        const next = visibleItems[i];
                        if (!next.disabled) {
                            focusLabelIcon((_b = next.shadowRoot) === null || _b === void 0 ? void 0 : _b.querySelector('.tree-item__label-icon-container'));
                            break;
                        }
                    }
                    break;
                }
                case 'ArrowUp': {
                    event.preventDefault();
                    for (let i = currentIndex - 1; i >= 0; i--) {
                        const prev = visibleItems[i];
                        if (!prev.disabled) {
                            focusLabelIcon((_c = prev.shadowRoot) === null || _c === void 0 ? void 0 : _c.querySelector('.tree-item__label-icon-container'));
                            break;
                        }
                    }
                    break;
                }
                case 'ArrowRight': {
                    event.preventDefault();
                    if (!this.isExpanded && this.hasChildren) {
                        this.expanded = true;
                    }
                    else if (this.isExpanded && this.hasChildren) {
                        const firstChild = this.host.querySelector('ifx-tree-view-item');
                        if (firstChild && !firstChild.disabled) {
                            focusLabelIcon((_d = firstChild.shadowRoot) === null || _d === void 0 ? void 0 : _d.querySelector('.tree-item__label-icon-container'));
                        }
                    }
                    break;
                }
                case 'ArrowLeft': {
                    event.preventDefault();
                    if (this.isExpanded && this.hasChildren) {
                        this.expanded = false;
                    }
                    else {
                        const parent = (_e = this.host.parentElement) === null || _e === void 0 ? void 0 : _e.closest('ifx-tree-view-item');
                        if (parent && !parent.disabled) {
                            focusLabelIcon((_f = parent.shadowRoot) === null || _f === void 0 ? void 0 : _f.querySelector('.tree-item__label-icon-container'));
                        }
                    }
                    break;
                }
                case ' ':
                case 'Enter': {
                    event.preventDefault();
                    if (this.hasChildren) {
                        const newCheckedState = !this.isChecked;
                        this.updateCheckState(newCheckedState);
                        const affectedItems = newCheckedState
                            ? this.expandOrCollapseAllDescendants(true)
                            : this.expandOrCollapseAllDescendants(false);
                        this.ifxTreeViewItemExpandChange.emit({
                            expanded: newCheckedState,
                            affectedItems,
                            component: this
                        });
                    }
                    else {
                        this.updateCheckState(!this.isChecked);
                    }
                    break;
                }
            }
        };
    }
    get disabled() {
        return this.disableAllItems || this.disableItem;
    }
    get isExpanded() {
        return this.expandAllItems || this.expanded;
    }
    componentWillLoad() {
        this.expanded = this.initiallyExpanded;
        this.hasChildren = this.findChildren().length > 0;
        this.level = this.calculateNodeLevel();
        this.host.setAttribute('data-level', this.level.toString());
        this.isChecked = this.initiallySelected;
        this.host.addEventListener('internal-check-state-change', this.handleStateChange);
    }
    componentDidLoad() {
        this.observeParentAttribute('disable-all-items', val => this.disableAllItems = val);
        this.observeParentAttribute('data-expand-all-items', val => this.expandAllItems = val, true);
        if (this.shouldExpandFromParent())
            this.expandAllDescendants();
        this.host['__stencil_instance'] = this;
        if (this.initiallySelected)
            setTimeout(() => this.updateParentState(), 0);
    }
    observeParentAttribute(attr, cb, breakOnAttr = false) {
        let parent = this.host.parentElement;
        while (parent) {
            if (parent.tagName === 'IFX-TREE-VIEW' || (breakOnAttr && parent.hasAttribute(attr))) {
                const observer = new MutationObserver(() => cb(parent.hasAttribute(attr)));
                observer.observe(parent, { attributes: true });
                cb(parent.hasAttribute(attr));
                break;
            }
            parent = parent.parentElement;
        }
    }
    shouldExpandFromParent() {
        let parent = this.host.parentElement;
        while (parent) {
            if (parent.tagName === 'IFX-TREE-VIEW' &&
                (parent.hasAttribute('expand-all-items') || parent.hasAttribute('data-expand-all-items')))
                return true;
            parent = parent.parentElement;
        }
        return false;
    }
    expandAllDescendants() {
        this.expanded = true;
        this.findChildren().forEach(child => {
            var _a, _b;
            child.expanded = true;
            (_b = (_a = child).expandAllDescendants) === null || _b === void 0 ? void 0 : _b.call(_a);
        });
    }
    expandOrCollapseAllDescendants(expand) {
        this.suppressExpandEvents = true;
        const affectedItems = [];
        this.expanded = expand;
        if (this.hasChildren)
            affectedItems.push({ expanded: expand, value: this.value });
        this.findChildren().forEach(child => {
            const childInstance = child['__stencil_instance'];
            if (childInstance && childInstance.hasChildren) {
                childInstance.suppressExpandEvents = true;
                childInstance.expanded = expand;
                affectedItems.push({ expanded: expand, value: childInstance.value });
                if (childInstance.hasChildren) {
                    const childAffected = childInstance.expandOrCollapseAllDescendants(expand);
                    affectedItems.push(...childAffected);
                }
            }
        });
        this.suppressExpandEvents = false;
        return affectedItems;
    }
    async updateCheckState(checked, fromParent = false) {
        if (this.disabled)
            return;
        if (!fromParent && this.hasChildren) {
            const affected = this.collectDescendantStates(checked);
            this.setNodeState({ isChecked: checked, partialChecked: false }, false);
            await this.updateChildrenSilently(checked);
            this.ifxTreeViewItemCheckChange.emit({
                checked,
                indeterminate: false,
                value: this.value,
                affectedChildItems: affected,
                component: this,
            });
            this.updateParentState();
        }
        else if (fromParent) {
            this.setNodeState({ isChecked: checked, partialChecked: false }, false);
        }
        else {
            this.setNodeState({ isChecked: checked, partialChecked: false });
            await this.updateChildrenState(checked);
            this.updateParentState();
        }
    }
    async updateChildrenSilently(checked) {
        for (const child of this.findChildren()) {
            const childInstance = child['__stencil_instance'];
            if (childInstance && !childInstance.disabled) {
                childInstance.setNodeState({ isChecked: checked, partialChecked: false }, false);
                await childInstance.updateChildrenSilently(checked);
            }
        }
    }
    handleExpandedChange(newValue) {
        if (!this.suppressExpandEvents) {
            this.ifxTreeViewItemExpandChange.emit({
                expanded: newValue,
                value: this.value,
                affectedItems: [{ expanded: newValue, value: this.value }],
                component: this
            });
        }
    }
    handleDisableItemChange(newValue) {
        this.ifxTreeViewItemDisableChange.emit({ disabled: newValue, component: this });
    }
    setNodeState(state, emitEvent = true) {
        this.isChecked = state.isChecked;
        this.partialChecked = state.partialChecked;
        if (emitEvent) {
            this.ifxTreeViewItemCheckChange.emit({
                checked: this.isChecked,
                indeterminate: this.partialChecked,
                value: this.value,
                level: this.level,
                disabled: this.disabled,
                component: this
            });
        }
    }
    collectDescendantStates(checked) {
        const descendants = [];
        const collect = (el, skipSelf = false) => {
            let instance = el === this.host ? this : el['__stencil_instance'];
            if (!skipSelf && !(instance === null || instance === void 0 ? void 0 : instance.disabled)) {
                descendants.push({
                    checked,
                    indeterminate: false,
                    value: instance === null || instance === void 0 ? void 0 : instance.value,
                });
            }
            Array.from(el.children)
                .forEach(child => {
                if (child.tagName === 'IFX-TREE-VIEW-ITEM')
                    collect(child, false);
            });
        };
        Array.from(this.host.children)
            .forEach(child => {
            if (child.tagName === 'IFX-TREE-VIEW-ITEM')
                collect(child, false);
        });
        return descendants;
    }
    async updateChildrenState(checked) {
        for (const child of this.findChildren()) {
            const childInstance = child['__stencil_instance'];
            if (childInstance && !childInstance.disabled) {
                await child.componentOnReady();
                child.dispatchEvent(new CustomEvent('internal-check-state-change', {
                    detail: { checked },
                    bubbles: false,
                    composed: true
                }));
            }
        }
    }
    findSiblingNodes(parent) {
        return Array.from(parent.children)
            .filter((child) => child instanceof HTMLElement && child.tagName === 'IFX-TREE-VIEW-ITEM');
    }
    updateParentState() {
        var _a;
        const parent = (_a = this.host.parentElement) === null || _a === void 0 ? void 0 : _a.closest('ifx-tree-view-item');
        if (!parent)
            return;
        setTimeout(() => {
            const parentInstance = parent['__stencil_instance'];
            if (!parentInstance)
                return;
            const siblings = this.findSiblingNodes(parent);
            const { allChecked, someChecked } = this.calculateSiblingStates(siblings);
            parentInstance.setNodeState({
                isChecked: allChecked,
                partialChecked: !allChecked && someChecked
            }, false);
            parentInstance.updateParentState();
        }, 0);
    }
    calculateSiblingStates(siblings) {
        const states = siblings.map(sib => {
            const instance = sib['__stencil_instance'];
            return { checked: instance === null || instance === void 0 ? void 0 : instance.isChecked, partial: instance === null || instance === void 0 ? void 0 : instance.partialChecked };
        });
        const checkedCount = states.filter(state => state.checked).length;
        const partialCount = states.filter(state => state.partial).length;
        return {
            allChecked: states.length > 0 && checkedCount === states.length && partialCount === 0,
            someChecked: checkedCount > 0 || partialCount > 0
        };
    }
    render() {
        return (h("div", { key: '21e156056d745dbea0cd221134c855ff2a57e317', class: {
                'tree-item': true,
                'tree-item--expanded': this.isExpanded,
                'tree-item--has-children': this.hasChildren,
                'tree-item--disabled': this.disabled,
            }, role: "treeitem", "aria-expanded": this.isExpanded ? 'true' : 'false', "data-level": this.level, "aria-disabled": this.disabled ? 'true' : undefined, "aria-label": this.ariaLabel }, h("div", { key: 'aabd6d6afdb0c8973cf37337dcdf882914e0639d', class: "tree-item__content" }, h("div", { key: '6017ec5b5f3bc8d4c3bf0c667ec9f67b45ed1380', class: "tree-item__checkbox-container", onClick: e => e.stopPropagation() }, h("ifx-checkbox", { key: '73e0a46191d3297dd8efc4115b523746cf12d1c4', size: 's', checked: this.partialChecked ? false : this.isChecked, indeterminate: this.partialChecked, onIfxChange: this.handleCheckboxChange, disabled: this.disabled })), h("div", { key: '779fc75cd5028fdeb296279c1a41439c139b3131', class: "tree-item__header", style: { paddingLeft: `${this.level * 24 + 10}px` }, onClick: this.handleHeaderClick, tabIndex: -1, "aria-disabled": this.disabled ? 'true' : undefined }, this.hasChildren && (h("div", { key: 'fb7febcbfda9b3262ce4b24f4cd1eb132e31de0a', class: "tree-item__chevron-container", onClick: this.toggleExpand }, h("ifx-icon", { key: 'a28dfd026545a107aaf88276ed6618f1be792fa7', class: `tree-item__chevron ${this.isExpanded ? 'chevron-down' : 'chevron-right'}`, icon: "chevron-right-16" }), h("div", { key: 'c3dc7648f05ef35975a3f8644801781c2ca3e393', class: "tree-item__line" }))), h("div", { key: '816e7dff619960dfaf781fba46dcd689119dae3c', class: "tree-item__label-icon-container", tabIndex: this.disabled ? -1 : 0, onKeyDown: this.handleKeyDown }, h("div", { key: 'c3f4f7482c9b011fa007697e5a754a56d5f7c1a2', class: "tree-item__icon-container" }, this.hasChildren ? (h(Fragment, null, h("ifx-icon", { class: { 'icon--hidden': this.isExpanded }, icon: "folder-16" }), h("ifx-icon", { class: { 'icon--hidden': !this.isExpanded }, icon: "folder-open-16" }))) : (h("ifx-icon", { icon: "file-16" }))), h("span", { key: '990889102057e40a7b2bc797ebb96f6dfb226a65', class: "tree-item__label" }, h("slot", { key: '566e3eecf153c9d1b565f35166e911ae12e58692' }))))), this.isExpanded && h("div", { key: 'a9b69bfc422177d1a812d961be1027369bdc6079', class: "tree-item__children" }, h("slot", { key: 'd954185323577e142ac8c42816f50ed43d670c6c', name: "children" }))));
    }
    static get is() { return "ifx-tree-view-item"; }
    static get encapsulation() { return "shadow"; }
    static get originalStyleUrls() {
        return {
            "$": ["tree-view-item.scss"]
        };
    }
    static get styleUrls() {
        return {
            "$": ["tree-view-item.css"]
        };
    }
    static get properties() {
        return {
            "expanded": {
                "type": "boolean",
                "attribute": "expanded",
                "mutable": true,
                "complexType": {
                    "original": "boolean",
                    "resolved": "boolean",
                    "references": {}
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": ""
                },
                "getter": false,
                "setter": false,
                "reflect": true,
                "defaultValue": "false"
            },
            "initiallyExpanded": {
                "type": "boolean",
                "attribute": "initially-expanded",
                "mutable": false,
                "complexType": {
                    "original": "boolean",
                    "resolved": "boolean",
                    "references": {}
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": ""
                },
                "getter": false,
                "setter": false,
                "reflect": false,
                "defaultValue": "false"
            },
            "disableItem": {
                "type": "boolean",
                "attribute": "disable-item",
                "mutable": false,
                "complexType": {
                    "original": "boolean",
                    "resolved": "boolean",
                    "references": {}
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": ""
                },
                "getter": false,
                "setter": false,
                "reflect": false,
                "defaultValue": "false"
            },
            "ariaLabel": {
                "type": "string",
                "attribute": "aria-label",
                "mutable": false,
                "complexType": {
                    "original": "string | null",
                    "resolved": "string",
                    "references": {}
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": ""
                },
                "getter": false,
                "setter": false,
                "reflect": false
            },
            "initiallySelected": {
                "type": "boolean",
                "attribute": "initially-selected",
                "mutable": false,
                "complexType": {
                    "original": "boolean",
                    "resolved": "boolean",
                    "references": {}
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": ""
                },
                "getter": false,
                "setter": false,
                "reflect": false,
                "defaultValue": "false"
            },
            "value": {
                "type": "string",
                "attribute": "value",
                "mutable": false,
                "complexType": {
                    "original": "string",
                    "resolved": "string",
                    "references": {}
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": ""
                },
                "getter": false,
                "setter": false,
                "reflect": false
            }
        };
    }
    static get states() {
        return {
            "hasChildren": {},
            "isChecked": {},
            "partialChecked": {},
            "level": {},
            "disableAllItems": {},
            "expandAllItems": {},
            "suppressExpandEvents": {}
        };
    }
    static get events() {
        return [{
                "method": "ifxTreeViewItemExpandChange",
                "name": "ifxTreeViewItemExpandChange",
                "bubbles": true,
                "cancelable": true,
                "composed": true,
                "docs": {
                    "tags": [],
                    "text": ""
                },
                "complexType": {
                    "original": "TreeViewExpandChangeEvent",
                    "resolved": "TreeViewExpandChangeEvent",
                    "references": {
                        "TreeViewExpandChangeEvent": {
                            "location": "local",
                            "path": "/home/runner/work/infineon-design-system-stencil/infineon-design-system-stencil/packages/components/src/components/tree-view/tree-view-item.tsx",
                            "id": "src/components/tree-view/tree-view-item.tsx::TreeViewExpandChangeEvent"
                        }
                    }
                }
            }, {
                "method": "ifxTreeViewItemCheckChange",
                "name": "ifxTreeViewItemCheckChange",
                "bubbles": true,
                "cancelable": true,
                "composed": true,
                "docs": {
                    "tags": [],
                    "text": ""
                },
                "complexType": {
                    "original": "TreeViewCheckChangeEvent",
                    "resolved": "TreeViewCheckChangeEvent",
                    "references": {
                        "TreeViewCheckChangeEvent": {
                            "location": "local",
                            "path": "/home/runner/work/infineon-design-system-stencil/infineon-design-system-stencil/packages/components/src/components/tree-view/tree-view-item.tsx",
                            "id": "src/components/tree-view/tree-view-item.tsx::TreeViewCheckChangeEvent"
                        }
                    }
                }
            }, {
                "method": "ifxTreeViewItemDisableChange",
                "name": "ifxTreeViewItemDisableChange",
                "bubbles": true,
                "cancelable": true,
                "composed": true,
                "docs": {
                    "tags": [],
                    "text": ""
                },
                "complexType": {
                    "original": "TreeViewDisableChangeEvent",
                    "resolved": "TreeViewDisableChangeEvent",
                    "references": {
                        "TreeViewDisableChangeEvent": {
                            "location": "local",
                            "path": "/home/runner/work/infineon-design-system-stencil/infineon-design-system-stencil/packages/components/src/components/tree-view/tree-view-item.tsx",
                            "id": "src/components/tree-view/tree-view-item.tsx::TreeViewDisableChangeEvent"
                        }
                    }
                }
            }];
    }
    static get elementRef() { return "host"; }
    static get watchers() {
        return [{
                "propName": "expanded",
                "methodName": "handleExpandedChange"
            }, {
                "propName": "disableItem",
                "methodName": "handleDisableItemChange"
            }];
    }
}
//# sourceMappingURL=tree-view-item.js.map
