import { h, Host } from "@stencil/core";
import { cls, getId } from "../../utils/helpers";
export class XSelect {
    constructor() {
        /**
         * Element ID for internal reference
         */
        this.inputId = getId('select');
        this.label = undefined;
        this.name = undefined;
        this.placeholder = undefined;
        this.info = undefined;
        this.validate = undefined;
        this.required = undefined;
        this.loading = undefined;
        this.autofocus = undefined;
        this.multiple = undefined;
        this.size = undefined;
        this.autocomplete = 'off';
        this.value = '';
        this.isValid = true;
        this.isFocused = undefined;
        this.isLoading = undefined;
        this.isDisabled = undefined;
        this.isFiltered = undefined;
        this.computedValue = [];
        this.computedText = [];
        this.filteredCount = undefined;
        this.filteredTotal = undefined;
    }
    /**
     * This is called when the component updated the value attribute
     */
    valueChanged(newValue) {
        this.selectOptionByValue(newValue);
    }
    /**
     * Validate the input and get the validation result
    */
    async checkValidity() {
        this.onValidate();
        return this.isValid;
    }
    /**
     * on child option element is triggered the selection
     */
    onOptionSelected(ev) {
        if (this.multiple) {
            this.computedValue.includes(ev.detail.value) ?
                this.computedValue.splice(this.computedValue.indexOf(ev.detail.value), 1) :
                this.computedValue.push(ev.detail.value);
            this.computedText.includes(ev.detail.text) ?
                this.computedText.splice(this.computedText.indexOf(ev.detail.text), 1) :
                this.computedText.push(ev.detail.text);
        }
        else {
            this.computedValue = this.computedValue.includes(ev.detail.value) ? [] : [ev.detail.value];
            this.computedText = this.computedText.includes(ev.detail.text) ? [] : [ev.detail.text];
        }
        this.el.querySelectorAll('x-select-option').forEach(async (el) => {
            el.selected = this.computedValue.includes(await el.getValue());
        });
        const input = this.el.querySelector('.select-input');
        input.value = '';
        input.dispatchEvent(new CustomEvent('input'));
        this.setFormValue();
    }
    /**
     * Set the actual value to internals
     */
    setFormValue() {
        if (this.multiple) {
            if (!this.name.length) {
                return;
            }
            const data = new FormData();
            this.computedValue.forEach((value) => {
                data.append(this.name, value);
            });
            this.internals.setFormValue(data);
        }
        else {
            this.internals.setFormValue(this.computedValue[0]);
        }
        this.el.dispatchEvent(new CustomEvent('input'));
        setTimeout(() => this.onValidate(), 50);
    }
    /**
     * This is called on component did load
     */
    componentDidLoad() {
        this.selectOptionByValue(this.value);
    }
    /**
     * This is called when the 'disabled' attribute of the element or or an ancestor <fieldset> is updated
     *
     * @param disabled
     */
    formDisabledCallback(disabled) {
        this.isDisabled = disabled;
    }
    /**
     * This is called when the parent/owner form is reset
     */
    formResetCallback() {
        this.isValid = true;
        this.internals.setFormValue('');
    }
    /**
     * Set element value by event
     *
     * @param event
     */
    onInput(event) {
        this.value = event.target.value;
        this.internals && this.internals.setFormValue(event.target.value);
        setTimeout(() => this.onValidate(), 50);
    }
    /**
     * This called on input field is unfocused
     */
    onBlurInput() {
        setTimeout(() => {
            this.isFocused = false;
            this.onValidate();
        }, 50);
    }
    /**
     * This called on input field is focused
     */
    onFocusInput() {
        this.isFocused = true;
    }
    /**
     * This called on search input have results
     */
    onFilterInput(ev) {
        this.isFiltered = ev.target.value.length > 0;
        setTimeout(() => {
            this.filteredTotal = this.el.querySelectorAll('x-select-option').length;
            this.filteredCount = this.el.querySelectorAll('x-select-option[matched]').length;
        }, 50);
    }
    /**
     * Validate the field input
     *
     * @returns
     */
    onValidate() {
        if (!this.validate) {
            return;
        }
        const selectors = ["input", "select", "textarea"];
        let input = null;
        selectors.forEach((selector) => {
            if (input === null) {
                input = this.el.querySelector(selector);
            }
        });
        this.isValid = (input === null || input === void 0 ? void 0 : input.validity) ? input.validity.valid : true;
        this.onValidateInputEvent.emit(input);
    }
    /**
     * Return validation of showing the input label
     *
     * @returns
     */
    showLabel() {
        var _a;
        return (this.label && this.placeholder) || (this.label && (((_a = this.value.toString()) !== null && _a !== void 0 ? _a : '').length > 0 || this.isFocused || this.multiple));
    }
    /**
     * Compute the placeholder value
     *
     * @returns
     */
    placeholderValue() {
        if (this.label) {
            if (this.placeholder) {
                return this.placeholder;
            }
            else if (!this.showLabel()) {
                return this.label;
            }
        }
        return this.placeholder;
    }
    /**
     * Focus the select input
     */
    focusSelect() {
        const event = new MouseEvent("mousedown", {
            bubbles: true,
            cancelable: true,
            view: window,
        });
        if (this.isAdvancedSelect()) {
            this.isFocused = !this.isFocused;
            setTimeout(() => {
                this.el.querySelector('.select-input').focus();
            }, 50);
        }
        else {
            this.el.querySelector("select").dispatchEvent(event);
        }
    }
    /**
     * Select the option element by value
     */
    selectOptionByValue(value) {
        const select = this.el.querySelector("select");
        select && select.querySelectorAll("option").forEach((option) => {
            if (option.value === value.toString()) {
                option.selected = true;
            }
        });
        if (this.isAdvancedSelect) {
            const selected = this.el.querySelectorAll('x-select-option');
            this.computedValue = [];
            this.computedText = [];
            selected && selected.forEach(async (el) => {
                if (value == await el.getValue()) {
                    el.selected = true;
                }
                if (el.selected) {
                    this.computedValue.push(await el.getValue());
                    this.computedText.push(await el.getElementOptionText());
                }
            });
        }
    }
    /**
     * Check if the select use not native options
     */
    isAdvancedSelect() {
        return this.el.querySelector("x-select-option") !== null;
    }
    /**
     * Render component
     */
    render() {
        return h(Host, { key: 'acc3da33fbc7c1d4662d8d3d3e7d75569a0fa3c0', "data-for": this.name }, h("div", { key: '48036dbc0920f51338fa504a187c75fccda116b3', class: cls("input-container", {
                "focus": this.isFocused,
                "loading": this.loading || this.isLoading,
                "disabled": this.isDisabled,
                "invalid": !this.isValid,
                "required": this.required,
                "multiple": this.multiple,
                "advanced": this.isAdvancedSelect(),
            }) }, h("div", { key: 'c3649bb1c5a6833bf015f78a746e35c98ff811d2', class: "indicator" }, h("slot", { key: 'fb81001e0c2f8304d2d5929a6d9be27224d54ab3', name: "indicator" })), h("div", { key: 'e6046364d87ca7cc05bdafc1c91b46d118a3115b', class: "separator" }), h("div", { key: 'a35c48ce68e2fa5e6d9b292fd1ec9847a791769e', class: "wrap" }, this.showLabel() && h("label", { key: '4b2de6f0ad249bbbdd2352e0c20ade11df6aa60f', htmlFor: this.inputId }, this.label), this.isAdvancedSelect() ?
            h("div", null, (!this.isFocused || this.multiple) && h("p", { style: { width: this.isFocused ? 'max-content' : '100%' }, onClick: () => this.focusSelect() }, this.computedText.join(', ')), h("input", { style: { display: this.isFocused || this.computedValue.length < 1 ? 'block' : 'none' }, class: "select-input", type: "text", id: this.inputId, required: this.required, disabled: this.isDisabled || this.loading || this.isLoading, autoComplete: this.autocomplete, autoFocus: this.autofocus, placeholder: this.placeholderValue(), onInput: (ev) => this.onFilterInput(ev), onBlur: () => this.onBlurInput(), onFocus: () => this.onFocusInput() }))
            : h("select", { id: this.inputId, required: this.required, disabled: this.isDisabled || this.loading || this.isLoading, autoComplete: this.autocomplete, autoFocus: this.autofocus, multiple: this.multiple, size: this.size, onInput: (e) => this.onInput(e), onBlur: () => this.onBlurInput(), onFocus: () => this.onFocusInput() }, this.placeholder && h("option", { value: "", selected: true, disabled: true }, this.placeholder), h("slot", null))), h("div", { key: 'b3dfb04e4d728d21d3467ffb091e0959dd2e449e', class: "field-float-components" }, this.loading && h("div", { key: '8810fb85e51a0ed2154bda6e7e026d3134da0c81', class: "loading-indicator" }), h("div", { key: 'ac4044c82e2cba9314a6281dc8e754267a9eebf4', class: "buttons" }, !(this.multiple && !this.isAdvancedSelect()) && h("x-button", { key: '573a109db0df01ec988e14dee4d597cc756d5d39', icon: "dropdown", onClick: () => this.focusSelect() }), h("slot", { key: '9d94116fc5828808584fa1c9d8df36510b3813cf', name: "buttons" })), this.info && h("div", { key: 'd9a0def2780cd0b8a4c1fe3ec63040d760231bc2', class: "info" }, h("x-tooltip", { key: '6cf5231bffc8bca03ba6511c31631d982e452771', content: this.info }, h("x-icon", { key: '252e3fe94098e9daf1973b485ab1488a6dcaceb8', name: "info" }))))), this.isAdvancedSelect() && h("div", { key: '5ddc15f003be5ca564833ddd32d0e8413a2f456c', class: cls('select-items', {
                'focused': this.isFocused,
                'filtered': this.isFiltered,
            }) }, h("slot", { key: 'b6fb54e96d2565ac64365ed112e3a5c942e17d1c' }), this.isFiltered && h("div", { key: '7ec1e19b2cf57e8bea72f35cfdf88448bfb91617', class: "select-results" }, h("span", { key: '3d243470caae97c068a2ae23b05078695c2ae367' }, "Mostrando ", h("strong", { key: 'afe3743dcc1b0f89bb754b3c8a122c1f055c3b71' }, this.filteredCount), " recomendacion(es) de ", h("strong", { key: '51241f9613b5e1e5c433305f78fcc64c6ecf1001' }, this.filteredTotal)))));
    }
    static get is() { return "x-select"; }
    static get formAssociated() { return true; }
    static get originalStyleUrls() {
        return {
            "$": ["./style.scss"]
        };
    }
    static get styleUrls() {
        return {
            "$": ["style.css"]
        };
    }
    static get properties() {
        return {
            "label": {
                "type": "string",
                "mutable": false,
                "complexType": {
                    "original": "string",
                    "resolved": "string",
                    "references": {}
                },
                "required": false,
                "optional": true,
                "docs": {
                    "tags": [],
                    "text": "Element input label text"
                },
                "attribute": "label",
                "reflect": false
            },
            "name": {
                "type": "string",
                "mutable": false,
                "complexType": {
                    "original": "string",
                    "resolved": "string",
                    "references": {}
                },
                "required": false,
                "optional": true,
                "docs": {
                    "tags": [],
                    "text": "Element input name for forms keys"
                },
                "attribute": "name",
                "reflect": false
            },
            "placeholder": {
                "type": "string",
                "mutable": false,
                "complexType": {
                    "original": "string",
                    "resolved": "string",
                    "references": {}
                },
                "required": false,
                "optional": true,
                "docs": {
                    "tags": [],
                    "text": "Element input placeholder text"
                },
                "attribute": "placeholder",
                "reflect": false
            },
            "info": {
                "type": "string",
                "mutable": false,
                "complexType": {
                    "original": "string",
                    "resolved": "string",
                    "references": {}
                },
                "required": false,
                "optional": true,
                "docs": {
                    "tags": [],
                    "text": "Element input information block"
                },
                "attribute": "info",
                "reflect": false
            },
            "validate": {
                "type": "boolean",
                "mutable": false,
                "complexType": {
                    "original": "boolean",
                    "resolved": "boolean",
                    "references": {}
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": "Element enable internal validation"
                },
                "attribute": "validate",
                "reflect": false
            },
            "required": {
                "type": "boolean",
                "mutable": false,
                "complexType": {
                    "original": "boolean",
                    "resolved": "boolean",
                    "references": {}
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": "Element input required for forms validations"
                },
                "attribute": "required",
                "reflect": false
            },
            "loading": {
                "type": "boolean",
                "mutable": false,
                "complexType": {
                    "original": "boolean",
                    "resolved": "boolean",
                    "references": {}
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": "Element show loading and block for edit"
                },
                "attribute": "loading",
                "reflect": false
            },
            "autofocus": {
                "type": "boolean",
                "mutable": false,
                "complexType": {
                    "original": "boolean",
                    "resolved": "boolean",
                    "references": {}
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": "Element autofocus on render"
                },
                "attribute": "autofocus",
                "reflect": false
            },
            "multiple": {
                "type": "boolean",
                "mutable": false,
                "complexType": {
                    "original": "boolean",
                    "resolved": "boolean",
                    "references": {}
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": "Element multiple selection"
                },
                "attribute": "multiple",
                "reflect": false
            },
            "size": {
                "type": "number",
                "mutable": false,
                "complexType": {
                    "original": "number",
                    "resolved": "number",
                    "references": {}
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": "Element rows size on multiple selection"
                },
                "attribute": "size",
                "reflect": false
            },
            "autocomplete": {
                "type": "string",
                "mutable": false,
                "complexType": {
                    "original": "InputAutocompleteTypes",
                    "resolved": "\"name\" | \"url\" | \"on\" | \"off\" | \"email\" | \"tel\" | \"honorific-prefix\" | \"given-name\" | \"additional-name\" | \"family-name\" | \"honorific-suffix\" | \"nickname\" | \"username\" | \"new-password\" | \"current-password\" | \"one-time-code\" | \"organization-title\" | \"organization\" | \"street-address\" | \"address-line1\" | \"address-line2\" | \"address-line3\" | \"address-level4\" | \"address-level3\" | \"address-level2\" | \"address-level1\" | \"country\" | \"country-name\" | \"postal-code\" | \"cc-name\" | \"cc-given-name\" | \"cc-additional-name\" | \"cc-family-name\" | \"cc-number\" | \"cc-exp\" | \"cc-exp-month\" | \"cc-exp-year\" | \"cc-csc\" | \"cc-type\" | \"transaction-currency\" | \"transaction-amount\" | \"language\" | \"bday\" | \"bday-day\" | \"bday-month\" | \"bday-year\" | \"sex\" | \"tel-country-code\" | \"tel-national\" | \"tel-area-code\" | \"tel-local\" | \"tel-extension\" | \"impp\" | \"photo\"",
                    "references": {
                        "InputAutocompleteTypes": {
                            "location": "import",
                            "path": "../x-input/component",
                            "id": "src/components/x-input/component.tsx::InputAutocompleteTypes"
                        }
                    }
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": "Element input value of the control can be automatically completed by the browser"
                },
                "attribute": "autocomplete",
                "reflect": false,
                "defaultValue": "'off'"
            },
            "value": {
                "type": "any",
                "mutable": true,
                "complexType": {
                    "original": "string | number | null",
                    "resolved": "number | string",
                    "references": {}
                },
                "required": false,
                "optional": true,
                "docs": {
                    "tags": [],
                    "text": "Element input value"
                },
                "attribute": "value",
                "reflect": false,
                "defaultValue": "''"
            }
        };
    }
    static get states() {
        return {
            "isValid": {},
            "isFocused": {},
            "isLoading": {},
            "isDisabled": {},
            "isFiltered": {},
            "computedValue": {},
            "computedText": {},
            "filteredCount": {},
            "filteredTotal": {}
        };
    }
    static get events() {
        return [{
                "method": "onValidateInputEvent",
                "name": "validated",
                "bubbles": true,
                "cancelable": true,
                "composed": true,
                "docs": {
                    "tags": [],
                    "text": "On validate input event"
                },
                "complexType": {
                    "original": "HTMLObjectElement",
                    "resolved": "HTMLObjectElement",
                    "references": {
                        "HTMLObjectElement": {
                            "location": "global",
                            "id": "global::HTMLObjectElement"
                        }
                    }
                }
            }];
    }
    static get methods() {
        return {
            "checkValidity": {
                "complexType": {
                    "signature": "() => Promise<boolean>",
                    "parameters": [],
                    "references": {
                        "Promise": {
                            "location": "global",
                            "id": "global::Promise"
                        }
                    },
                    "return": "Promise<boolean>"
                },
                "docs": {
                    "text": "Validate the input and get the validation result",
                    "tags": []
                }
            }
        };
    }
    static get elementRef() { return "el"; }
    static get watchers() {
        return [{
                "propName": "value",
                "methodName": "valueChanged"
            }];
    }
    static get listeners() {
        return [{
                "name": "option-selected",
                "method": "onOptionSelected",
                "target": undefined,
                "capture": false,
                "passive": false
            }];
    }
    static get attachInternalsMemberName() { return "internals"; }
}
