"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.ColumnValuesSelect = void 0;
const tslib_1 = require("tslib");
const React = tslib_1.__importStar(require("react"));
const StringExtensions_1 = require("../../../Utilities/Extensions/StringExtensions");
const date_fns_1 = require("date-fns");
const DateHelper_1 = require("../../../Utilities/Helpers/DateHelper");
const join_1 = tslib_1.__importDefault(require("../../../components/utils/join"));
const Select_1 = require("../../../components/Select");
const TreeDropdown_1 = require("../../../components/Tree/TreeDropdown");
const GeneralConstants_1 = require("../../../Utilities/Constants/GeneralConstants");
const AdaptableContext_1 = require("../../AdaptableContext");
const react_1 = require("react");
const baseClassName = 'ab-ListBoxFilterForm';
// used for displaying the date values in the input
function toDateDisplayValue(values) {
    values = values.map((v) => {
        if (!Array.isArray(v)) {
            return v;
        }
        return v[v.length - 1];
    });
    return (0, TreeDropdown_1.toDisplayValueDefault)(values);
}
const dateOnChangeParser = (value) => {
    /**
     * the value looks like this:
     * [
     *  ["2021","2021-01","2021-01-01"],
     *  ["2024","2024-02","2024-02-15T12:34:00"],
     * ]
     */
    // so first need to transfor the above to this:
    /**
     * [
     *  [2023, 12, 1, 1640668800000],
     *  [2023, 12, 3, 1738377600000]
     * ]
     */
    return value.map((v) => {
        return v[v.length - 1];
    });
};
const EMPTY_ARRAY = [];
const ColumnValuesSelect = (props) => {
    const column = props.column;
    const { api } = (0, AdaptableContext_1.useAdaptable)();
    let selectedColumnValues = props.value || EMPTY_ARRAY;
    const optionsFromProps = Array.isArray(props.options) ? props.options : EMPTY_ARRAY;
    const value = [];
    if (column.dataType === 'date') {
        // we might have a use-case where users might want to get rid of a tree level
        // because it may contain only one child. currently,
        // the value is an array of strings that have this form (ISOish)
        // ["2021-01-01", "2021-10-02", "2021-01-03T12:00:00"]
        // but we want the full path to each value
        // but we can't compute that by simply splitting the strings by '-' or 'T',
        // as if we do that, then we won't support removing a tree level
        // so we have to compute the paths based on the options
        const valueToPath = (0, react_1.useMemo)(() => {
            const valueToPath = new Map();
            const withOption = (option, parentPath = []) => {
                const optionPath = [...parentPath, option.value];
                valueToPath.set(option.value, optionPath);
                if (Array.isArray(option.children)) {
                    option.children.forEach((child) => withOption(child, optionPath));
                }
            };
            optionsFromProps.forEach((option) => withOption(option, []));
            return valueToPath;
        }, [optionsFromProps]);
        selectedColumnValues = selectedColumnValues
            .map((v) => {
            return valueToPath.get(v);
        })
            .filter(Boolean);
    }
    const options = column.dataType === 'date' || column.columnId === GeneralConstants_1.AG_GRID_GROUPED_COLUMN
        ? optionsFromProps
        : optionsFromProps.filter((distinctValue) => {
            let isActive = selectedColumnValues.indexOf(distinctValue.value) >= 0;
            // special case for date objects, need to check against string values
            if (!isActive && distinctValue.value && distinctValue.value instanceof Date) {
                isActive = selectedColumnValues.some((dateStr) => (0, date_fns_1.isEqual)((0, DateHelper_1.parseDateValue)(dateStr), (0, DateHelper_1.parseDateValue)(distinctValue.value)));
            }
            if (StringExtensions_1.StringExtensions.IsNullOrEmpty(distinctValue.value)) {
                return false;
            }
            if (isActive) {
                value.push(distinctValue.value);
            }
            return true;
        });
    const menuStyle = React.useMemo(() => {
        return {
            minWidth: `var(--ab-cmp-select-column-menu-${column.columnId}__min-width, var(--ab-cmp-select-column-menu__min-width, 160px))`,
        };
    }, [column.columnId]);
    const component = column.dataType === 'date' || column.columnId === GeneralConstants_1.AG_GRID_GROUPED_COLUMN ? (React.createElement(TreeDropdown_1.TreeDropdown, { style: {
            width: '100%',
            height: '100%',
            ...props.selectProps?.styles?.container,
        }, toDisplayValue: column.dataType === 'date' ? toDateDisplayValue : undefined, fieldStyle: {
            boxShadow: 'none',
            ...props.selectProps?.styles?.control,
        }, resizable: true, onChange: column.dataType === 'date'
            ? (value) => props.onChange(dateOnChangeParser(value))
            : props.onChange, options: options, 
        // for dates, the treeDateOptions have ids that are numbers
        // so we have to add the `toDateValue` function to convert the values to the correct format
        value: selectedColumnValues, primaryKey: 'value', onMenuOpen: props.onMenuOpen, onMouseDown: (e) => e.stopPropagation() })) : (React.createElement(Select_1.Select, { key: "select", isMulti: true, resizable: true, showHeaderSelectionCheckbox: true, searchable: 'menulist', closeMenuOnSelect: false, menuStyle: menuStyle, ...props.selectProps, onMenuOpen: props.onMenuOpen, options: options, value: value, isLoading: props.isLoading, onChange: props.onChange }));
    return (React.createElement("div", { className: (0, join_1.default)(baseClassName, props.isLoading && `${baseClassName}--loading`, !value.length && `${baseClassName}--empty`), onKeyDownCapture: (e) => {
            const event = e.nativeEvent || e;
            event.stopPropagation = () => {
                // see #ensure-keyboard-navigation-works-in-column-values-filter
                // we want to prevent ag grid from stopping the propagation of the event
                // so that the event can be handled by the select component and thus makes keyboard navigation work
                //
                // the solution is to reassign the stopPropagation method to a function that does nothing
            };
        } }, component));
};
exports.ColumnValuesSelect = ColumnValuesSelect;
