"use strict";
Object.defineProperty(exports, "__esModule", {
    value: true
});
function _export(target, all) {
    for(var name in all)Object.defineProperty(target, name, {
        enumerable: true,
        get: Object.getOwnPropertyDescriptor(all, name).get
    });
}
_export(exports, {
    get CHIP_CLASS () {
        return CHIP_CLASS;
    },
    get CHIP_REMOVE_CLASS () {
        return CHIP_REMOVE_CLASS;
    },
    get CLASS_PREFIX () {
        return CLASS_PREFIX;
    },
    get cacheColumnWidthAndRegisterResizeHook () {
        return cacheColumnWidthAndRegisterResizeHook;
    },
    get createChipElement () {
        return createChipElement;
    },
    get createOverflowIndicator () {
        return createOverflowIndicator;
    },
    get getItemProperty () {
        return getItemProperty;
    },
    get handleChipsOverflow () {
        return handleChipsOverflow;
    },
    get parseValue () {
        return parseValue;
    },
    get registerChipRemovingEvents () {
        return registerChipRemovingEvents;
    },
    get removeValueByKey () {
        return removeValueByKey;
    }
});
const _object = require("../../../helpers/object");
const _a11y = require("../../../helpers/a11y");
const _element = require("../../../helpers/dom/element");
const _event = require("../../../helpers/dom/event");
const _eventManager = /*#__PURE__*/ _interop_require_default(require("../../../eventManager"));
function _interop_require_default(obj) {
    return obj && obj.__esModule ? obj : {
        default: obj
    };
}
const CLASS_PREFIX = 'ht-multi-select';
const CHIP_CLASS = `${CLASS_PREFIX}-chip`;
const CHIP_REMOVE_CLASS = `${CLASS_PREFIX}-chip-remove`;
const CHIP_LABEL_CLASS = `${CLASS_PREFIX}-chip-label`;
const OVERFLOW_INDICATOR_CLASS = `${CLASS_PREFIX}-overflow`;
const beforeColumnResizeHookRegistered = new WeakSet();
const latestColumnWidthCache = new WeakMap();
const chipsEventManagers = new WeakMap();
function getItemProperty(item, property) {
    return (0, _object.isKeyValueObject)(item) ? item[property] : item;
}
function parseValue(value) {
    if (value === null || value === undefined || value === '') {
        return [];
    }
    if (Array.isArray(value)) {
        return value;
    }
    if (typeof value === 'string') {
        try {
            const parsed = JSON.parse(value);
            return Array.isArray(parsed) ? parsed : [
                parsed
            ];
        } catch  {
            return value.trim() ? [
                value
            ] : [];
        }
    }
    return [
        value
    ];
}
function createChipElement(rootDocument, item, isAriaEnabled, row, prop) {
    const chip = rootDocument.createElement('span');
    const textContent = getItemProperty(item, 'value');
    (0, _element.addClass)(chip, CHIP_CLASS);
    chip.dataset.row = row;
    chip.dataset.prop = prop;
    chip.title = textContent;
    const label = rootDocument.createElement('span');
    (0, _element.addClass)(label, CHIP_LABEL_CLASS);
    label.textContent = textContent;
    chip.appendChild(label);
    const removeBtn = rootDocument.createElement('span');
    (0, _element.addClass)(removeBtn, CHIP_REMOVE_CLASS);
    if (isAriaEnabled) {
        removeBtn.setAttribute(...(0, _a11y.A11Y_HIDDEN)());
    }
    chip.dataset.key = getItemProperty(item, 'key');
    chip.appendChild(removeBtn);
    return chip;
}
function createOverflowIndicator(rootDocument, count) {
    const indicator = rootDocument.createElement('span');
    (0, _element.addClass)(indicator, OVERFLOW_INDICATOR_CLASS);
    indicator.textContent = `+${count}`;
    return indicator;
}
function registerChipRemovingEvents(hotInstance, rendererType) {
    if (chipsEventManagers.has(hotInstance)) {
        return;
    }
    chipsEventManagers.set(hotInstance, new _eventManager.default(hotInstance));
    const eventManager = chipsEventManagers.get(hotInstance);
    eventManager.addEventListener(hotInstance.rootElement, 'click', (event)=>{
        if (!(0, _element.hasClass)(event.target, CHIP_REMOVE_CLASS)) {
            return;
        }
        event.preventDefault();
        event.stopPropagation();
        const chip = event.target.closest(`.${CHIP_CLASS}`);
        if (!chip) {
            return;
        }
        const rowIndex = chip.dataset.row;
        const columnProp = chip.dataset.prop;
        const physicalRow = hotInstance.toPhysicalRow(rowIndex);
        const physicalColumn = typeof columnProp === 'string' ? columnProp : hotInstance.toPhysicalColumn(columnProp);
        const visualColumn = hotInstance.propToCol(columnProp);
        const currentData = hotInstance.getSourceDataAtCell(physicalRow, visualColumn);
        const keyToRemove = chip.dataset.key;
        const newData = removeValueByKey(parseValue(currentData), keyToRemove);
        hotInstance.setSourceDataAtCell(physicalRow, physicalColumn, newData, `${rendererType}-renderer`);
        hotInstance.render();
    });
    hotInstance.addHook('beforeOnCellMouseDown', (event)=>{
        if ((0, _element.hasClass)(event.target, CHIP_REMOVE_CLASS)) {
            (0, _event.stopImmediatePropagation)(event);
        }
    });
}
function cacheColumnWidthAndRegisterResizeHook(hotInstance, col) {
    const currentWidth = hotInstance.getColWidth(col);
    // Cache the column width (required to know the column width before it's rendered - e.g. ManualColumnResize)
    if (!latestColumnWidthCache.has(hotInstance)) {
        latestColumnWidthCache.set(hotInstance, {
            [col]: {
                width: currentWidth
            }
        });
    } else if (latestColumnWidthCache.get(hotInstance)?.[col]?.width !== currentWidth) {
        latestColumnWidthCache.set(hotInstance, {
            ...latestColumnWidthCache.get(hotInstance),
            [col]: {
                width: currentWidth
            }
        });
    }
    if (!beforeColumnResizeHookRegistered.has(hotInstance)) {
        hotInstance.addHook('beforeColumnResize', (newSize, columnIndex)=>{
            if (latestColumnWidthCache.get(hotInstance)?.[columnIndex]?.width !== newSize) {
                latestColumnWidthCache.set(hotInstance, {
                    ...latestColumnWidthCache.get(hotInstance),
                    [columnIndex]: {
                        width: newSize
                    }
                });
            }
        });
        beforeColumnResizeHookRegistered.add(hotInstance);
    }
    return latestColumnWidthCache.get(hotInstance)?.[col]?.width ?? currentWidth;
}
/**
 * Recalculates which chips are visible and updates the overflow indicator.
 * This function is called both on initial render and when container size changes.
 *
 * @param {number} columnWidth The width of the column.
 * @param {HTMLElement} chipsContainer The container holding the chips.
 * @param {Document} rootDocument The document object.
 */ function recalculateChipsVisibility(columnWidth, chipsContainer, rootDocument) {
    const containerWidth = columnWidth;
    const chips = chipsContainer.querySelectorAll(`.${CHIP_CLASS}`);
    for(let i = 0; i < chips.length; i++){
        chips[i].style.display = '';
    }
    if (containerWidth === null || chips.length === 0) {
        return;
    }
    let indicator = chipsContainer.querySelector(`.${OVERFLOW_INDICATOR_CLASS}`);
    if (!indicator) {
        indicator = createOverflowIndicator(rootDocument, chips.length);
        indicator.style.visibility = 'hidden';
        chipsContainer.appendChild(indicator);
    } else {
        indicator.style.display = '';
        indicator.style.visibility = 'hidden';
    }
    const containerStyles = rootDocument.defaultView.getComputedStyle(chipsContainer);
    const gap = parseFloat(containerStyles.gap) || 0;
    const indicatorWidth = indicator.offsetWidth;
    let totalWidth = 0;
    let visibleCount = 0;
    for(let i = 0; i < chips.length; i++){
        const chipWidth = chips[i].offsetWidth;
        const chipGap = i < chips.length - 1 ? gap : 0;
        const nextWidth = totalWidth + chipWidth + chipGap;
        const needsIndicatorSpace = i < chips.length - 1;
        const availableWidth = containerWidth - (needsIndicatorSpace ? indicatorWidth + gap : 0);
        if (nextWidth <= availableWidth) {
            totalWidth = nextWidth;
            visibleCount += 1;
        } else {
            break;
        }
    }
    const hiddenCount = chips.length - visibleCount;
    if (hiddenCount > 0) {
        for(let i = visibleCount; i < chips.length; i++){
            chips[i].style.display = 'none';
        }
        indicator.textContent = `+${hiddenCount}`;
        indicator.style.visibility = 'visible';
    } else {
        indicator.style.display = 'none';
    }
}
function handleChipsOverflow(columnWidth, chipsContainer, rootDocument) {
    recalculateChipsVisibility(columnWidth, chipsContainer, rootDocument);
}
function removeValueByKey(array, keyToRemove) {
    return array.filter((item)=>{
        return getItemProperty(item, 'key') !== keyToRemove;
    });
}
