import { Fragment as _Fragment, jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
// (C) 2007-2026 GoodData Corporation
import { useCallback } from "react";
import cx from "classnames";
import { defaultImport } from "default-import";
import DefaultMeasure from "react-measure";
import { ErrorComponent } from "@gooddata/sdk-ui";
import { LoadingMask } from "../../LoadingMask/LoadingMask.js";
import { AsyncList } from "../AsyncList.js";
import { InvertableSelectAllCheckbox } from "./InvertableSelectAllCheckbox.js";
import { InvertableSelectItem } from "./InvertableSelectItem.js";
import { InvertableSelectNoResultsMatch } from "./InvertableSelectNoResultsMatch.js";
import { InvertableSelectSearchBar } from "./InvertableSelectSearchBar.js";
import { InvertableSelectStatusBar } from "./InvertableSelectStatusBar.js";
import { useInvertableSelect } from "./useInvertableSelect.js";
// There are known compatibility issues between CommonJS (CJS) and ECMAScript modules (ESM).
// In ESM, default exports of CJS modules are wrapped in default properties instead of being exposed directly.
// https://github.com/microsoft/TypeScript/issues/52086#issuecomment-1385978414
const Measure = defaultImport(DefaultMeasure);
/**
 * @internal
 */
export function InvertableSelect(props) {
    const { className, width, height, adaptiveWidth, adaptiveHeight, isSingleSelect = false, items, totalItemsCount, itemHeight, getItemTitle, isInverted = true, selectedItems, selectedItemsLimit = Infinity, onEscKeyPress, onSearch, searchString, searchPlaceholder, error, isLoading, nextPageItemPlaceholdersCount, isLoadingNextPage, onLoadNextPage, renderError = defaultError, renderLoading = defaultLoading, renderSearchBar = defaultSearchBar, renderNoData = defaultNoData, renderItem = defaultItem, renderStatusBar = defaultStatusBar, renderActions = defaultActions, } = props;
    const { onSelectAllCheckboxChange, onSelectAllCheckboxToggle, selectOnly, selectItems, deselectItems, selectionState, getIsItemSelected, } = useInvertableSelect(props);
    const itemRenderer = useCallback(({ item }) => {
        return renderItem({
            onSelect: () => {
                selectItems([item]);
            },
            onDeselect: () => {
                deselectItems([item]);
            },
            onSelectOnly: () => selectOnly(item),
            item,
            title: getItemTitle(item),
            isSelected: getIsItemSelected(item),
        });
    }, [renderItem, getIsItemSelected, getItemTitle, selectItems, deselectItems, selectOnly]);
    const searchFilled = (searchString ?? "").length > 0;
    const onEscKeyPressHandler = useCallback((e) => {
        if (searchFilled) {
            e.stopPropagation();
        }
        else {
            onEscKeyPress?.(e);
        }
    }, [searchFilled, onEscKeyPress]);
    return (_jsxs("div", { className: "gd-invertable-select", style: adaptiveWidth ? undefined : { width }, children: [
            _jsx("div", { className: "gd-invertable-select-search-bar", children: renderSearchBar({
                    onSearch: onSearch ?? (() => { }),
                    onEscKeyPress: onEscKeyPressHandler,
                    searchPlaceholder,
                    searchString,
                }) }), isLoading ? (_jsx("div", { className: "gd-invertable-select-loading", children: renderLoading({ height }) })) : error ? (_jsx("div", { className: "gd-invertable-select-error", children: renderError({ height, error }) })) : (_jsxs(_Fragment, { children: [renderActions({
                        isVisible: items.length > 0,
                        checked: selectionState !== "none",
                        onToggle: onSelectAllCheckboxToggle,
                        onChange: onSelectAllCheckboxChange,
                        isFiltered: (searchString?.length ?? 0) > 0,
                        totalItemsCount: totalItemsCount ?? 0,
                        isPartialSelection: selectionState === "partial",
                    }), items.length > 0 && (_jsx(Measure, { client: true, children: ({ measureRef, contentRect }) => {
                            return (_jsx("div", { className: "gd-invertable-select-list", ref: measureRef, children: _jsx(AsyncList, { className: cx(className, {
                                        "is-multiselect": !isSingleSelect,
                                    }), width: adaptiveWidth ? contentRect?.client?.width : width, height: adaptiveHeight
                                        ? contentRect?.client?.height
                                        : Math.min(items.length, 10) * (itemHeight ?? 28), items: items, itemHeight: itemHeight, renderItem: itemRenderer, nextPageItemPlaceholdersCount: nextPageItemPlaceholdersCount, isLoadingNextPage: isLoadingNextPage, onLoadNextPage: onLoadNextPage }) }));
                        } })), items.length === 0 && (_jsx("div", { className: "gd-invertable-select-no-data", children: renderNoData?.({ height }) }))] })), _jsx("div", { className: "gd-invertable-select-status-bar", children: renderStatusBar({ getItemTitle, isInverted, selectedItems, selectedItemsLimit }) })
        ] }));
}
function defaultError({ error }) {
    return _jsx(ErrorComponent, { message: error?.message });
}
function defaultLoading({ height }) {
    return _jsx(LoadingMask, { height: height });
}
function defaultSearchBar({ onSearch, onEscKeyPress, searchPlaceholder, searchString, }) {
    return (_jsx(InvertableSelectSearchBar, { searchPlaceholder: searchPlaceholder, onSearch: onSearch, onEscKeyPress: onEscKeyPress, searchString: searchString, isSmall: true }));
}
function defaultNoData() {
    return _jsx(InvertableSelectNoResultsMatch, {});
}
function defaultItem(props) {
    return (_jsx(InvertableSelectItem, { title: props.title, isSelected: props.isSelected, onClick: props.isSelected ? props.onDeselect : props.onSelect, onOnly: props.onSelectOnly }));
}
function defaultStatusBar({ isInverted, selectedItems, getItemTitle, selectedItemsLimit, }) {
    return (_jsx(InvertableSelectStatusBar, { isInverted: isInverted, selectedItems: selectedItems, getItemTitle: getItemTitle, selectedItemsLimit: selectedItemsLimit ?? 0 }));
}
function defaultActions({ checked, onToggle, onChange, isFiltered, totalItemsCount, isPartialSelection, isVisible, }) {
    return (_jsx(InvertableSelectAllCheckbox, { isVisible: isVisible, checked: checked, onChange: onChange, onToggle: onToggle, isFiltered: isFiltered, totalItemsCount: totalItemsCount, isPartialSelection: isPartialSelection }));
}
