var __rest = (this && this.__rest) || function (s, e) {
    var t = {};
    for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
        t[p] = s[p];
    if (s != null && typeof Object.getOwnPropertySymbols === "function")
        for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
            if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
                t[p[i]] = s[p[i]];
        }
    return t;
};
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
import React, { useId, useRef } from "react";
import ReactSelect, { components } from "react-select";
import CreatableSelect from "react-select/creatable";
import clsx from "clsx";
// Disable exhaustive-deps: customComponents only needs to update when menuFooter changes
import { Checkbox } from "../checkbox";
import { ADPIcon, iconList } from "../adpIcon";
import { reactSelectCustomStyles } from "./utils";
import { cn } from "@utils";
import { selectVariants, selectLabelVariants, selectHelperTextVariants } from "./selectVariants";
import { ESelectSizes } from "./types";
/**
 * Select component for single or multi selection
 */
export function Select(selectProps) {
    const { id, className, label, size = ESelectSizes.MD, options = [], value, helperText, error = false, disabled = false, creatable = false, maxVisibleValues = 3, maxVisibleValuesMsg, menuFooter, prefixIcon, suffixIcon } = selectProps, restProps = __rest(selectProps, ["id", "className", "label", "size", "options", "value", "helperText", "error", "disabled", "creatable", "maxVisibleValues", "maxVisibleValuesMsg", "menuFooter", "prefixIcon", "suffixIcon"]);
    // Dropdown indicator icon
    const DropdownIndicator = (props) => {
        const { selectProps: { menuIsOpen } } = props;
        return (_jsx(ADPIcon, { size: "xs", icon: menuIsOpen ? iconList.upArrow : iconList.downArrow }));
    };
    // Custom option rendering (handles select-all and checkboxes)
    const OptionComponent = (props) => {
        const optionStyles = props.getStyles("option", props);
        const baseClassName = props.cx({
            option: true,
            "option--is-disabled": props.isDisabled,
            "option--is-focused": props.isFocused,
            "option--is-selected": props.isSelected
        }, props.className);
        const selectedValues = props.getValue();
        const areAllSelected = selectedValues.filter((o) => o.value !== "select-all").length ===
            props.options.length - 1;
        const handleClick = (e) => {
            e.stopPropagation();
            if (props.isDisabled || props.data.isFixed) {
                return;
            }
            if (props.data.value === "select-all") {
                const others = props.options.filter((o) => "value" in o && o.value !== "select-all");
                if (areAllSelected) {
                    props.clearValue();
                }
                else {
                    props.setValue(others, "select-option");
                }
            }
            else {
                props.selectOption(props.data);
            }
        };
        const handleChange = (e) => {
            e.stopPropagation();
            if (props.isDisabled || props.data.isFixed) {
                return;
            }
            if (props.data.value === "select-all") {
                const others = props.options.filter((o) => "value" in o && o.value !== "select-all");
                if (areAllSelected) {
                    const fixed = props.options.filter((o) => "value" in o && o.isFixed);
                    props.setValue(fixed, "select-option");
                }
                else {
                    props.setValue(others, "select-option");
                }
            }
            else {
                props.selectOption(props.data);
            }
        };
        return (_jsxs("div", { style: optionStyles, className: clsx(baseClassName, "select__custom-option", (props.isSelected || props.isFocused) &&
                "dark:!bg-secondary-800", props.isMulti && "select__custom-option--is-multi"), children: [restProps.isMulti && (_jsx(Checkbox, { className: "me-2", onChange: handleChange, checked: areAllSelected || props.isSelected, disabled: props.isDisabled || props.data.isFixed })), _jsx(components.Option, Object.assign({}, props, { className: "!p-0", innerProps: Object.assign(Object.assign({}, props.innerProps), (restProps.isMulti ? { onClick: handleClick } : {})) }))] }));
    };
    // Custom value container to handle prefix/suffix icons and truncation
    const ValueContainer = (_a) => {
        var { children } = _a, props = __rest(_a, ["children"]);
        const values = props.getValue();
        const withData = React.Children.toArray(children).filter((c) => c.props.data);
        const inputChild = React.Children.toArray(children).filter((c) => !c.props.data);
        return (_jsxs(_Fragment, { children: [prefixIcon &&
                    (typeof prefixIcon === "string" ? (_jsx(ADPIcon, { icon: prefixIcon, size: "xs" })) : (prefixIcon)), _jsxs(components.ValueContainer, Object.assign({}, props, { children: [withData, values.length > maxVisibleValues && (_jsxs("div", { className: clsx("select__truncated-multi-value", disabled && "select__truncated-multi-value--is-disabled"), children: ["+", values.length - maxVisibleValues, " ", maxVisibleValuesMsg !== null && maxVisibleValuesMsg !== void 0 ? maxVisibleValuesMsg : "More"] })), inputChild] })), suffixIcon &&
                    (typeof suffixIcon === "string" ? (_jsx(ADPIcon, { icon: suffixIcon, size: "xs" })) : (suffixIcon))] }));
    };
    // Hide extra MultiValue components
    const MultiValue = (props) => {
        if (props.index !== undefined && props.index >= maxVisibleValues) {
            return null;
        }
        return _jsx(components.MultiValue, Object.assign({}, props));
    };
    // Custom input to prevent backspace removing truncated values
    const Input = (props) => {
        const handleKeyDown = (e) => {
            if (e.key === "Backspace") {
                const vals = props.getValue();
                if (vals.length > maxVisibleValues) {
                    e.stopPropagation();
                    e.preventDefault();
                }
            }
        };
        return _jsx(components.Input, Object.assign({}, props, { onKeyDown: handleKeyDown }));
    };
    // Footer for menu if provided
    const Footer = (props) => {
        const { children, innerProps, innerRef } = props;
        return (_jsxs(components.Menu, Object.assign({}, props, { innerProps: innerProps, innerRef: innerRef, children: [children, menuFooter] })));
    };
    const customComponents = Object.assign({ IndicatorSeparator: () => null, DropdownIndicator, Option: OptionComponent, ValueContainer,
        MultiValue,
        Input }, (menuFooter ? { Menu: Footer } : {}));
    const inputId = useRef(useId());
    const SelectType = creatable
        ? CreatableSelect
        : ReactSelect;
    return (_jsxs("div", { className: cn(selectVariants({ size, error, disabled }), className), children: [label !== undefined && (_jsx("label", { htmlFor: id || inputId.current, className: cn(selectLabelVariants()), children: label })), _jsx(SelectType, Object.assign({ classNamePrefix: "select", inputId: id || inputId.current, options: restProps.isMulti && options.length
                    ? [{ value: "select-all", label: "Select All" }].concat(options)
                    : options, value: value, hideSelectedOptions: false, menuPlacement: "auto", components: customComponents, className: clsx("select", `select-${size}`), styles: reactSelectCustomStyles(error, size, restProps.isMulti), isDisabled: disabled, closeMenuOnSelect: !restProps.isMulti }, restProps)), helperText && (_jsx("div", { className: cn(selectHelperTextVariants({ error })), children: helperText }))] }));
}
Select.displayName = "Select";
//# sourceMappingURL=select.js.map