import { Host, h, } from "@stencil/core";
import { hasValidationStatus, slotHasContent, onComponentRequiredPropUndefined, removeDisabledFalse, checkResizeObserver, } from "../../utils/helpers";
/**
 * @slot helper-text - Content is set as the helper text for the radio group.
 */
export class RadioGroup {
    constructor() {
        this.resizeObserver = null;
        this.ADDITIONAL_FIELD = "additional-field";
        this.RADIO_HORIZONTAL = "horizontal";
        this.RADIO_VERTICAL = "vertical";
        this.checkedValue = "";
        this.selectedChild = -1;
        /**
         * If `true`, the disabled state will be set.
         */
        this.disabled = false;
        /**
         * If `true`, the label will be hidden and the required label value will be applied as an aria-label.
         */
        this.hideLabel = false;
        /**
         * The orientation of the radio buttons in the radio group. If there are more than two radio buttons in a radio group or either of the radio buttons use the `additional-field` slot, then the orientation will always be vertical.
         */
        this.orientation = "vertical";
        /**
         * If `true`, the radio group will require a value.
         */
        this.required = false;
        /**
         * The size of the radio group component.
         */
        this.size = "medium";
        /**
         * The value of the `aria-live` attribute on the validation message.
         */
        this.validationAriaLive = "polite";
        /**
         * The validation status - e.g. 'error' | 'warning' | 'success'.
         */
        this.validationStatus = "";
        /**
         * The text to display as the validation message.
         */
        this.validationText = "";
        /**
         * Sets the theme color to the dark or light theme color. "inherit" will set the color based on the system settings or ic-theme component.
         */
        this.theme = "inherit";
        this.runResizeObserver = () => {
            this.resizeObserver = new ResizeObserver(() => {
                this.checkOrientation();
            });
            this.resizeObserver.observe(this.el);
        };
        this.handleKeyDown = (event) => {
            const additionalFields = Array.from(this.el.querySelectorAll('ic-text-field[slot="additional-field"]'));
            const activeEl = document.activeElement;
            if (additionalFields.length > 0 &&
                this.radioOptions.map((el) => slotHasContent(el, this.ADDITIONAL_FIELD)) &&
                additionalFields.map((el) => el == activeEl)) {
                return;
            }
            event.stopPropagation();
            switch (event.key) {
                case "ArrowDown":
                case "ArrowRight":
                    this.radioOptions[this.getNextItemToSelect(this.selectedChild, true)].click();
                    event.preventDefault();
                    break;
                case "ArrowUp":
                case "ArrowLeft":
                    this.radioOptions[this.getNextItemToSelect(this.selectedChild, false)].click();
                    event.preventDefault();
            }
        };
        this.getNextItemToSelect = (currentItem, movingDown) => {
            const numRadios = this.radioOptions.length - 1;
            if (currentItem < 1) {
                currentItem = 0;
            }
            let nextItem = movingDown ? currentItem + 1 : currentItem - 1;
            //check if wrap around necessary
            if (nextItem < 0) {
                nextItem = numRadios;
            }
            else if (nextItem > numRadios) {
                nextItem = 0;
            }
            //if next item is disabled then find next
            if (this.radioOptions[nextItem].disabled) {
                nextItem = this.getNextItemToSelect(nextItem, movingDown);
            }
            return nextItem;
        };
        this.addSlotChangeListener = () => {
            var _a;
            (_a = this.radioContainer) === null || _a === void 0 ? void 0 : _a.addEventListener("slotchange", this.setRadioOptions);
        };
        this.setFirstRadioOptionTabIndex = (value) => {
            this.radioOptions[0].setTabIndex(value);
        };
        this.setRadioOptions = () => {
            this.selectedChild = -1;
            this.checkedValue = "";
            this.radioOptions = Array.from(this.el.children).filter((el) => el.tagName === "IC-RADIO-OPTION");
            if (this.radioOptions.length > 0) {
                this.radioOptions.forEach((radioOption, index) => {
                    if (!radioOption.selected) {
                        radioOption.selected = this.checkedValue === radioOption.value;
                    }
                    radioOption.name = this.name;
                    radioOption.groupLabel = this.label;
                    if (radioOption.selected) {
                        this.selectedChild = index;
                        this.checkedValue = radioOption.value;
                    }
                    if (this.disabled) {
                        radioOption.disabled = true;
                    }
                });
                this.setFirstRadioOptionTabIndex(this.selectedChild > 0 ? -1 : 0);
                if (this.initialOrientation === this.RADIO_HORIZONTAL &&
                    this.radioOptions !== undefined &&
                    (this.radioOptions.length > 2 ||
                        (this.radioOptions.length === 2 &&
                            (slotHasContent(this.radioOptions[0], this.ADDITIONAL_FIELD) ||
                                slotHasContent(this.radioOptions[1], this.ADDITIONAL_FIELD))))) {
                    this.currentOrientation = this.RADIO_VERTICAL;
                }
            }
        };
    }
    watchDisabledHandler(newValue) {
        this.radioOptions.forEach((radioOption) => (radioOption.disabled = newValue));
        removeDisabledFalse(this.disabled, this.el);
    }
    orientationChangeHandler() {
        this.initialOrientation = this.orientation;
        this.checkOrientation();
    }
    watchThemeHandler(newValue) {
        this.radioOptions.forEach((radioOption) => (radioOption.theme = newValue));
    }
    disconnectedCallback() {
        var _a, _b;
        (_a = this.resizeObserver) === null || _a === void 0 ? void 0 : _a.disconnect();
        (_b = this.radioContainer) === null || _b === void 0 ? void 0 : _b.removeEventListener("slotchange", this.setRadioOptions);
    }
    componentWillLoad() {
        removeDisabledFalse(this.disabled, this.el);
        this.orientationChangeHandler();
        this.currentOrientation = this.initialOrientation;
    }
    componentDidLoad() {
        this.setRadioOptions();
        checkResizeObserver(this.runResizeObserver);
        this.addSlotChangeListener();
        onComponentRequiredPropUndefined([
            { prop: this.label, propName: "label" },
            { prop: this.name, propName: "name" },
        ], "Radio Group");
        this.watchThemeHandler(this.theme);
    }
    selectHandler({ detail, target }) {
        var _a;
        const selectedOption = target;
        if (selectedOption.parentElement === this.el) {
            this.checkedValue = detail.value;
            this.icChange.emit({
                value: this.checkedValue,
                selectedOption: {
                    radio: selectedOption,
                    textFieldValue: (_a = selectedOption === null || selectedOption === void 0 ? void 0 : selectedOption.querySelector("ic-text-field")) === null || _a === void 0 ? void 0 : _a.value,
                },
            });
            if (this.radioOptions !== undefined) {
                this.radioOptions.forEach((radioOption, index) => {
                    radioOption.selected = selectedOption === radioOption;
                    if (radioOption.selected) {
                        this.selectedChild = index;
                    }
                });
                this.setFirstRadioOptionTabIndex(this.selectedChild > 0 ? -1 : 0);
            }
        }
    }
    changeHandler() {
        var _a;
        const selectedOption = (_a = this.radioOptions) === null || _a === void 0 ? void 0 : _a.findIndex((radioOption) => radioOption.selected);
        if (selectedOption < 0) {
            this.setFirstRadioOptionTabIndex(0);
            this.selectedChild = selectedOption;
        }
    }
    checkOrientation() {
        if (this.initialOrientation === this.RADIO_HORIZONTAL) {
            let totalWidth = 0;
            if (Array.isArray(this.radioOptions) && this.radioOptions.length > 0) {
                this.radioOptions.forEach(({ clientWidth }, i, arr) => {
                    totalWidth += clientWidth;
                    if (i < arr.length - 1)
                        totalWidth += 40;
                });
            }
            else {
                totalWidth = 0;
            }
            if (this.initialOrientation == this.RADIO_HORIZONTAL) {
                if (this.radioOptions !== undefined &&
                    (this.radioOptions.length > 2 ||
                        (this.radioOptions.length === 2 &&
                            (slotHasContent(this.radioOptions[0], this.ADDITIONAL_FIELD) ||
                                slotHasContent(this.radioOptions[1], this.ADDITIONAL_FIELD))))) {
                    this.currentOrientation = this.RADIO_VERTICAL;
                }
                else {
                    if (this.radioContainer) {
                        if (totalWidth >= this.radioContainer.clientWidth) {
                            this.currentOrientation = this.RADIO_VERTICAL;
                        }
                        else if (totalWidth < this.radioContainer.clientWidth) {
                            this.currentOrientation = this.RADIO_HORIZONTAL;
                        }
                    }
                }
            }
        }
    }
    render() {
        const { currentOrientation, disabled, handleKeyDown, helperText, hideLabel, label, required, size, validationAriaLive, validationStatus, validationText, theme, } = this;
        const showValidation = hasValidationStatus(validationStatus, disabled);
        return (h(Host, { key: '0a0b04bb7266c3400e22dd26cdbde025b1bf8a72', onKeyDown: handleKeyDown, class: {
                "ic-radio-group-small": size === "small",
                [`ic-theme-${theme}`]: theme !== "inherit",
            } }, h("fieldset", { key: '8d6fb8bcce4573ce461d09cf9a07783b95e47ab9', role: "radiogroup", id: this.name, "aria-required": `${required}` }, !hideLabel && (h("legend", { key: 'b9a0ff7e81c30100b137e35bdd6c24c71b00b385' }, h("ic-input-label", { key: '078b3ecfe62746c6e91a9f61435c56825b746a5e', class: {
                [`${validationStatus}`]: true,
                ["disabled"]: !!disabled,
            }, label: label, helperText: helperText, required: required, disabled: disabled }, h("slot", { key: '2b071159427e09d3e69945a2460283c32bcf7e97', name: "helper-text", slot: "helper-text" })))), h("div", { key: '7dac840c03547d56606dbc82031cc2b237b0600d', class: {
                "radio-buttons-container": true,
                horizontal: currentOrientation === this.RADIO_HORIZONTAL,
            }, ref: (el) => (this.radioContainer = el) }, h("slot", { key: '324a042d9a015f25d4e831617575830f02f5df08' }))), h("ic-input-validation", { key: '6cab446cc36cb7af4dc48e7ee4e13e72568bb571', class: {
                "show-validation": showValidation,
            }, ariaLiveMode: validationAriaLive, status: showValidation ? validationStatus : "", message: showValidation ? validationText : "" })));
    }
    static get is() { return "ic-radio-group"; }
    static get encapsulation() { return "shadow"; }
    static get originalStyleUrls() {
        return {
            "$": ["ic-radio-group.css"]
        };
    }
    static get styleUrls() {
        return {
            "$": ["ic-radio-group.css"]
        };
    }
    static get properties() {
        return {
            "disabled": {
                "type": "boolean",
                "mutable": false,
                "complexType": {
                    "original": "boolean",
                    "resolved": "boolean | undefined",
                    "references": {}
                },
                "required": false,
                "optional": true,
                "docs": {
                    "tags": [],
                    "text": "If `true`, the disabled state will be set."
                },
                "getter": false,
                "setter": false,
                "attribute": "disabled",
                "reflect": false,
                "defaultValue": "false"
            },
            "helperText": {
                "type": "string",
                "mutable": false,
                "complexType": {
                    "original": "string",
                    "resolved": "string | undefined",
                    "references": {}
                },
                "required": false,
                "optional": true,
                "docs": {
                    "tags": [],
                    "text": "The helper text that will be displayed for additional field guidance."
                },
                "getter": false,
                "setter": false,
                "attribute": "helper-text",
                "reflect": false
            },
            "hideLabel": {
                "type": "boolean",
                "mutable": false,
                "complexType": {
                    "original": "boolean",
                    "resolved": "boolean | undefined",
                    "references": {}
                },
                "required": false,
                "optional": true,
                "docs": {
                    "tags": [],
                    "text": "If `true`, the label will be hidden and the required label value will be applied as an aria-label."
                },
                "getter": false,
                "setter": false,
                "attribute": "hide-label",
                "reflect": false,
                "defaultValue": "false"
            },
            "label": {
                "type": "string",
                "mutable": false,
                "complexType": {
                    "original": "string",
                    "resolved": "string",
                    "references": {}
                },
                "required": true,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": "The label for the radio group to be displayed."
                },
                "getter": false,
                "setter": false,
                "attribute": "label",
                "reflect": false
            },
            "name": {
                "type": "string",
                "mutable": false,
                "complexType": {
                    "original": "string",
                    "resolved": "string",
                    "references": {}
                },
                "required": true,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": "The name for the radio group to differentiate from other groups."
                },
                "getter": false,
                "setter": false,
                "attribute": "name",
                "reflect": false
            },
            "orientation": {
                "type": "string",
                "mutable": false,
                "complexType": {
                    "original": "IcOrientation",
                    "resolved": "\"horizontal\" | \"vertical\" | undefined",
                    "references": {
                        "IcOrientation": {
                            "location": "import",
                            "path": "../../utils/types",
                            "id": "src/utils/types.ts::IcOrientation"
                        }
                    }
                },
                "required": false,
                "optional": true,
                "docs": {
                    "tags": [],
                    "text": "The orientation of the radio buttons in the radio group. If there are more than two radio buttons in a radio group or either of the radio buttons use the `additional-field` slot, then the orientation will always be vertical."
                },
                "getter": false,
                "setter": false,
                "attribute": "orientation",
                "reflect": false,
                "defaultValue": "\"vertical\""
            },
            "required": {
                "type": "boolean",
                "mutable": false,
                "complexType": {
                    "original": "boolean",
                    "resolved": "boolean | undefined",
                    "references": {}
                },
                "required": false,
                "optional": true,
                "docs": {
                    "tags": [],
                    "text": "If `true`, the radio group will require a value."
                },
                "getter": false,
                "setter": false,
                "attribute": "required",
                "reflect": false,
                "defaultValue": "false"
            },
            "size": {
                "type": "string",
                "mutable": false,
                "complexType": {
                    "original": "IcSizesNoLarge",
                    "resolved": "\"medium\" | \"small\" | undefined",
                    "references": {
                        "IcSizesNoLarge": {
                            "location": "import",
                            "path": "../../utils/types",
                            "id": "src/utils/types.ts::IcSizesNoLarge"
                        }
                    }
                },
                "required": false,
                "optional": true,
                "docs": {
                    "tags": [],
                    "text": "The size of the radio group component."
                },
                "getter": false,
                "setter": false,
                "attribute": "size",
                "reflect": false,
                "defaultValue": "\"medium\""
            },
            "validationAriaLive": {
                "type": "string",
                "mutable": false,
                "complexType": {
                    "original": "IcAriaLive",
                    "resolved": "\"assertive\" | \"off\" | \"polite\"",
                    "references": {
                        "IcAriaLive": {
                            "location": "import",
                            "path": "../../utils/types",
                            "id": "src/utils/types.ts::IcAriaLive"
                        }
                    }
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": "The value of the `aria-live` attribute on the validation message."
                },
                "getter": false,
                "setter": false,
                "attribute": "validation-aria-live",
                "reflect": false,
                "defaultValue": "\"polite\""
            },
            "validationStatus": {
                "type": "string",
                "mutable": false,
                "complexType": {
                    "original": "IcInformationStatusOrEmpty",
                    "resolved": "\"\" | \"error\" | \"success\" | \"warning\" | undefined",
                    "references": {
                        "IcInformationStatusOrEmpty": {
                            "location": "import",
                            "path": "../../utils/types",
                            "id": "src/utils/types.ts::IcInformationStatusOrEmpty"
                        }
                    }
                },
                "required": false,
                "optional": true,
                "docs": {
                    "tags": [],
                    "text": "The validation status - e.g. 'error' | 'warning' | 'success'."
                },
                "getter": false,
                "setter": false,
                "attribute": "validation-status",
                "reflect": false,
                "defaultValue": "\"\""
            },
            "validationText": {
                "type": "string",
                "mutable": false,
                "complexType": {
                    "original": "string",
                    "resolved": "string",
                    "references": {}
                },
                "required": false,
                "optional": false,
                "docs": {
                    "tags": [],
                    "text": "The text to display as the validation message."
                },
                "getter": false,
                "setter": false,
                "attribute": "validation-text",
                "reflect": false,
                "defaultValue": "\"\""
            },
            "theme": {
                "type": "string",
                "mutable": false,
                "complexType": {
                    "original": "IcThemeMode",
                    "resolved": "\"dark\" | \"inherit\" | \"light\" | undefined",
                    "references": {
                        "IcThemeMode": {
                            "location": "import",
                            "path": "../../utils/types",
                            "id": "src/utils/types.ts::IcThemeMode"
                        }
                    }
                },
                "required": false,
                "optional": true,
                "docs": {
                    "tags": [],
                    "text": "Sets the theme color to the dark or light theme color. \"inherit\" will set the color based on the system settings or ic-theme component."
                },
                "getter": false,
                "setter": false,
                "attribute": "theme",
                "reflect": false,
                "defaultValue": "\"inherit\""
            }
        };
    }
    static get states() {
        return {
            "checkedValue": {},
            "currentOrientation": {},
            "initialOrientation": {},
            "selectedChild": {}
        };
    }
    static get events() {
        return [{
                "method": "icChange",
                "name": "icChange",
                "bubbles": true,
                "cancelable": true,
                "composed": true,
                "docs": {
                    "tags": [],
                    "text": "Emitted when a user selects a radio."
                },
                "complexType": {
                    "original": "IcChangeEventDetail",
                    "resolved": "IcChangeEventDetail",
                    "references": {
                        "IcChangeEventDetail": {
                            "location": "import",
                            "path": "./ic-radio-group.types",
                            "id": "src/components/ic-radio-group/ic-radio-group.types.ts::IcChangeEventDetail"
                        }
                    }
                }
            }];
    }
    static get elementRef() { return "el"; }
    static get watchers() {
        return [{
                "propName": "disabled",
                "methodName": "watchDisabledHandler"
            }, {
                "propName": "orientation",
                "methodName": "orientationChangeHandler"
            }, {
                "propName": "theme",
                "methodName": "watchThemeHandler"
            }];
    }
    static get listeners() {
        return [{
                "name": "icCheck",
                "method": "selectHandler",
                "target": undefined,
                "capture": false,
                "passive": false
            }, {
                "name": "icSelectedChange",
                "method": "changeHandler",
                "target": undefined,
                "capture": false,
                "passive": false
            }];
    }
}
//# sourceMappingURL=ic-radio-group.js.map
