"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.backspaceCommand = exports.clearSelectedCells = void 0;
const commands_1 = require("../../../../pm/commands.js");
const state_1 = require("../../../../pm/state.js");
const specs_1 = require("../../../base/specs.js");
const lodash_1 = require("../../../../lodash.js");
const table_utils_1 = require("../../../../table-utils/index.js");
const table_desc_1 = require("../../../../table-utils/table-desc.js");
const selection_1 = require("../../../../utils/selection.js");
const utils_1 = require("../utils.js");
const removeCellNodeContent = (state, dispatch) => {
    const sel = state.selection;
    if (!(0, selection_1.isNodeSelection)(sel))
        return false;
    const selNode = sel.node;
    if ((0, table_utils_1.isTableRowNode)(selNode)) {
        // remove the table row
        dispatch?.(state.tr.deleteSelection());
        return true;
    }
    if ((0, table_utils_1.isTableCellNode)(selNode)) {
        if (dispatch) {
            // clearing the table cell
            const from = sel.from + 1;
            const to = sel.to - 1;
            let tr = state.tr.delete(from, to);
            tr = tr.setSelection(state_1.TextSelection.create(tr.doc, from));
            dispatch(tr);
        }
        return true;
    }
    return false;
};
const clearSelectedCells = (state, dispatch) => {
    const sel = state.selection;
    if (!(0, selection_1.isTextSelection)(sel))
        return false;
    const { $from, $to } = sel;
    const sharedDepth = $from.sharedDepth($to.pos);
    const commonAncestor = $from.node(sharedDepth);
    const { schema } = commonAncestor.type;
    if (!isAnyOfTypes(commonAncestor, [
        (0, utils_1.yfmTableType)(schema),
        (0, utils_1.yfmTableBodyType)(schema),
        (0, utils_1.yfmTableRowType)(schema),
    ]))
        return false;
    const tablePos = findTablePos($from, sharedDepth);
    if (typeof tablePos !== 'number')
        return false;
    const tableNode = $from.doc.nodeAt(tablePos);
    if (!tableNode)
        return false;
    const tableDesc = table_desc_1.TableDesc.create(tableNode)?.bind(tablePos);
    if (!tableDesc)
        return false;
    if (dispatch) {
        const tr = state.tr;
        const cells = (0, lodash_1.range)(0, tableDesc.rows)
            .flatMap((rowIdx) => tableDesc.getPosForRowCells(rowIdx))
            .filter((cell) => cell.type === 'real');
        const isAllSelected = $from.pos <= cells[0].from + 2 && $to.pos >= cells[cells.length - 1].to - 2;
        if (isAllSelected) {
            // all table content is selected, we should remove table
            tr.replaceWith(tablePos, tablePos + tableNode.nodeSize, (0, specs_1.pType)(schema).create());
            tr.setSelection(state_1.TextSelection.create(tr.doc, tablePos + 1));
        }
        else {
            for (const cell of cells) {
                if ($from.pos > cell.to)
                    continue;
                if ($to.pos < cell.from)
                    break;
                const from = Math.max($from.pos, cell.from + 1);
                const to = Math.min($to.pos, cell.to - 1);
                tr.delete(tr.mapping.map(from), tr.mapping.map(to));
                tr.setSelection(state_1.TextSelection.near(tr.doc.resolve(tr.mapping.map(to)), -1));
            }
        }
        dispatch(tr.scrollIntoView());
    }
    return true;
};
exports.clearSelectedCells = clearSelectedCells;
exports.backspaceCommand = (0, commands_1.chainCommands)(removeCellNodeContent, exports.clearSelectedCells);
function isAnyOfTypes(node, types) {
    return types.some((type) => type === node.type);
}
function findTablePos($pos, startDepth) {
    const ASCENTS = 5;
    let depth = startDepth;
    while (depth >= 0 && startDepth - depth <= ASCENTS) {
        const node = $pos.node(depth);
        if ((0, table_utils_1.isTableNode)(node)) {
            return $pos.before(depth);
        }
        depth--;
    }
    return null;
}
//# sourceMappingURL=backspace.js.map
