import { createDomElement, emptyElement } from '@slickgrid-universal/utils';
import { SlickEventHandler } from '../core/index.js';
export class HeaderGroupingService {
    constructor(extensionUtility) {
        this.extensionUtility = extensionUtility;
        this.pluginName = 'HeaderGroupingService';
        this._subscriptions = [];
        this._eventHandler = new SlickEventHandler();
    }
    /** Getter of SlickGrid DataView object */
    get _dataView() {
        return this._grid?.getData() ?? {};
    }
    /** Getter of the SlickGrid Event Handler */
    get eventHandler() {
        return this._eventHandler;
    }
    /** Getter for the Grid Options pulled through the Grid Object */
    get _gridOptions() {
        return this._grid?.getOptions() ?? {};
    }
    /**
     * Initialize the Service
     * @param {SlickGrid} grid
     */
    init(grid) {
        this._grid = grid;
        if (grid && this._gridOptions) {
            // When dealing with Pre-Header Grouping colspan, we need to re-create the pre-header in multiple occasions
            // for all these events, we have to trigger a re-create
            if (this._gridOptions.createPreHeaderPanel) {
                // if we use Translation, then we need to translate the first time
                if (this._gridOptions.enableTranslate) {
                    this.translateHeaderGrouping();
                }
                this._eventHandler
                    .subscribe(grid.onAfterUpdateColumns, () => this.renderPreHeaderRowGroupingTitles())
                    .subscribe(grid.onColumnsReordered, () => this.renderPreHeaderRowGroupingTitles())
                    .subscribe(grid.onRendered, () => this.renderPreHeaderRowGroupingTitles())
                    .subscribe(grid.onAutosizeColumns, () => this.renderPreHeaderRowGroupingTitles())
                    .subscribe(this._dataView.onRowCountChanged, () => this.delayRenderPreHeaderRowGroupingTitles(0))
                    .subscribe(grid.onSetOptions, (_e, args) => {
                    // and finally we need to re-create after user calls the Grid "setOptions" when changing from regular to frozen grid (and vice versa)
                    // when user changes frozen columns dynamically (e.g. from header menu), we need to re-render the pre-header of the grouping titles
                    if (args?.optionsBefore?.frozenColumn !== args?.optionsAfter?.frozenColumn) {
                        this.delayRenderPreHeaderRowGroupingTitles(0);
                    }
                });
                // also not sure why at this point, but it seems that I need to call the 1st create in a delayed execution
                // probably some kind of timing issues and delaying it until the grid is fully ready fixes this problem
                this.delayRenderPreHeaderRowGroupingTitles(75);
            }
        }
    }
    dispose() {
        // unsubscribe all SlickGrid events
        clearTimeout(this._timer);
        this._eventHandler.unsubscribeAll();
    }
    /** call "renderPreHeaderRowGroupingTitles()" with a setTimeout delay */
    delayRenderPreHeaderRowGroupingTitles(delay = 0) {
        clearTimeout(this._timer);
        this._timer = setTimeout(() => this.renderPreHeaderRowGroupingTitles(), delay);
    }
    /** Create or Render the Pre-Header Row Grouping Titles */
    renderPreHeaderRowGroupingTitles() {
        const colsCount = this._grid.getVisibleColumns().length;
        if (this._gridOptions?.frozenColumn !== undefined && this._gridOptions.frozenColumn >= 0) {
            const frozenCol = this._gridOptions.frozenColumn;
            // Add column groups to left panel
            this.renderHeaderGroups(this._grid.getPreHeaderPanelLeft(), 0, frozenCol + 1);
            // Add column groups to right panel
            this.renderHeaderGroups(this._grid.getPreHeaderPanelRight(), frozenCol + 1, colsCount);
        }
        else {
            // regular grid (not a frozen grid)
            this.renderHeaderGroups(this._grid.getPreHeaderPanel(), 0, colsCount);
        }
    }
    renderHeaderGroups(preHeaderPanel, start, end) {
        emptyElement(preHeaderPanel);
        preHeaderPanel.className = 'slick-header-columns';
        preHeaderPanel.style.left = '-1000px';
        preHeaderPanel.style.width = `${this._grid.getHeadersWidth()}px`;
        preHeaderPanel.parentElement?.classList.add('slick-header');
        const headerColumnWidthDiff = this._grid.getHeaderColumnWidthDiff();
        let colDef;
        let headerElm = null;
        let lastColumnGroup = '';
        let widthTotal = 0;
        const frozenHeaderWidthCalcDifferential = this._gridOptions?.frozenHeaderWidthCalcDifferential ?? 0;
        const isFrozenGrid = this._gridOptions?.frozenColumn !== undefined && this._gridOptions.frozenColumn >= 0;
        const visibleColumns = this._grid.getVisibleColumns();
        for (let i = start; i < end; i++) {
            colDef = visibleColumns[i];
            if (colDef) {
                if (lastColumnGroup === colDef.columnGroup && i > 0) {
                    widthTotal += colDef.width || 0;
                    if (headerElm?.style) {
                        headerElm.style.width = `${widthTotal - headerColumnWidthDiff - frozenHeaderWidthCalcDifferential}px`; // remove possible frozen border
                    }
                }
                else {
                    widthTotal = colDef.width || 0;
                    headerElm = createDomElement('div', {
                        className: `slick-state-default slick-header-column ${isFrozenGrid ? 'frozen' : ''}`,
                        dataset: { group: colDef.columnGroup },
                        style: { width: `${widthTotal - headerColumnWidthDiff}px` },
                    });
                    createDomElement('span', { className: 'slick-column-name', textContent: colDef.columnGroup || '' }, headerElm);
                    preHeaderPanel.appendChild(headerElm);
                }
                lastColumnGroup = colDef.columnGroup || '';
            }
        }
    }
    /** Translate Column Group texts and re-render them afterward. */
    translateHeaderGrouping() {
        const currentColumnDefinitions = this._grid.getColumns();
        this.extensionUtility.translateItems(currentColumnDefinitions, 'columnGroupKey', 'columnGroup');
        this._grid.updateColumns();
        this.renderPreHeaderRowGroupingTitles();
    }
}
//# sourceMappingURL=headerGrouping.service.js.map