import { isFunction, isValid, merge } from "@visactor/vutils";

import { cellStyleKeys } from "../ts-types";

import { Factory } from "../core/factory";

export class CustomCellStylePlugin {
    constructor(table, customCellStyle, customCellStyleArrangement) {
        this.table = table, this.customCellStyle = customCellStyle, this.customCellStyleArrangement = customCellStyleArrangement;
    }
    getCustomCellStyle(col, row) {
        const customStyleIds = this.getCustomCellStyleIds(col, row);
        if (customStyleIds.length) {
            const styles = [];
            return customStyleIds.forEach((customStyleId => {
                const styleOption = this.getCustomCellStyleOption(customStyleId);
                if (isFunction(null == styleOption ? void 0 : styleOption.style)) {
                    const style = styleOption.style({
                        col: col,
                        row: row,
                        table: this.table,
                        value: this.table.getCellValue(col, row),
                        dataValue: this.table.getCellOriginValue(col, row),
                        cellHeaderPaths: this.table.getCellHeaderPaths(col, row)
                    });
                    styles.push(style);
                } else (null == styleOption ? void 0 : styleOption.style) && styles.push(styleOption.style);
            })), merge({}, ...styles);
        }
    }
    getCustomCellStyleIds(col, row) {
        const customStyleIds = [], range = this.table.getCellRange(col, row);
        for (let c = range.start.col; c <= range.end.col; c++) for (let r = range.start.row; r <= range.end.row; r++) this.customCellStyleArrangement.forEach((style => {
            style.cellPosition.range ? style.cellPosition.range.start.col <= c && style.cellPosition.range.end.col >= c && style.cellPosition.range.start.row <= r && style.cellPosition.range.end.row >= r && customStyleIds.push(style.customStyleId) : style.cellPosition.col === c && style.cellPosition.row === r && customStyleIds.push(style.customStyleId);
        }));
        return customStyleIds;
    }
    getCustomCellStyleOption(customStyleId) {
        return this.customCellStyle.find((style => style.id === customStyleId));
    }
    registerCustomCellStyle(customStyleId, customStyle) {
        const index = this.customCellStyle.findIndex((style => style.id === customStyleId));
        -1 === index ? this.customCellStyle.push({
            id: customStyleId,
            style: customStyle
        }) : this.customCellStyle[index] = {
            id: customStyleId,
            style: customStyle
        }, this.customCellStyleArrangement.forEach((cellStyle => {
            const cellPos = cellStyle.cellPosition;
            if (cellStyle.customStyleId === customStyleId) if (cellPos.range) for (let col = Math.max(0, cellPos.range.start.col); col <= Math.min(this.table.colCount - 1, cellPos.range.end.col); col++) for (let row = Math.max(0, cellPos.range.start.row); row <= Math.min(this.table.rowCount - 1, cellPos.range.end.row); row++) this.table.scenegraph.updateCellContent(col, row); else this.table.scenegraph.updateCellContent(cellPos.col, cellPos.row);
        })), this.table.scenegraph.updateNextFrame();
    }
    arrangeCustomCellStyle(cellPos, customStyleId, forceFastUpdate) {
        var _a;
        const index = this.customCellStyleArrangement.findIndex((style => style.cellPosition.range && cellPos.range ? style.cellPosition.range.start.col === cellPos.range.start.col && style.cellPosition.range.start.row === cellPos.range.start.row && style.cellPosition.range.end.col === cellPos.range.end.col && style.cellPosition.range.end.row === cellPos.range.end.row : style.cellPosition.col === cellPos.col && style.cellPosition.row === cellPos.row));
        if (-1 === index && !customStyleId) return;
        if (-1 === index && customStyleId) this.customCellStyleArrangement.push({
            cellPosition: {
                col: cellPos.col,
                row: cellPos.row,
                range: cellPos.range
            },
            customStyleId: customStyleId
        }); else {
            if (this.customCellStyleArrangement[index].customStyleId === customStyleId) return;
            customStyleId ? this.customCellStyleArrangement[index].customStyleId = customStyleId : this.customCellStyleArrangement.splice(index, 1);
        }
        const style = null === (_a = this.getCustomCellStyleOption(customStyleId)) || void 0 === _a ? void 0 : _a.style;
        if (style) {
            forceFastUpdate = !0;
            for (const key in style) if (-1 === cellStyleKeys.indexOf(key)) {
                forceFastUpdate = !1;
                break;
            }
        }
        if (cellPos.range) for (let col = Math.max(0, cellPos.range.start.col); col <= Math.min(this.table.colCount - 1, cellPos.range.end.col); col++) for (let row = Math.max(0, cellPos.range.start.row); row <= Math.min(this.table.rowCount - 1, cellPos.range.end.row); row++) {
            const range = this.table.getCellRange(col, row);
            for (let c = range.start.col; c <= range.end.col; c++) for (let r = range.start.row; r <= range.end.row; r++) this.table.scenegraph.updateCellContent(c, r, forceFastUpdate);
        } else this.table.scenegraph.updateCellContent(cellPos.col, cellPos.row, forceFastUpdate);
        this.table.scenegraph.updateNextFrame();
    }
    updateCustomCell(customCellStyle, customCellStyleArrangement) {
        this.customCellStyle.length = 0, this.customCellStyleArrangement.length = 0, customCellStyle.forEach((cellStyle => {
            this.registerCustomCellStyle(cellStyle.id, cellStyle.style);
        })), customCellStyleArrangement.forEach((cellStyle => {
            this.arrangeCustomCellStyle(cellStyle.cellPosition, cellStyle.customStyleId);
        }));
    }
    hasCustomCellStyle(customStyleId) {
        return this.customCellStyle.some((style => style.id === customStyleId));
    }
}

export function mergeStyle(cacheStyle, customCellStyle) {
    cacheStyle = cacheStyle.clone();
    for (const key in customCellStyle) {
        const value = customCellStyle[key];
        isValid(value) && (cacheStyle[`_${key}`] = value);
    }
    return cacheStyle;
}

export const registerCustomCellStylePlugin = () => {
    Factory.registerComponent("customCellStylePlugin", CustomCellStylePlugin);
};
//# sourceMappingURL=custom-cell-style.js.map
