import { h } from "@stencil/core";
import { isMultiple } from "../../util/multiple";
import { getIconColor, getIconName } from "../icon/get-icon-props";
export const SelectTemplate = (props) => {
    const value = props.value;
    let hasValue = !!props.value;
    let hasEmptyText = true;
    if (isMultiple(value)) {
        hasValue = value.length > 0;
    }
    else if (hasValue) {
        hasValue = !!value.value;
        hasEmptyText = value.text === '';
    }
    let isValid = !props.invalid;
    if (props.checkValid && props.required && !hasValue) {
        isValid = false;
    }
    const classList = {
        'limel-select': true,
        'mdc-select': true,
        'mdc-select--disabled': props.disabled,
        'limel-select--readonly': props.readonly,
        'limel-select--invalid': !isValid,
        'limel-select--with-helper-text': typeof props.helperText === 'string',
    };
    return [
        h("limel-notched-outline", { class: classList, labelId: "s-label", label: props.label, required: props.required, invalid: !isValid, disabled: props.disabled, readonly: props.readonly, hasValue: hasValue, hasFloatingLabel: floatLabelAbove(props) }, h(SelectValue, Object.assign({}, props, { hasValue: hasValue, isValid: isValid, hasEmptyText: hasEmptyText }))),
        h(HelperText, { text: props.helperText, isValid: !props.invalid }),
        h(SelectDropdown, Object.assign({}, props)),
    ];
};
const floatLabelAbove = (props) => {
    if (props.isOpen) {
        return true;
    }
    const value = props.value;
    if (value) {
        if (isMultiple(value)) {
            return value.length > 0;
        }
        else {
            return value.text !== '';
        }
    }
    return false;
};
const SelectValue = (props) => {
    const anchorClassList = {
        'mdc-select__anchor': true,
        'limel-select-trigger': true,
        'limel-select--focused': props.isOpen,
    };
    return (h("button", { slot: "content", class: anchorClassList, onClick: props.open, onKeyPress: props.onTriggerPress, "aria-haspopup": "listbox", "aria-expanded": props.isOpen, "aria-controls": props.id, "aria-labelledby": "s-label s-selected-text", "aria-required": props.required, disabled: props.disabled || props.readonly }, h("span", { class: "mdc-select__selected-text-container limel-select__selected-option" }, getSelectedIcon(props.value), h("span", { id: "s-selected-text", class: "mdc-select__selected-text limel-select__selected-option__text" }, getSelectedText(props.value))), h(ShowIcon, Object.assign({}, props, { isValid: props.isValid })), h("span", { class: "mdc-select__dropdown-icon" }, h("svg", { class: "mdc-select__dropdown-icon-graphic", viewBox: "7 10 10 5", focusable: "false" }, h("polygon", { stroke: "none", "fill-rule": "evenodd", points: "7 10 12 15 17 10" })))));
};
const ShowIcon = (props) => {
    if (props.isValid) {
        return;
    }
    return (h("limel-icon", { name: "high_importance", size: "medium", class: "invalid-icon" }));
};
const HelperText = (props) => {
    if (typeof props.text !== 'string') {
        return;
    }
    return (h("limel-helper-line", { helperText: props.text.trim(), invalid: !props.isValid }));
};
const SelectDropdown = (props) => {
    if (props.native) {
        return h(NativeDropdown, Object.assign({}, props));
    }
    return h(MenuDropdown, Object.assign({}, props));
};
const MenuDropdown = (props) => {
    const items = createMenuItems(props.options, props.value, props.required);
    return (h("limel-portal", { containerId: props.id, visible: props.isOpen, inheritParentWidth: true, containerStyle: { 'z-index': props.dropdownZIndex }, anchor: props.anchor }, h("limel-menu-surface", { open: props.isOpen, onDismiss: props.close, style: {
            '--menu-surface-width': '100%',
            'max-height': 'inherit',
            display: 'flex',
            'min-width': '100%',
            width: 'fit-content',
        } }, h("limel-list", { items: items, type: props.multiple ? 'checkbox' : 'selectable', onChange: props.onMenuChange }))));
};
const NativeDropdown = (props) => {
    const options = props.options
        .filter((option) => !('separator' in option))
        .map(renderOption(props.value));
    return (h("select", { required: props.required, "aria-disabled": props.disabled, "aria-required": props.required, onChange: props.onNativeChange, onFocus: props.open, onBlur: props.close, class: "limel-select__native-control", disabled: props.disabled, multiple: props.multiple }, options));
};
const renderOption = (selectedOption) => {
    return (option) => {
        const { value, disabled, text } = option;
        return (h("option", { key: value, value: value, selected: isSelected(option, selectedOption), disabled: disabled }, text));
    };
};
function isSelected(option, value) {
    if (!value) {
        return false;
    }
    if (isMultiple(value)) {
        return value.some((o) => option.value === o.value);
    }
    return option.value === value.value;
}
function createMenuItems(options, value, selectIsRequired = false) {
    const menuOptionFilter = getMenuOptionFilter(selectIsRequired);
    return options.filter(menuOptionFilter).map((option) => {
        if ('separator' in option) {
            return {
                text: option.text,
                separator: true,
            };
        }
        const selected = isSelected(option, value);
        const { text, secondaryText, disabled } = option;
        const name = getIconName(option.icon);
        const color = getIconColor(option.icon, option.iconColor);
        if (!name) {
            return {
                text: text,
                secondaryText: secondaryText,
                selected: selected,
                disabled: disabled,
                value: option,
            };
        }
        return {
            text: text,
            secondaryText: secondaryText,
            selected: selected,
            disabled: disabled,
            value: option,
            icon: {
                name: name,
                color: color,
            },
        };
    });
}
function getMenuOptionFilter(selectIsRequired) {
    return (option) => {
        if (!selectIsRequired) {
            // If the select component is NOT required, we keep all options.
            return true;
        }
        if (option.text) {
            // If the select component IS required, we keep only options
            // that are not "empty". We only check the text property, because
            // some systems use an "empty option" that will have a value for
            // the `value` property, to signify "no option selected". Such
            // an option should be treated as "empty".
            return true;
        }
        if ('separator' in option) {
            return true;
        }
    };
}
function getSelectedText(value) {
    const isEmptyValue = !value || (isMultiple(value) && value.length === 0);
    if (isEmptyValue) {
        return '';
    }
    if (isMultiple(value)) {
        return value.map((option, index) => (h("span", { class: "multiple-selected-options", key: option.value }, renderOptionWithIcon(option), index < value.length - 1 && ', ')));
    }
    return value.text;
}
function renderOptionWithIcon(option) {
    const name = getIconName(option.icon);
    if (!name) {
        return option.text;
    }
    const color = getIconColor(option.icon, option.iconColor);
    const style = {};
    if (color) {
        style.color = color;
    }
    return [
        h("limel-icon", { class: "limel-select__selected-option__icon", name: name, size: "small", style: style }),
        option.text,
    ];
}
function getSelectedIcon(value) {
    // For multiple selections, icons are rendered inline with text
    if (isMultiple(value)) {
        return;
    }
    if (!(value === null || value === void 0 ? void 0 : value.icon)) {
        return;
    }
    const name = getIconName(value.icon);
    const color = getIconColor(value.icon, value.iconColor);
    const style = {};
    if (color) {
        style.color = color;
    }
    return (h("limel-icon", { class: "limel-select__selected-option__icon", name: name, size: "medium", style: style }));
}
/**
 *
 * @param options
 */
export function triggerIconColorWarning(options) {
    for (const option of options) {
        if (option.iconColor) {
            console.warn("The `iconColor` prop is deprecated now! Use the new `Icon` interface and instead of `iconColor: 'color-name'` write `icon {name: 'icon-name', color: 'color-name'}`.");
        }
    }
}
