import * as i0 from '@angular/core';
import { EventEmitter, Injectable } from '@angular/core';
import { isUndefined, isNullOrUndefined, isNumber } from '@ironsource/fusion-ui/utils';
import * as i1 from '@angular/platform-browser';
import * as i2 from '@ironsource/fusion-ui/services/log';
import { TableColumnTypeEnum, MAXIMUM_EXPANDABLE_LEVEL, DEFAULT_EXPANDABLE_LEVEL, TableRowClassesEnum } from '@ironsource/fusion-ui/components/table/common/entities';
import * as i3 from '@ironsource/fusion-ui/services/unique-id';

class TableService {
    constructor(sanitizer, logService, uniqueService) {
        this.sanitizer = sanitizer;
        this.logService = logService;
        this.uniqueService = uniqueService;
        this.selectedRows = [];
        this.selectionChanged = new EventEmitter();
        this.rowModelChange = new EventEmitter();
        this.rowActionClicked = new EventEmitter();
        this.hasRowspanRows = false;
        this.rowsMetadata = {};
    }
    onRowsSelectChanged(isGroupedTable, rows, isChecked) {
        if (isGroupedTable) {
            this.selectionChanged.emit({ isAllSelected: isChecked });
        }
        else {
            this.selectedRows = [];
            rows.forEach(row => {
                if (!row.isRowTotal) {
                    row.checkbox = isChecked;
                    if (isChecked) {
                        this.selectedRows.push(row);
                    }
                }
            });
            this.selectionChanged.emit(this.selectedRows);
        }
    }
    onRowSelectChanged(isChecked, row) {
        this.setRowSelectionState(isChecked, row);
        this.selectionChanged.emit(this.selectedRows);
    }
    removeRow({ rows, rowIndex, row, options = {} }) {
        if (options.remove && options.remove.active) {
            if (rowIndex !== -1) {
                let rowToRemove = row;
                if (options.isGroupedTable) {
                    // in grouped table we emit the data until the main parent
                    let rowLevel = row.data.length;
                    for (let i = rowIndex - 1; i >= 0; i--) {
                        if (rows[i].data.length > rowLevel) {
                            rowLevel = rows[i].data.length;
                            rowToRemove = { parent: rows[i], child: rowToRemove };
                        }
                    }
                }
                // if onRemove event emitter is set we emit event to subscribers
                if (options.remove.onRemove) {
                    options.remove.onRemove.emit({ rowIndex, rowToRemove });
                }
                else if (!options.isGroupedTable) {
                    rows.splice(rowIndex, 1);
                }
            }
            else {
                this.logService.error(new Error('Row Not found'));
            }
        }
    }
    initSelectedRows(rows) {
        this.selectedRows = [];
        rows.forEach(row => {
            this.setRowSelectionState(row.checkbox, row);
        });
    }
    setRowsMetadata(rows) {
        return rows.map((row, idx) => {
            const rowId = idx + '_' + this.uniqueService.getUniqueId();
            this.rowsMetadata[rowId] = row.rowMetaData ?? {};
            if (!!this.rowsExpandableKey && row[this.rowsExpandableKey]) {
                row[this.rowsExpandableKey] = this.setRowsMetadata(row[this.rowsExpandableKey]);
            }
            return { ...row, _rowId: rowId };
        });
    }
    clearSelectedRows() {
        this.selectedRows.forEach(row => {
            row.checkbox = false;
        });
        this.selectedRows = [];
    }
    replaceSelectedRows({ selectedTableRows, iditicationFunc }) {
        if (Array.isArray(selectedTableRows)) {
            selectedTableRows.forEach(row => {
                const id = iditicationFunc(row);
                const selectedRowIndex = this.selectedRows.findIndex(selectedRow => iditicationFunc(selectedRow) === id);
                if (selectedRowIndex !== -1) {
                    this.selectedRows.splice(selectedRowIndex, 1);
                    this.selectedRows.push(row);
                }
            });
        }
    }
    isAllRowsSelected(rows) {
        return rows.length === this.selectedRows.length;
    }
    isPartialSelected(rows) {
        return this.selectedRows.length && rows.length !== this.selectedRows.length;
    }
    getColumnStyle(col) {
        const style = col.style || {};
        if (col.stickyLeftMargin) {
            style.left = col.stickyLeftMargin;
        }
        return style;
    }
    getColumnClasses(col, isHeader = false) {
        const classes = [];
        classes.push(!!col.groupName ? 'fu-border-left' : '');
        if (isHeader) {
            classes.push(this.isColumnSortable(col) ? `is-sort ${col.sort}` : '');
            classes.push(this.getHeaderStickyClass(col));
            classes.push(this.isTypeCheckbox(col) ? 'is-checkbox-holder' : '');
        }
        else {
            classes.push(`${col.class || ''} ${this.isColumnSortable(col) ? 'is-sorted' : ''}`.trim());
        }
        return classes.filter(Boolean);
    }
    isRowSelected(row) {
        return this.isInSelected(row) !== -1;
    }
    isColumnSortable(col) {
        return !isUndefined(col.sort);
    }
    isTableEmpty(rows, isGroupedTable, hasTotalRow = false) {
        return !isGroupedTable ? rows.length - (!!hasTotalRow ? 1 : 0) < 1 : !rows.value && (!rows.children || !rows.children.length);
    }
    isTypeComponent(column) {
        return TableColumnTypeEnum.Component === column.type;
    }
    isTypeString(column) {
        return !column.type || TableColumnTypeEnum.String === column.type;
    }
    isTypeCurrency(column) {
        return column.type && TableColumnTypeEnum.Currency === column.type;
    }
    isTypeNumber(column) {
        return column.type && TableColumnTypeEnum.Number === column.type;
    }
    isTypePercent(column) {
        return column.type && TableColumnTypeEnum.Percent === column.type;
    }
    isTypeDate(column) {
        return TableColumnTypeEnum.Date === column.type;
    }
    isTypeCheckbox(column) {
        return TableColumnTypeEnum.Checkbox === column.type;
    }
    isTypeToggleButton(column) {
        return TableColumnTypeEnum.ToggleButton === column.type;
    }
    isTypeInputEdit(column) {
        return TableColumnTypeEnum.InputEdit === column.type;
    }
    isInTotalTypeString(column) {
        let defaultAsString = false;
        if (isNullOrUndefined(column.totalRowTypeAsString)) {
            switch (column.type) {
                case TableColumnTypeEnum.Component:
                case TableColumnTypeEnum.Checkbox:
                case TableColumnTypeEnum.ToggleButton:
                case TableColumnTypeEnum.InputEdit:
                    defaultAsString = true;
            }
        }
        return defaultAsString || column.totalRowTypeAsString;
    }
    isRemove(isLast, tableOptions, rowOptions = {}) {
        return tableOptions?.remove?.active && isLast && !rowOptions.hideRemoveIcon;
    }
    setWidth(isLast, width) {
        return !isLast && width ? width : '';
    }
    getWidth(columns, column) {
        if (column.width) {
            return column.width;
        }
        else {
            let columnToCalc = columns.length;
            const widthToReduce = columns.reduce((sum, currentColumn) => {
                if (currentColumn.width) {
                    columnToCalc--;
                    return (sum ? `${sum} -` : '') + currentColumn.width;
                }
                else {
                    return sum;
                }
            }, '');
            return this.sanitizer.bypassSecurityTrustStyle(`calc((100% - ${widthToReduce}) / ${columnToCalc})`);
        }
    }
    getHeaderStickyClass(col) {
        let headerClass = '';
        if (col.sticky) {
            headerClass += ' sticky-left';
        }
        if (col.class && col.class.indexOf('display-shadow-on-scroll') !== -1) {
            headerClass += ' display-shadow-on-scroll';
        }
        return headerClass;
    }
    setExpandLevelByExpandOptions(expandOptions) {
        if (!!expandOptions.expandLevels) {
            // check that it <= 2 or throw exception
            if (expandOptions.expandLevels > MAXIMUM_EXPANDABLE_LEVEL) {
                throw new Error(`Maximum table rows expandable level is: ${MAXIMUM_EXPANDABLE_LEVEL}`);
            }
            else {
                this.expandLevels = expandOptions.expandLevels;
            }
        }
        else {
            this.expandLevels = DEFAULT_EXPANDABLE_LEVEL;
        }
    }
    getExpandLevelByRowIndex(rowIndex) {
        if (isNumber(rowIndex)) {
            return 1;
        }
        return rowIndex.split('_').length;
    }
    isRowReadOnly(row) {
        return row.hasOwnProperty('_rowId')
            ? !!this.rowsMetadata[row['_rowId']]?.readonly // for style v1 and 2
            : !!row.rowMetaData?.readonly; // for style v3
    }
    toggleRowInRequest(row, isInRequest) {
        this.rowsMetadata[row['_rowId']].inRequest = isInRequest;
    }
    setRowspanColumnsData(rows, columnsKeys) {
        rows.forEach(row => {
            if (Object.values(row).some(val => Array.isArray(val))) {
                if (!this.hasRowspanRows) {
                    this.hasRowspanRows = true;
                }
                const rowId = row['_rowId'];
                this.rowsMetadata[rowId].rowspanColumnsData = this.getRowspanColumns(row, columnsKeys);
                this.rowsMetadata[rowId].maxRowspanInColumn = Math.max(...Object.values(this.rowsMetadata[rowId].rowspanColumnsData));
            }
        });
    }
    getRowspanColumnsData(row) {
        return this.rowsMetadata[row['_rowId']]?.rowspanColumnsData;
    }
    getMaxRowspanInColumn(row) {
        return this.rowsMetadata[row['_rowId']]?.maxRowspanInColumn ?? 0;
    }
    getRowspanColumns(row, columnsKeys) {
        const multiRows = {};
        columnsKeys.forEach(cell => {
            if (Array.isArray(row[cell])) {
                multiRows[cell] = row[cell].length;
            }
            else {
                multiRows[cell] = 0;
            }
        });
        return multiRows;
    }
    setRowSelectionState(isChecked, row) {
        const idx = this.isInSelected(row);
        if (isChecked && idx === -1) {
            row.checkbox = true;
            this.selectedRows.push(row);
        }
        if (!isChecked && idx !== -1) {
            row.checkbox = false;
            this.selectedRows.splice(idx, 1);
        }
    }
    isInSelected(row) {
        if (row.hasOwnProperty('checkbox')) {
            return this.selectedRows.findIndex(item => {
                return Object.keys(row).every(key => {
                    if (key !== 'checkbox') {
                        return row[key] == item[key];
                    }
                    return true;
                });
            });
        }
        return this.selectedRows.indexOf(row);
    }
    static { this.ɵfac = function TableService_Factory(t) { return new (t || TableService)(i0.ɵɵinject(i1.DomSanitizer), i0.ɵɵinject(i2.LogService), i0.ɵɵinject(i3.UniqueIdService)); }; }
    static { this.ɵprov = /*@__PURE__*/ i0.ɵɵdefineInjectable({ token: TableService, factory: TableService.ɵfac }); }
}
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(TableService, [{
        type: Injectable
    }], () => [{ type: i1.DomSanitizer }, { type: i2.LogService }, { type: i3.UniqueIdService }], null); })();

class TableUtils {
    onTableRowDataChanged(options, tableOptions, tableRows$) {
        const rowIndex = options.cellPosition.x;
        const tableRowOptions = !isNullOrUndefined(tableOptions.rowsOptions) ? tableOptions.rowsOptions : (tableOptions.rowsOptions = {});
        tableRowOptions[rowIndex] = { class: TableRowClassesEnum.Loading };
        return {
            rowIndex,
            rowModel: tableRows$.getValue()[rowIndex],
            keyChanged: options.keyChanged,
            newValue: options.newValue,
            prevValue: options.prevValue,
            onRequestDone: (state, error, stayInEditOnCancel = false) => {
                const rowOptionsByIndex = tableRowOptions[rowIndex];
                if (!!rowOptionsByIndex) {
                    delete rowOptionsByIndex.class;
                    if (!Object.keys(rowOptionsByIndex).length) {
                        delete tableRowOptions[rowIndex];
                    }
                }
                // callback to cell
                if (options.onCellRequestDone) {
                    options.onCellRequestDone(state, error, stayInEditOnCancel);
                }
            }
        };
    }
    static { this.ɵfac = function TableUtils_Factory(t) { return new (t || TableUtils)(); }; }
    static { this.ɵprov = /*@__PURE__*/ i0.ɵɵdefineInjectable({ token: TableUtils, factory: TableUtils.ɵfac, providedIn: 'root' }); }
}
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(TableUtils, [{
        type: Injectable,
        args: [{
                providedIn: 'root'
            }]
    }], null, null); })();

/**
 * Generated bundle index. Do not edit.
 */

export { TableService, TableUtils };
//# sourceMappingURL=ironsource-fusion-ui-components-table-common-services.mjs.map
