'use strict';

var React = require('react');
var DataListContext = require('./DataListContext-cjs.js');
var DataList_utils = require('./DataList.utils-cjs.js');
var useResponsiveSizing = require('./useResponsiveSizing-cjs.js');
var classnames = require('classnames');
var AnimatedSwitcher = require('./AnimatedSwitcher-cjs.js');
var Text = require('./Text-cjs.js');
var Button = require('./Button-cjs.js');
var Checkbox = require('./Checkbox-cjs.js');
var DataList_module = require('./DataList.module-cjs.js');
var DataListBulkActions = require('./DataListBulkActions-cjs.js');
var useBatchSelect = require('./useBatchSelect-cjs.js');
var useActiveLayout = require('./useActiveLayout-cjs.js');

const DATA_LIST_HEADER_CHECKBOX_TEST_ID = "ATL-DataList-header-checkbox";
const DATA_LIST_HEADER_BATCH_SELECT_TEST_ID = "ATL-DataList-header-batch-select";
function DataListHeaderCheckbox({ children }) {
    const { sm } = useResponsiveSizing.useResponsiveSizing();
    const { data, totalCount } = DataListContext.useDataListContext();
    const { canSelect, canSelectAll, hasAtLeastOneSelected, isSelectAll, selectedCount, selectedIDs, selected, onSelectAll, onSelect, } = useBatchSelect.useBatchSelect();
    // If there's no onSelect, we don't need to render the checkbox.
    // We'll still render the (invisible) checkbox even if only onSelect is provided for alignment.
    if (!canSelect)
        return children;
    const deselectText = sm ? "Deselect All" : "Deselect";
    const selectedLabel = selectedCount ? `${selectedCount} selected` : "";
    return (React.createElement("div", { className: DataList_module.styles.selectable },
        React.createElement("div", { "data-testid": DATA_LIST_HEADER_CHECKBOX_TEST_ID, style: {
                visibility: canSelectAll ? "visible" : "hidden",
            }, className: classnames(DataList_module.styles.selectAllCheckbox) },
            React.createElement(Checkbox.Checkbox, { checked: isAllSelected(), indeterminate: isIndeterminate(), onChange: handleSelectAll, label: React.createElement("div", { className: DataList_module.styles.srOnly }, selectedLabel) })),
        React.createElement(ColumnHeaderContent, { canSelectAll: canSelectAll, hasAtLeastOneSelected: hasAtLeastOneSelected, selectedCount: selectedCount, deselectText: deselectText, onSelect: onSelect }, children)));
    function isIndeterminate() {
        if (isSelectAll)
            return selectedIDs.length > 0;
        return selectedCount > 0 && !isAllSelected();
    }
    function isAllSelected() {
        if (isSelectAll)
            return true;
        // If there's a totalCount, we can use that to accurately determine if the
        // user have "selected all".
        if (totalCount) {
            return totalCount === selectedCount;
        }
        // Otherwise, we'll use the total count of data. This is not as reliable, as
        // it's possible that the would select all loaded data while we're
        // loading more. It's still hard to get to that state as the load more
        // triggers before you see the last item.
        return data.length > 0 && selectedCount >= data.length;
    }
    function handleSelectAll() {
        if (isAllSelected()) {
            return onSelectAll === null || onSelectAll === void 0 ? void 0 : onSelectAll([]);
        }
        onSelectAll === null || onSelectAll === void 0 ? void 0 : onSelectAll({ totalCount: getTotalCount(), unselected: [] });
    }
    function getTotalCount() {
        if (selected && "totalCount" in selected)
            return selected.totalCount;
        if (totalCount)
            return totalCount;
        return 0;
    }
}
function ColumnHeaderContent({ canSelectAll, children, hasAtLeastOneSelected, selectedCount, deselectText, onSelect, }) {
    if (canSelectAll) {
        return (React.createElement(AnimatedSwitcher.AnimatedSwitcher, { switched: hasAtLeastOneSelected, initialChild: children, switchTo: React.createElement("div", { "data-testid": DATA_LIST_HEADER_BATCH_SELECT_TEST_ID, className: DataList_module.styles.batchSelectContainer },
                React.createElement("div", { className: DataList_module.styles.headerBatchSelect },
                    Boolean(selectedCount) && React.createElement(Text.Text, null,
                        selectedCount,
                        " selected"),
                    React.createElement(Button.Button, { label: deselectText, onClick: () => onSelect === null || onSelect === void 0 ? void 0 : onSelect([]), type: "tertiary" })),
                React.createElement(DataListBulkActions.InternalDataListBulkActions, null)) }));
    }
    else {
        return children;
    }
}

function DataListHeader() {
    const breakpoints = useResponsiveSizing.useResponsiveSizing();
    const { headerVisibility = { xs: true, sm: true, md: true, lg: true, xl: true }, headers, layoutBreakpoints, } = DataListContext.useDataListContext();
    const { hasAtLeastOneSelected, canSelect, canSelectAll } = useBatchSelect.useBatchSelect();
    const size = getVisibleSize();
    const { layout } = useActiveLayout.useActiveLayout();
    const visible = headerVisibility[size];
    if (isHeaderHidden(visible, hasAtLeastOneSelected, layout, canSelect, canSelectAll)) {
        return null;
    }
    const headerData = DataList_utils.generateHeaderElements(headers);
    if (!headerData || !layout)
        return null;
    return (React.createElement("div", { className: DataList_module.styles.headerTitles },
        React.createElement(DataListHeaderCheckbox, null, layout(headerData))));
    function getVisibleSize() {
        const visibilityKeys = Object.keys(headerVisibility);
        const headerBreakpoints = DataList_utils.sortBreakpoints(visibilityKeys).reverse();
        const visibleHeaderSize = headerBreakpoints.find(key => breakpoints[key]);
        return visibleHeaderSize || layoutBreakpoints[0];
    }
}
function isHeaderHidden(visible, hasAtLeastOneSelected, layout, canSelect, canSelectAll) {
    // When the horizontal area is too small and the data starts to wrap
    // we want to hide the headers that will no longer align with the content
    // The exception is when we have onSelectAll AND one or more are selected
    // because then we show the "header" in its select-all UI variation state
    const isHiddenForSelect = !visible && canSelect && !canSelectAll;
    const isHiddenForSelectAll = !visible && !hasAtLeastOneSelected;
    return !layout || isHiddenForSelect || isHiddenForSelectAll;
}

exports.DataListHeader = DataListHeader;
