import { isArray, isFunction, isNumber, isObject, isValid } from "@visactor/vutils";

import { getOrApply } from "../../tools/helper";

export function setCheckedState(col, row, field, checked, state) {
    const cellRange = state.table.getCellRange(col, row);
    if (cellRange.start.col !== cellRange.end.col || cellRange.start.row !== cellRange.end.row) for (let i = cellRange.start.col; i <= cellRange.end.col; i++) for (let j = cellRange.start.row; j <= cellRange.end.row; j++) setSingleCheckedState(i, j, field, checked, state); else setSingleCheckedState(col, row, field, checked, state);
}

function setSingleCheckedState(col, row, field, checked, state) {
    const recordIndex = state.table.getRecordShowIndexByCell(col, row);
    if (recordIndex >= 0) {
        const dataIndex = state.table.dataSource.getIndexKey(recordIndex).toString();
        state.checkedState.get(dataIndex) ? state.checkedState.get(dataIndex)[field] = checked : state.checkedState.set(dataIndex, {
            [field]: checked
        });
    }
}

export function setHeaderCheckedState(field, checked, state) {
    var _a;
    state.headerCheckedState[field] = checked, state.table.internalProps.enableCheckboxCascade && (null === (_a = state.checkedState) || void 0 === _a || _a.forEach((recordCheckState => {
        recordCheckState[field] = checked;
    })));
}

export function syncCheckedState(col, row, field, checked, state) {
    var _a, _b;
    if (state.table.isHeader(col, row)) {
        if (isValid(state.headerCheckedState[field])) return state.headerCheckedState[field];
        if ("function" == typeof checked) return;
        if (isValid(checked)) state.headerCheckedState[field] = checked; else if ((null === (_a = state.checkedState) || void 0 === _a ? void 0 : _a.size) > 0) {
            return state.updateHeaderCheckedState(field, col, row);
        }
        return state.headerCheckedState[field];
    }
    const recordIndex = state.table.getRecordShowIndexByCell(col, row);
    if (recordIndex >= 0) {
        const dataIndex = state.table.dataSource.getIndexKey(recordIndex).toString();
        if (isValid(null === (_b = state.checkedState.get(dataIndex)) || void 0 === _b ? void 0 : _b[field])) return state.checkedState.get(dataIndex)[field];
        if (state.checkedState.get(dataIndex)) state.checkedState.get(dataIndex)[field] = checked; else if (state.table.internalProps.enableCheckboxCascade && dataIndex.includes(",")) {
            const parentDataIndex = dataIndex.split(",").slice(0, -1).join(",");
            state.checkedState.has(parentDataIndex) && !0 === state.checkedState.get(parentDataIndex)[field] ? state.checkedState.set(dataIndex, {
                [field]: !0
            }) : state.checkedState.set(dataIndex, {
                [field]: checked
            });
        } else state.checkedState.set(dataIndex, {
            [field]: checked
        });
    }
    return checked;
}

export function initCheckedState(records, state) {
    state.checkedState.clear(), state.headerCheckedState = {}, state.radioState = {};
    let isNeedInitHeaderCheckedStateFromRecord = !1;
    if (state._checkboxCellTypeFields = [], state._headerCheckFuncs = {}, state.table.internalProps.layoutMap.headerObjects.forEach(((hd, index) => {
        if ("checkbox" === hd.headerType) {
            const headerChecked = hd.define.checked;
            null == headerChecked || "function" == typeof headerChecked ? (isNeedInitHeaderCheckedStateFromRecord = !0, 
            "function" == typeof headerChecked && (state._headerCheckFuncs[hd.field] = headerChecked)) : state.headerCheckedState[hd.field] = headerChecked, 
            "checkbox" !== hd.define.cellType && !isFunction(hd.define.cellType) || hd.fieldFormat || state._checkboxCellTypeFields.push(hd.field);
        }
    })), 1 === state.table.leftRowSeriesNumberCount) state.headerCheckedState._vtable_rowSeries_number = !1, 
    state._checkboxCellTypeFields.push("_vtable_rowSeries_number"), isNeedInitHeaderCheckedStateFromRecord = !0; else if (state.table.leftRowSeriesNumberCount > 1) {
        for (let i = 0; i < state.table.leftRowSeriesNumberCount; i++) state.headerCheckedState[`_vtable_rowSeries_number_${i}`] = !1, 
        state._checkboxCellTypeFields.push(`_vtable_rowSeries_number_${i}`);
        isNeedInitHeaderCheckedStateFromRecord = !0;
    }
    isNeedInitHeaderCheckedStateFromRecord && initRecordCheckState(records, state);
}

export function updateHeaderCheckedState(field, state, col, row) {
    let allChecked = !0, allUnChecked = !0, hasChecked = !1;
    return state.checkedState.forEach(((check_state, index) => {
        var _a;
        index = index.includes(",") ? index.split(",").map((item => Number(item))) : Number(index);
        const tableIndex = state.table.getTableIndexByRecordIndex(index), mergeCell = state.table.transpose ? state.table.getCustomMerge(tableIndex, row) : state.table.getCustomMerge(col, tableIndex), data = null === (_a = state.table.dataSource) || void 0 === _a ? void 0 : _a.get(index);
        mergeCell || !state.table.internalProps.enableCheckboxCascade && (null == data ? void 0 : data.vtableMerge) || (!0 !== (null == check_state ? void 0 : check_state[field]) ? allChecked = !1 : (allUnChecked = !1, 
        hasChecked = !0));
    })), allChecked ? (state.headerCheckedState[field] = !0, allChecked) : allUnChecked ? (state.headerCheckedState[field] = !1, 
    !1) : !!hasChecked && (state.headerCheckedState[field] = "indeterminate", "indeterminate");
}

export function initLeftRecordsCheckState(records, state) {
    for (let index = state.checkedState.size; index < records.length; index++) {
        const record = records[index];
        state._checkboxCellTypeFields.forEach((field => {
            const value = record[field];
            let isChecked;
            isObject(value) ? isChecked = value.checked : "boolean" == typeof value && (isChecked = value);
            const dataIndex = index.toString();
            state.checkedState.get(dataIndex) || state.checkedState.set(dataIndex, {}), state.checkedState.get(dataIndex)[field] = isChecked;
        }));
    }
}

export function setCellCheckboxState(col, row, checked, table) {
    var _a, _b;
    const cellGroup = table.scenegraph.getCell(col, row), checkbox = (null == cellGroup ? void 0 : cellGroup.getChildByName("checkbox")) || (null === (_b = null === (_a = null == cellGroup ? void 0 : cellGroup.getChildByName("checkbox-content")) || void 0 === _a ? void 0 : _a._checkboxGroup) || void 0 === _b ? void 0 : _b.getChildByName("checkbox"));
    if (!checkbox) {
        const field = table.getHeaderField(col, row);
        if (table.isHeader(col, row)) {
            table.stateManager.setHeaderCheckedState(field, checked);
            "checkbox" === table.getCellType(col, row) && table.scenegraph.updateCheckboxCellState(col, row, checked);
        } else {
            table.stateManager.setCheckedState(col, row, field, checked);
            if ("checkbox" === table.getCellType(col, row)) {
                const oldHeaderCheckedState = table.stateManager.headerCheckedState[field], newHeaderCheckedState = table.stateManager.updateHeaderCheckedState(field, col, row);
                oldHeaderCheckedState !== newHeaderCheckedState && table.scenegraph.updateHeaderCheckboxCellState(col, row, newHeaderCheckedState);
            }
        }
        return;
    }
    const {checked: oldChecked, indeterminate: indeterminate} = checkbox.attribute;
    indeterminate ? (checked || checkbox._handlePointerUp(), checkbox._handlePointerUp()) : oldChecked ? checked || checkbox._handlePointerUp() : checked && checkbox._handlePointerUp();
}

export function setCellCheckboxStateByAttribute(col, row, checked, table) {
    var _a, _b;
    const cellGroup = table.scenegraph.getCell(col, row), checkbox = (null == cellGroup ? void 0 : cellGroup.getChildByName("checkbox")) || (null === (_b = null === (_a = null == cellGroup ? void 0 : cellGroup.getChildByName("checkbox-content")) || void 0 === _a ? void 0 : _a._checkboxGroup) || void 0 === _b ? void 0 : _b.getChildByName("checkbox"));
    checkbox && ("indeterminate" === checked ? (checkbox.setAttribute("indeterminate", !0), 
    checkbox.setAttribute("checked", void 0)) : (checkbox.setAttribute("indeterminate", void 0), 
    checkbox.setAttribute("checked", checked)));
}

export function changeCheckboxOrder(sourceIndex, targetIndex, state) {
    const {checkedState: checkedState, table: table} = state;
    let source, target;
    if (table.internalProps.transpose ? (sourceIndex = table.getRecordShowIndexByCell(sourceIndex, 0), 
    targetIndex = table.getRecordShowIndexByCell(targetIndex, 0)) : (source = table.isPivotTable() ? void 0 : table.getRecordIndexByCell(0, sourceIndex), 
    target = table.isPivotTable() ? void 0 : table.getRecordIndexByCell(0, targetIndex)), 
    isNumber(source) && isNumber(target)) {
        if ((sourceIndex = source) > (targetIndex = target)) {
            const sourceRecord = checkedState.get(sourceIndex.toString());
            for (let i = sourceIndex; i > targetIndex; i--) checkedState.set(i.toString(), checkedState.get((i - 1).toString()));
            checkedState.set(targetIndex.toString(), sourceRecord);
        } else if (sourceIndex < targetIndex) {
            const sourceRecord = checkedState.get(sourceIndex.toString());
            for (let i = sourceIndex; i < targetIndex; i++) checkedState.set(i.toString(), checkedState.get((i + 1).toString()));
            checkedState.set(targetIndex.toString(), sourceRecord);
        }
    } else if (isArray(source) && isArray(target)) if ((sourceIndex = source[source.length - 1]) > (targetIndex = target[target.length - 1])) {
        const sourceRecord = checkedState.get(source.toString());
        for (let i = sourceIndex; i > targetIndex; i--) {
            const now = [ ...source ];
            now[now.length - 1] = i;
            const last = [ ...source ];
            last[last.length - 1] = i - 1, checkedState.set(now.toString(), checkedState.get(last.toString()));
        }
        checkedState.set(target.toString(), sourceRecord);
    } else if (sourceIndex < targetIndex) {
        const sourceRecord = checkedState.get(source.toString());
        for (let i = sourceIndex; i < targetIndex; i++) {
            const now = [ ...source ];
            now[now.length - 1] = i;
            const next = [ ...source ];
            next[next.length - 1] = i + 1, checkedState.set(now.toString(), checkedState.get(next.toString()));
        }
        checkedState.set(target.toString(), sourceRecord);
    }
}

export function getGroupCheckboxState(table) {
    const result = [], dataSource = table.dataSource, groupKeyLength = dataSource.dataConfig.groupByRules.length + 1;
    return dataSource.currentIndexedData.forEach(((indexArr, index) => {
        if (isArray(indexArr) && indexArr.length === groupKeyLength) {
            const vtableOriginIndex = dataSource.getOriginRecordIndexForGroup(indexArr);
            result[vtableOriginIndex] = table.stateManager.checkedState.get(indexArr.toString());
        }
    })), result;
}

function initRecordCheckState(records, state) {
    const table = state.table, start = table.isPivotTable() ? 0 : table.internalProps.transpose ? table.rowHeaderLevelCount : table.columnHeaderLevelCount, end = table.isPivotTable() ? isArray(records) ? records.length : 0 : table.internalProps.transpose ? table.colCount : table.rowCount;
    for (let index = 0; index + start < end; index++) {
        const record = table.isPivotTable() ? records[index] : table.dataSource.get(index);
        state._checkboxCellTypeFields.forEach((field => {
            const value = record && record[field];
            let isChecked;
            if (isObject(value) ? isChecked = value.checked : "boolean" == typeof value && (isChecked = value), 
            null == isChecked) {
                const headerCheckFunc = state._headerCheckFuncs[field];
                if (headerCheckFunc) {
                    const cellAddr = state.table.getCellAddrByFieldRecord(field, index);
                    isChecked = getOrApply(headerCheckFunc, {
                        col: cellAddr.col,
                        row: cellAddr.row,
                        table: state.table,
                        context: null,
                        value: value
                    });
                }
            }
            const dataIndex = table.isPivotTable() ? index.toString() : state.table.dataSource.getIndexKey(index).toString();
            state.checkedState.get(dataIndex) || state.checkedState.set(dataIndex, {}), state.checkedState.get(dataIndex)[field] = isChecked;
        }));
    }
}
//# sourceMappingURL=checkbox.js.map
