import { h, Host } from "@stencil/core";
import { inheritAttributes } from "../../../utils/attributes";
import { BEM } from "../../../utils/bem";
import { defaultBalAriaForm } from "../../../utils/form";
import { addEventListener, raf, removeEventListener } from "../../../utils/helpers";
let SegmentItemIds = 0;
export class SegmentItem {
    constructor() {
        this.segmentEl = null;
        this.inheritedAttributes = {};
        this.internalId = SegmentItemIds++;
        this.inputId = `bal-si-${this.internalId}`;
        this.hasSlotContent = false;
        this.isFocusable = false;
        this.isVertical = false;
        this.isLast = false;
        this.isFirst = false;
        this.hasEmptyValue = true;
        this.ariaForm = defaultBalAriaForm;
        /**
         * If `true`, the user cannot interact with the segment button.
         */
        this.disabled = false;
        /**
         * If `true`, the segment is shown in red.
         */
        this.invalid = false;
        /**
         * @internal
         * Sets focus state for key navigation
         */
        this.focused = false;
        /**
         * @internal
         * Sets checked state for key navigation
         */
        this.checked = false;
        /**
         * Label of the segment control
         */
        this.label = '';
        /**
         * The value of the segment button.
         */
        this.value = 'bal-si-' + this.internalId;
        this.updateVertical = (ev) => {
            this.isVertical = ev.detail;
        };
        this.updateState = () => {
            const { segmentEl } = this;
            if (segmentEl) {
                if (segmentEl.value === '' || segmentEl.value === undefined || segmentEl.value === null) {
                    const items = this.allAvailableOptions;
                    if (items.length > 0) {
                        const first = items[0];
                        this.checked = false;
                        this.isFocusable = first === this.el;
                    }
                }
                else {
                    this.checked = segmentEl.value === this.value;
                    this.isFocusable = segmentEl.value === this.value;
                }
                if (segmentEl.disabled) {
                    this.disabled = true;
                }
                if (segmentEl.invalid) {
                    this.invalid = true;
                }
                this.isLast = segmentEl.lastElementChild === this.el;
                this.isFirst = segmentEl.firstElementChild === this.el;
                this.calculateEmptyValue();
            }
        };
        this.onSlottedItemsChange = () => {
            /**
             * When the slotted segment buttons change we need to
             * ensure that the new segment buttons are checked if
             * the value matches the segment button value.
             */
            this.checkSlotContent();
        };
    }
    valueChanged(newValue, oldValue) {
        if (newValue !== oldValue) {
            this.updateState();
        }
    }
    componentWillLoad() {
        this.inheritedAttributes = Object.assign({}, inheritAttributes(this.el, ['aria-label']));
    }
    connectedCallback() {
        const segmentEl = (this.segmentEl = this.el.closest('bal-segment'));
        if (segmentEl && segmentEl.vertical) {
            this.isVertical = segmentEl.vertical;
        }
    }
    componentDidLoad() {
        const segmentEl = (this.segmentEl = this.el.closest('bal-segment'));
        if (segmentEl) {
            addEventListener(segmentEl, 'balSelect', this.updateState);
            addEventListener(segmentEl, 'balVertical', this.updateVertical);
        }
        raf(() => {
            this.checkSlotContent();
            this.updateState();
        });
    }
    disconnectedCallback() {
        const segmentEl = this.segmentEl;
        if (segmentEl) {
            removeEventListener(segmentEl, 'balSelect', this.updateState);
            removeEventListener(segmentEl, 'balVertical', this.updateVertical);
            this.segmentEl = null;
        }
    }
    calculateEmptyValue() {
        if (this.segmentEl) {
            const segments = Array.from(this.segmentEl.querySelectorAll('bal-segment-item'));
            this.hasEmptyValue = !segments.some(item => item.value === this.segmentEl.value);
        }
        else {
            this.hasEmptyValue = false;
        }
    }
    /**
     * @internal
     * Focuses the native <button> element
     * inside of ion-segment-button.
     */
    async setFocus() {
        const { nativeEl } = this;
        if (nativeEl !== undefined) {
            nativeEl.focus();
        }
    }
    /**
     * @internal
     */
    async setAriaForm(ariaForm) {
        this.ariaForm = Object.assign({}, ariaForm);
    }
    get allAvailableOptions() {
        return this.allOptions.filter(item => !item.disabled);
    }
    get allOptions() {
        const { segmentEl } = this;
        if (segmentEl) {
            return Array.from(segmentEl.querySelectorAll('bal-segment-item'));
        }
        return [];
    }
    checkSlotContent() {
        const slot = this.el.querySelector('[part="slot"]');
        const children = slot ? slot.innerHTML.trim() : '';
        this.hasSlotContent = children.length > 0;
    }
    render() {
        const { checked, focused, segmentEl, label, isFocusable, isFirst, hasEmptyValue } = this;
        const block = BEM.block('segment-item');
        const buttonBem = block.element('button');
        const indicatorBem = block.element('indicator');
        const invalid = this.invalid || (segmentEl && segmentEl.invalid);
        const disabled = this.disabled || (segmentEl && segmentEl.disabled);
        const vertical = this.isVertical;
        const hasTabindex = (hasEmptyValue && isFirst) || (isFocusable && !disabled);
        const id = (hasTabindex && this.ariaForm.controlId) || this.inputId;
        let buttonAttributes = {};
        if (hasTabindex) {
            buttonAttributes = {
                'aria-labelledby': this.ariaForm.labelId,
                'aria-describedby': this.ariaForm.messageId,
            };
        }
        return (h(Host, { key: '54ab8ce0ab290fcbc238087789ce0bca3caedddc', class: Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({}, block.class()), block.modifier('vertical').class(vertical)), block.modifier('disabled').class(disabled)), block.modifier('checked').class(checked)), block.modifier('invalid').class(invalid)), block.modifier('last').class(this.isLast && !checked)) }, h("button", Object.assign({ key: 'be4e31f8a5b0da8cc9f70a867e546920127ba4b2', id: id, role: "radio", "aria-checked": checked ? 'true' : 'false' }, buttonAttributes, { class: Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({}, buttonBem.class()), buttonBem.modifier('checked').class(checked)), buttonBem.modifier('invalid').class(invalid)), buttonBem.modifier('disabled').class(disabled)), buttonBem.modifier('focused').class(focused)), buttonBem.modifier('vertical').class(vertical)), type: 'button', tabIndex: hasTabindex ? 0 : -1, part: "native", disabled: disabled, ref: el => (this.nativeEl = el) }, this.inheritedAttributes), h("bal-icon", { key: 'f6d56f256041be2a97822dcc424d887844bacc0e', name: "check", size: "small", class: Object.assign(Object.assign(Object.assign({}, buttonBem.element('icon').class()), buttonBem.element('icon').modifier('animated').class(checked)), buttonBem.element('icon').modifier('vertical').class(vertical)), color: disabled ? 'grey-dark' : invalid ? 'white' : 'primary' }), h("bal-stack", { key: '15df166b0d0d2b6a6b9447506755b9de3581c77d', space: "x-small", layout: 'horizontal' }, h("bal-content", { key: '056ba7bfb5d4f456f03f70e9f86e0269bd44a78b', space: "none" }, h("bal-label", { key: '055ca1dd2f698e5b3758fbc5535a221801d90642', htmlId: `bal-si-${this.internalId}-label` }, label), h("span", { key: '5a4ea620046a856959a811110f9c8ec5dfefa156', part: "slot", class: Object.assign({}, buttonBem.element('slot').modifier('hidden').class(!this.hasSlotContent)) }, ' ', h("slot", { key: 'ceeb6506e86bde765a45497987759479b450c16f', onSlotchange: this.onSlottedItemsChange }))))), h("div", { key: '7384e9bec0b8c8337191b79a54a18cf5cc89a55b', class: Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({}, indicatorBem.class()), indicatorBem.modifier('animated').class()), indicatorBem.modifier('background').class()), indicatorBem.modifier('disabled').class(disabled)), indicatorBem.modifier('invalid').class(invalid)), indicatorBem.modifier('checked').class(checked)), indicatorBem.modifier('vertical').class(vertical)) })));
    }
    static get is() { return "bal-segment-item"; }
    static get originalStyleUrls() {
        return {
            "$": ["bal-segment-item.sass"]
        };
    }
    static get styleUrls() {
        return {
            "$": ["bal-segment-item.css"]
        };
    }
    static get properties() {
        return {
            "disabled": {
                "type": "boolean",
                "mutable": true,
                "complexType": {
                    "original": "boolean",
                    "resolved": "boolean",
                    "references": {}
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": "If `true`, the user cannot interact with the segment button."
                },
                "getter": false,
                "setter": false,
                "reflect": false,
                "attribute": "disabled",
                "defaultValue": "false"
            },
            "invalid": {
                "type": "boolean",
                "mutable": true,
                "complexType": {
                    "original": "boolean",
                    "resolved": "boolean",
                    "references": {}
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": "If `true`, the segment is shown in red."
                },
                "getter": false,
                "setter": false,
                "reflect": false,
                "attribute": "invalid",
                "defaultValue": "false"
            },
            "focused": {
                "type": "boolean",
                "mutable": true,
                "complexType": {
                    "original": "boolean",
                    "resolved": "boolean",
                    "references": {}
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [{
                            "name": "internal",
                            "text": "Sets focus state for key navigation"
                        }],
                    "text": ""
                },
                "getter": false,
                "setter": false,
                "reflect": false,
                "attribute": "focused",
                "defaultValue": "false"
            },
            "checked": {
                "type": "boolean",
                "mutable": true,
                "complexType": {
                    "original": "boolean",
                    "resolved": "boolean",
                    "references": {}
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [{
                            "name": "internal",
                            "text": "Sets checked state for key navigation"
                        }],
                    "text": ""
                },
                "getter": false,
                "setter": false,
                "reflect": false,
                "attribute": "checked",
                "defaultValue": "false"
            },
            "label": {
                "type": "string",
                "mutable": false,
                "complexType": {
                    "original": "string",
                    "resolved": "string",
                    "references": {}
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": "Label of the segment control"
                },
                "getter": false,
                "setter": false,
                "reflect": false,
                "attribute": "label",
                "defaultValue": "''"
            },
            "value": {
                "type": "any",
                "mutable": true,
                "complexType": {
                    "original": "SegmentValue",
                    "resolved": "number | string",
                    "references": {
                        "SegmentValue": {
                            "location": "import",
                            "path": "../bal-segment.types",
                            "id": "src/components/bal-segment/bal-segment.types.ts::SegmentValue"
                        }
                    }
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": "The value of the segment button."
                },
                "getter": false,
                "setter": false,
                "reflect": false,
                "attribute": "value",
                "defaultValue": "'bal-si-' + this.internalId"
            }
        };
    }
    static get states() {
        return {
            "hasSlotContent": {},
            "isFocusable": {},
            "isVertical": {},
            "isLast": {},
            "isFirst": {},
            "hasEmptyValue": {},
            "ariaForm": {}
        };
    }
    static get methods() {
        return {
            "setFocus": {
                "complexType": {
                    "signature": "() => Promise<void>",
                    "parameters": [],
                    "references": {
                        "Promise": {
                            "location": "global",
                            "id": "global::Promise"
                        }
                    },
                    "return": "Promise<void>"
                },
                "docs": {
                    "text": "",
                    "tags": [{
                            "name": "internal",
                            "text": "Focuses the native <button> element\ninside of ion-segment-button."
                        }]
                }
            },
            "setAriaForm": {
                "complexType": {
                    "signature": "(ariaForm: BalAriaForm) => Promise<void>",
                    "parameters": [{
                            "name": "ariaForm",
                            "type": "BalAriaForm",
                            "docs": ""
                        }],
                    "references": {
                        "Promise": {
                            "location": "global",
                            "id": "global::Promise"
                        },
                        "BalAriaForm": {
                            "location": "import",
                            "path": "../../../utils/form",
                            "id": "src/utils/form.ts::BalAriaForm"
                        }
                    },
                    "return": "Promise<void>"
                },
                "docs": {
                    "text": "",
                    "tags": [{
                            "name": "internal",
                            "text": undefined
                        }]
                }
            }
        };
    }
    static get elementRef() { return "el"; }
    static get watchers() {
        return [{
                "propName": "value",
                "methodName": "valueChanged"
            }];
    }
}
