/*!
 * KoliBri - The accessible HTML-Standard
 */
import { h } from "@stencil/core";
import clsx from "../../utils/clsx";
import { createRelatedUniqueId, createUniqueId } from "../../utils/dev.utils";
import { delegateClick, setClick } from "../../utils/element-click";
import { delegateFocus, setFocus } from "../../utils/element-focus";
import { propagateSubmitEventToForm } from "../form/controller";
import { InputRadioController } from "./controller";
import KolFieldControlStateWrapperFc from "../../functional-component-wrappers/FieldControlStateWrapper/FieldControlStateWrapper";
import KolFormFieldStateWrapperFc from "../../functional-component-wrappers/FormFieldStateWrapper/FormFieldStateWrapper";
import KolRadioStateWrapperFc from "../../functional-component-wrappers/RadioStateWrapper/RadioStateWrapper";
export class KolInputRadio {
    async getValue() {
        return this._value;
    }
    async focus(options) {
        const input = this.getFocusableInput();
        return delegateFocus(this.host, () => setFocus(input, options));
    }
    async click() {
        return delegateClick(this.host, async () => setClick(this.inputRef));
    }
    getFocusableInput() {
        const options = this.state._options;
        const isComponentDisabled = Boolean(this.state._disabled);
        const selectedIndex = options.findIndex((option) => option.value === this.state._value && !isComponentDisabled && !option.disabled);
        if (selectedIndex !== -1) {
            const input = this.inputRefs.get(selectedIndex);
            if (input) {
                return input;
            }
        }
        const firstEnabledIndex = options.findIndex((option) => !isComponentDisabled && !option.disabled);
        if (firstEnabledIndex !== -1) {
            return this.inputRefs.get(firstEnabledIndex);
        }
        return undefined;
    }
    getFormFieldProps() {
        return {
            state: this.state,
            component: 'fieldset',
            disabled: Boolean(this.state._disabled),
            class: clsx('kol-form-field--radio'),
            formFieldLabelProps: {
                component: 'legend',
                class: 'kol-form-field__label--legend',
            },
            formFieldInputProps: {
                class: `kol-form-field__input--orientation-${this.state._orientation}`,
            },
            tooltipAlign: this._tooltipAlign,
            alert: this.showAsAlert(),
            hideLabel: false,
        };
    }
    render() {
        return (h(KolFormFieldStateWrapperFc, Object.assign({ key: '8492634fff44e29606e77b7864aebfc9b5fec7f6' }, this.getFormFieldProps()), this.state._options.map((option, index) => this.renderOption(option, index))));
    }
    calculateDisabled(option) {
        return Boolean(this.state._disabled) || Boolean(option.disabled);
    }
    getOptionProps(option, id) {
        return {
            state: this.state,
            id: id,
            hint: option.hint,
            label: option.label,
            required: false,
            fieldControlLabelProps: {
                showBadge: false,
            },
            disabled: this.calculateDisabled(option),
        };
    }
    getInputProps(option, id, index, selected) {
        return {
            state: this.state,
            inputProps: Object.assign(Object.assign({ id: id, ref: (ref) => {
                    this.setInputRefByIndex(index)(ref);
                    if (selected) {
                        this.setInputRef(ref);
                    }
                }, 'aria-label': this.state._hideLabel && typeof option.label === 'string' ? option.label : undefined, type: 'radio', name: this.state._name || this.state._id, value: `-${index}`, checked: selected, disabled: this.calculateDisabled(option) }, this.controller.onFacade), { onChange: this.onChange, onClick: undefined, onInput: this.onInput, onKeyDown: this.onKeyDown.bind(this), onFocus: (event) => {
                    this.controller.onFacade.onFocus(event);
                    this.inputHasFocus = true;
                }, onBlur: (event) => {
                    this.controller.onFacade.onBlur(event);
                    this.inputHasFocus = false;
                } }),
        };
    }
    renderOption(option, index) {
        const customId = createRelatedUniqueId(this.state._id, String(index));
        const selected = this.state._value === option.value;
        return (h(KolFieldControlStateWrapperFc, Object.assign({ key: customId }, this.getOptionProps(option, customId)), h(KolRadioStateWrapperFc, Object.assign({}, this.getInputProps(option, customId, index, selected)))));
    }
    constructor() {
        this.inputRefs = new Map();
        this.setInputRef = (ref) => {
            this.inputRef = ref;
        };
        this.setInputRefByIndex = (index) => (ref) => {
            if (ref) {
                this.inputRefs.set(index, ref);
            }
            else {
                this.inputRefs.delete(index);
            }
        };
        this._disabled = false;
        this._hideMsg = false;
        this._hideLabel = false;
        this._hint = '';
        this._orientation = 'vertical';
        this._required = false;
        this._tooltipAlign = 'top';
        this._touched = false;
        this._value = null;
        this.state = {
            _hideMsg: false,
            _id: createUniqueId('input-radio'),
            _label: '',
            _options: [],
            _orientation: 'vertical',
        };
        this.inputHasFocus = false;
        this.onInput = (event) => {
            if (event.target instanceof HTMLInputElement) {
                const option = this.controller.getOptionByKey(event.target.value);
                if (option !== undefined) {
                    this.controller.onFacade.onInput(event, true, option.value);
                }
            }
        };
        this.onChange = (event) => {
            if (event.target instanceof HTMLInputElement) {
                const option = this.controller.getOptionByKey(event.target.value);
                if (option !== undefined) {
                    this.controller.onFacade.onChange(event, option.value);
                    this._value = option.value;
                }
            }
        };
        this.onKeyDown = (event) => {
            this.controller.onFacade.onKeyDown(event);
            if (event.code === 'Enter' || event.code === 'NumpadEnter') {
                propagateSubmitEventToForm({
                    form: this.host,
                    ref: this.inputRef,
                });
            }
        };
        this.controller = new InputRadioController(this, 'radio', this.host);
    }
    showAsAlert() {
        return Boolean(this.state._touched) && !this.inputHasFocus;
    }
    validateTooltipAlign(value) {
        this.controller.validateTooltipAlign(value);
    }
    validateDisabled(value) {
        this.controller.validateDisabled(value);
    }
    validateHideLabel(value) {
        this.controller.validateHideLabel(value);
    }
    validateHideMsg(value) {
        this.controller.validateHideMsg(value);
    }
    validateHint(value) {
        this.controller.validateHint(value);
    }
    validateLabel(value) {
        this.controller.validateLabel(value);
    }
    validateMsg(value) {
        this.controller.validateMsg(value);
    }
    validateName(value) {
        this.controller.validateName(value);
    }
    validateOn(value) {
        this.controller.validateOn(value);
    }
    validateOptions(value) {
        this.controller.validateOptions(value);
    }
    validateOrientation(value) {
        this.controller.validateOrientation(value);
    }
    validateRequired(value) {
        this.controller.validateRequired(value);
    }
    validateSyncValueBySelector(value) {
        this.controller.validateSyncValueBySelector(value);
    }
    validateTouched(value) {
        this.controller.validateTouched(value);
    }
    validateValue(value) {
        this.controller.validateValue(value);
    }
    validateVariant(value) {
        this.controller.validateVariant(value);
    }
    componentWillLoad() {
        this._touched = this._touched === true;
        this.controller.componentWillLoad();
    }
    static get is() { return "kol-input-radio"; }
    static get encapsulation() { return "shadow"; }
    static get originalStyleUrls() {
        return {
            "default": ["./style.scss"]
        };
    }
    static get styleUrls() {
        return {
            "default": ["style.css"]
        };
    }
    static get properties() {
        return {
            "_disabled": {
                "type": "boolean",
                "mutable": false,
                "complexType": {
                    "original": "boolean",
                    "resolved": "boolean | undefined",
                    "references": {}
                },
                "required": false,
                "optional": true,
                "docs": {
                    "tags": [{
                            "name": "TODO",
                            "text": ": Change type back to `DisabledPropType` after Stencil#4663 has been resolved."
                        }],
                    "text": "Makes the element not focusable and ignore all events."
                },
                "getter": false,
                "setter": false,
                "reflect": false,
                "attribute": "_disabled",
                "defaultValue": "false"
            },
            "_hideMsg": {
                "type": "boolean",
                "mutable": false,
                "complexType": {
                    "original": "boolean",
                    "resolved": "boolean | undefined",
                    "references": {}
                },
                "required": false,
                "optional": true,
                "docs": {
                    "tags": [{
                            "name": "TODO",
                            "text": ": Change type back to `HideMsgPropType` after Stencil#4663 has been resolved."
                        }],
                    "text": "Hides the error message but leaves it in the DOM for the input's aria-describedby."
                },
                "getter": false,
                "setter": false,
                "reflect": false,
                "attribute": "_hide-msg",
                "defaultValue": "false"
            },
            "_hideLabel": {
                "type": "boolean",
                "mutable": false,
                "complexType": {
                    "original": "boolean",
                    "resolved": "boolean | undefined",
                    "references": {}
                },
                "required": false,
                "optional": true,
                "docs": {
                    "tags": [{
                            "name": "TODO",
                            "text": ": Change type back to `HideLabelPropType` after Stencil#4663 has been resolved."
                        }],
                    "text": "Hides the caption by default and displays the caption text with a tooltip when the\ninteractive element is focused or the mouse is over it."
                },
                "getter": false,
                "setter": false,
                "reflect": false,
                "attribute": "_hide-label",
                "defaultValue": "false"
            },
            "_hint": {
                "type": "string",
                "mutable": false,
                "complexType": {
                    "original": "string",
                    "resolved": "string | undefined",
                    "references": {}
                },
                "required": false,
                "optional": true,
                "docs": {
                    "tags": [],
                    "text": "Defines the hint text."
                },
                "getter": false,
                "setter": false,
                "reflect": false,
                "attribute": "_hint",
                "defaultValue": "''"
            },
            "_label": {
                "type": "string",
                "mutable": false,
                "complexType": {
                    "original": "LabelWithExpertSlotPropType",
                    "resolved": "string",
                    "references": {
                        "LabelWithExpertSlotPropType": {
                            "location": "import",
                            "path": "../../schema",
                            "id": "src/schema/index.ts::LabelWithExpertSlotPropType"
                        }
                    }
                },
                "required": true,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": "Defines the visible or semantic label of the component (e.g. aria-label, label, headline, caption, summary, etc.). Set to `false` to enable the expert slot."
                },
                "getter": false,
                "setter": false,
                "reflect": false,
                "attribute": "_label"
            },
            "_msg": {
                "type": "string",
                "mutable": false,
                "complexType": {
                    "original": "Stringified<MsgPropType>",
                    "resolved": "Omit<AlertProps, \"_on\" | \"_label\" | \"_level\" | \"_variant\" | \"_hasCloser\"> & { _description: string; } | string | undefined",
                    "references": {
                        "Stringified": {
                            "location": "import",
                            "path": "../../schema",
                            "id": "src/schema/index.ts::Stringified"
                        },
                        "MsgPropType": {
                            "location": "import",
                            "path": "../../schema",
                            "id": "src/schema/index.ts::MsgPropType"
                        }
                    }
                },
                "required": false,
                "optional": true,
                "docs": {
                    "tags": [],
                    "text": "Defines the properties for a message rendered as Alert component."
                },
                "getter": false,
                "setter": false,
                "reflect": false,
                "attribute": "_msg"
            },
            "_name": {
                "type": "string",
                "mutable": false,
                "complexType": {
                    "original": "NamePropType",
                    "resolved": "string | undefined",
                    "references": {
                        "NamePropType": {
                            "location": "import",
                            "path": "../../schema",
                            "id": "src/schema/index.ts::NamePropType"
                        }
                    }
                },
                "required": false,
                "optional": true,
                "docs": {
                    "tags": [],
                    "text": "Defines the technical name of an input field."
                },
                "getter": false,
                "setter": false,
                "reflect": false,
                "attribute": "_name"
            },
            "_on": {
                "type": "unknown",
                "mutable": false,
                "complexType": {
                    "original": "InputTypeOnDefault",
                    "resolved": "InputTypeOnBlur & InputTypeOnClick & InputTypeOnChange & InputTypeOnFocus & InputTypeOnInput & InputTypeOnKeyDown | undefined",
                    "references": {
                        "InputTypeOnDefault": {
                            "location": "import",
                            "path": "../../schema",
                            "id": "src/schema/index.ts::InputTypeOnDefault"
                        }
                    }
                },
                "required": false,
                "optional": true,
                "docs": {
                    "tags": [],
                    "text": "Gibt die EventCallback-Funktionen f\u00FCr das Input-Event an."
                },
                "getter": false,
                "setter": false
            },
            "_options": {
                "type": "string",
                "mutable": false,
                "complexType": {
                    "original": "RadioOptionsPropType",
                    "resolved": "RadioOption<StencilUnknown>[] | string | undefined",
                    "references": {
                        "RadioOptionsPropType": {
                            "location": "import",
                            "path": "../../schema",
                            "id": "src/schema/index.ts::RadioOptionsPropType"
                        }
                    }
                },
                "required": false,
                "optional": true,
                "docs": {
                    "tags": [],
                    "text": "Options the user can choose from."
                },
                "getter": false,
                "setter": false,
                "reflect": false,
                "attribute": "_options"
            },
            "_orientation": {
                "type": "string",
                "mutable": false,
                "complexType": {
                    "original": "OrientationPropType",
                    "resolved": "\"horizontal\" | \"vertical\" | undefined",
                    "references": {
                        "OrientationPropType": {
                            "location": "import",
                            "path": "../../schema/props/orientation",
                            "id": "src/schema/props/orientation.ts::OrientationPropType"
                        }
                    }
                },
                "required": false,
                "optional": true,
                "docs": {
                    "tags": [],
                    "text": "Defines whether the orientation of the component is horizontal or vertical."
                },
                "getter": false,
                "setter": false,
                "reflect": false,
                "attribute": "_orientation",
                "defaultValue": "'vertical'"
            },
            "_required": {
                "type": "boolean",
                "mutable": false,
                "complexType": {
                    "original": "boolean",
                    "resolved": "boolean | undefined",
                    "references": {}
                },
                "required": false,
                "optional": true,
                "docs": {
                    "tags": [{
                            "name": "TODO",
                            "text": ": Change type back to `RequiredPropType` after Stencil#4663 has been resolved."
                        }],
                    "text": "Makes the input element required."
                },
                "getter": false,
                "setter": false,
                "reflect": false,
                "attribute": "_required",
                "defaultValue": "false"
            },
            "_syncValueBySelector": {
                "type": "string",
                "mutable": false,
                "complexType": {
                    "original": "SyncValueBySelectorPropType",
                    "resolved": "string | undefined",
                    "references": {
                        "SyncValueBySelectorPropType": {
                            "location": "import",
                            "path": "../../schema",
                            "id": "src/schema/index.ts::SyncValueBySelectorPropType"
                        }
                    }
                },
                "required": false,
                "optional": true,
                "docs": {
                    "tags": [{
                            "name": "internal",
                            "text": undefined
                        }],
                    "text": "Selector for synchronizing the value with another input element."
                },
                "getter": false,
                "setter": false,
                "reflect": false,
                "attribute": "_sync-value-by-selector"
            },
            "_tooltipAlign": {
                "type": "string",
                "mutable": false,
                "complexType": {
                    "original": "TooltipAlignPropType",
                    "resolved": "\"bottom\" | \"left\" | \"right\" | \"top\" | undefined",
                    "references": {
                        "TooltipAlignPropType": {
                            "location": "import",
                            "path": "../../schema",
                            "id": "src/schema/index.ts::TooltipAlignPropType"
                        }
                    }
                },
                "required": false,
                "optional": true,
                "docs": {
                    "tags": [],
                    "text": "Defines where to show the Tooltip preferably: top, right, bottom or left."
                },
                "getter": false,
                "setter": false,
                "reflect": false,
                "attribute": "_tooltip-align",
                "defaultValue": "'top'"
            },
            "_touched": {
                "type": "boolean",
                "mutable": true,
                "complexType": {
                    "original": "boolean",
                    "resolved": "boolean | undefined",
                    "references": {}
                },
                "required": false,
                "optional": true,
                "docs": {
                    "tags": [{
                            "name": "TODO",
                            "text": ": Change type back to `TouchedPropType` after Stencil#4663 has been resolved."
                        }],
                    "text": "Shows if the input was touched by a user."
                },
                "getter": false,
                "setter": false,
                "reflect": true,
                "attribute": "_touched",
                "defaultValue": "false"
            },
            "_value": {
                "type": "any",
                "mutable": true,
                "complexType": {
                    "original": "StencilUnknown",
                    "resolved": "boolean | null | number | object | string | undefined",
                    "references": {
                        "StencilUnknown": {
                            "location": "import",
                            "path": "../../schema",
                            "id": "src/schema/index.ts::StencilUnknown"
                        }
                    }
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [{
                            "name": "see",
                            "text": "Known bug: https://github.com/ionic-team/stencil/issues/3902"
                        }],
                    "text": "Defines the value of the element."
                },
                "getter": false,
                "setter": false,
                "reflect": true,
                "attribute": "_value",
                "defaultValue": "null"
            },
            "_variant": {
                "type": "string",
                "mutable": false,
                "complexType": {
                    "original": "VariantClassNamePropType",
                    "resolved": "string | undefined",
                    "references": {
                        "VariantClassNamePropType": {
                            "location": "import",
                            "path": "../../schema",
                            "id": "src/schema/index.ts::VariantClassNamePropType"
                        }
                    }
                },
                "required": false,
                "optional": true,
                "docs": {
                    "tags": [],
                    "text": "Defines which variant should be used for presentation."
                },
                "getter": false,
                "setter": false,
                "reflect": false,
                "attribute": "_variant"
            }
        };
    }
    static get states() {
        return {
            "state": {},
            "inputHasFocus": {}
        };
    }
    static get methods() {
        return {
            "getValue": {
                "complexType": {
                    "signature": "() => Promise<StencilUnknown>",
                    "parameters": [],
                    "references": {
                        "Promise": {
                            "location": "global",
                            "id": "global::Promise"
                        },
                        "StencilUnknown": {
                            "location": "import",
                            "path": "../../schema",
                            "id": "src/schema/index.ts::StencilUnknown"
                        }
                    },
                    "return": "Promise<StencilUnknown>"
                },
                "docs": {
                    "text": "Returns the current value.",
                    "tags": []
                }
            },
            "focus": {
                "complexType": {
                    "signature": "(options?: KolFocusOptions) => Promise<void>",
                    "parameters": [{
                            "name": "options",
                            "type": "KolFocusOptions | undefined",
                            "docs": ""
                        }],
                    "references": {
                        "Promise": {
                            "location": "global",
                            "id": "global::Promise"
                        },
                        "KolFocusOptions": {
                            "location": "import",
                            "path": "../../schema",
                            "id": "src/schema/index.ts::KolFocusOptions"
                        }
                    },
                    "return": "Promise<void>"
                },
                "docs": {
                    "text": "Sets focus on the internal element.",
                    "tags": []
                }
            },
            "click": {
                "complexType": {
                    "signature": "() => Promise<void>",
                    "parameters": [],
                    "references": {
                        "Promise": {
                            "location": "global",
                            "id": "global::Promise"
                        }
                    },
                    "return": "Promise<void>"
                },
                "docs": {
                    "text": "Clicks the primary interactive element inside this component.",
                    "tags": []
                }
            }
        };
    }
    static get elementRef() { return "host"; }
    static get watchers() {
        return [{
                "propName": "_tooltipAlign",
                "methodName": "validateTooltipAlign"
            }, {
                "propName": "_disabled",
                "methodName": "validateDisabled"
            }, {
                "propName": "_hideLabel",
                "methodName": "validateHideLabel"
            }, {
                "propName": "_hideMsg",
                "methodName": "validateHideMsg"
            }, {
                "propName": "_hint",
                "methodName": "validateHint"
            }, {
                "propName": "_label",
                "methodName": "validateLabel"
            }, {
                "propName": "_msg",
                "methodName": "validateMsg"
            }, {
                "propName": "_name",
                "methodName": "validateName"
            }, {
                "propName": "_on",
                "methodName": "validateOn"
            }, {
                "propName": "_options",
                "methodName": "validateOptions"
            }, {
                "propName": "_orientation",
                "methodName": "validateOrientation"
            }, {
                "propName": "_required",
                "methodName": "validateRequired"
            }, {
                "propName": "_syncValueBySelector",
                "methodName": "validateSyncValueBySelector"
            }, {
                "propName": "_touched",
                "methodName": "validateTouched"
            }, {
                "propName": "_value",
                "methodName": "validateValue"
            }, {
                "propName": "_variant",
                "methodName": "validateVariant"
            }];
    }
}
//# sourceMappingURL=shadow.js.map
