import { PointRange } from './point-range.js';
import { get, set, split, getSize, unset, pad, entries, has } from './matrix.js';
import { ORIGIN } from './point.js';
import { EmptySelection, RangeSelection, EntireWorksheetSelection, EntireColumnsSelection, EntireRowsSelection } from './selection.js';
import { EmptyCell, isPasteAllowed, isActive, deleteColumnDimension, deleteRowDimension } from './util.js';
import { COMMIT, DRAG_END, ON_MOUSE_UP, DRAG_START, SET_COLUMN_POSITION, SET_COLUMN_WIDTH, SET_ROW_HEIGHT, KEY_DOWN, KEY_PRESS, BLUR, CLEAR, VIEW, EDIT, PASTE, CUT, COPY, SET_CELL_DIMENSIONS, SET_CELL_DATA, ACTIVATE, SELECT, SET_SELECTION, SELECT_ENTIRE_WORKSHEET, SELECT_ENTIRE_COLUMN, SELECT_ENTIRE_ROW, SET_CREATE_FORMULA_PARSER, SET_DATA, FORMATE_PAINTER, BACKGROUND_COLOR, COLOR, TEXT_ALIGN, FONT_FAMILY, FONT_SIZE, UNDERLINE_TYPE, BORDER_TYPE, ITALIC, BOLD, DELETE_COLUMN, DELETE_ROW, ADD_COLUMN_RIGHT, ADD_COLUMN_LEFT, ADD_ROW_BOTTOM, ADD_ROW_TOP, SET_AUTO_FILL, SET_EDITABLE, UPDATE_COLUMN_DIMENSIONS } from './actions.js';
import { Model, updateCellValue } from './engine/engine.js';
import { createFormulaParser } from './engine/formula.js';
import { commit, dragEndFormatePainter, dragEndAutoFill, cellFormatePainter, isActiveReadOnly, getKeyDownHandler, edit, clear, blur, view, applyFormatePainter, applyBackgroundColorToCells, applyColorToCells, applyTextAlign, applyFontFamily, applyFontSize, applyUnderlineToCells, applyBorderToCells, applyItalicToCells, applyBoldToCells, handleAddColumn, handleAddRow } from './reducerFunctions.js';
import { checkEmpty } from '../../../../utils/checkEmpty/checkEmpty.js';

const INITIAL_STATE = {
    active: null,
    mode: 'view',
    rowDimensions: {},
    columnDimensions: {},
    lastChanged: null,
    hasPasted: false,
    cut: false,
    autoFill: { open: false, cellValue: { value: '', style: {} } },
    dragging: false,
    model: new Model(createFormulaParser, []),
    selected: new EmptySelection(),
    copied: null,
    lastCommit: null,
    selectedColumn: null,
    selectedRow: null,
    formattedStyle: { open: false, style: undefined },
    editable: false,
    ctrl: true,
};
function reducer(state, action) {
    switch (action.type) {
        case UPDATE_COLUMN_DIMENSIONS: {
            const { minimumColumnWidth } = action.payload;
            const newColumnDimensions = { ...state.columnDimensions };
            Object.keys(newColumnDimensions).forEach((colKey) => {
                const colIndex = parseInt(colKey);
                const currentWidth = newColumnDimensions[colIndex]?.width || 0;
                // Only apply minimumColumnWidth if the column has no saved width (i.e. equals the default).
                // This prevents overwriting widths that were restored from cell.style.width on initial load.
                if (currentWidth !== minimumColumnWidth) {
                    newColumnDimensions[colIndex] = {
                        left: newColumnDimensions[colIndex]?.left || 0,
                        width: minimumColumnWidth,
                    };
                }
            });
            return {
                ...state,
                columnDimensions: newColumnDimensions,
            };
        }
        case SET_EDITABLE: {
            const { editable } = action.payload;
            return {
                ...state,
                editable: editable,
            };
        }
        case SET_AUTO_FILL: {
            const { autofill } = action.payload;
            const activeCell = state.active;
            let currentCell = EmptyCell;
            if (activeCell) {
                currentCell =
                    get({ row: activeCell.row, column: activeCell.column }, state.model.data) || currentCell;
            }
            return {
                ...state,
                autoFill: { open: autofill, cellValue: currentCell },
            };
        }
        case ADD_ROW_TOP:
            return handleAddRow(state, action, 'TOP');
        case ADD_ROW_BOTTOM:
            return handleAddRow(state, action, 'BOTTOM');
        case ADD_COLUMN_LEFT:
            return handleAddColumn(state, action, 'LEFT');
        case ADD_COLUMN_RIGHT:
            return handleAddColumn(state, action, 'RIGHT');
        case DELETE_ROW: {
            let { selectedRow, selectedColumn, model, rowDimensions, copied } = state;
            const { row } = action;
            if (checkEmpty(selectedRow))
                return state;
            const deleteIndex = row ?? selectedRow;
            let updatedData = [...model.data];
            updatedData.splice(deleteIndex, 1);
            const updatedModel = new Model(model.createFormulaParser, updatedData);
            let newSelectedRow = deleteIndex > 0 ? deleteIndex - 1 : 0;
            const newSelectedColumn = selectedColumn !== null ? selectedColumn : 0;
            const newActive = updatedData.length > 0
                ? { row: newSelectedRow, column: newSelectedColumn }
                : null;
            const newSelected = updatedData.length > 0
                ? new EntireRowsSelection(newSelectedRow, newSelectedRow)
                : new EmptySelection();
            let newCopied = copied;
            if (copied && copied.start.row <= deleteIndex && copied.end.row >= deleteIndex) {
                newCopied = null;
            }
            return {
                ...state,
                model: updatedModel,
                selectedRow: newSelectedRow,
                selectedColumn: newSelectedColumn,
                selected: newSelected,
                active: newActive,
                copied: newCopied,
                rowDimensions: deleteRowDimension(rowDimensions, deleteIndex),
            };
        }
        case DELETE_COLUMN: {
            const { selectedRow, selectedColumn, model, columnDimensions, copied } = state;
            const { column } = action;
            if (checkEmpty(column ?? selectedColumn))
                return state;
            const deleteIndex = column ?? selectedColumn;
            const updatedData = model.data.map((row) => row.filter((_, cellIndex) => cellIndex !== deleteIndex));
            const updatedModel = new Model(model.createFormulaParser, updatedData);
            const newSelectedRow = selectedRow !== null ? selectedRow : 0;
            const newSelectedColumn = deleteIndex > 0 ? deleteIndex - 1 : 0;
            const newActive = updatedData.length > 0
                ? { row: newSelectedRow, column: newSelectedColumn }
                : null;
            const newSelected = updatedData.length > 0
                ? new EntireColumnsSelection(newSelectedColumn, newSelectedColumn)
                : new EmptySelection();
            let newCopied = copied;
            if (copied && copied.start.column <= deleteIndex && copied.end.column >= deleteIndex) {
                newCopied = null;
            }
            return {
                ...state,
                model: updatedModel,
                selectedRow: newSelectedRow,
                selectedColumn: newSelectedColumn,
                selected: newSelected,
                active: newActive,
                copied: newCopied,
                columnDimensions: deleteColumnDimension(columnDimensions, deleteIndex),
            };
        }
        case BOLD: {
            const selectedRange = state.selected.toRange(state.model.data);
            const updatedData = applyBoldToCells(state.model.data, selectedRange, state.editable);
            return {
                ...state,
                model: new Model(state.model.createFormulaParser, updatedData),
            };
        }
        case ITALIC: {
            const selectedRange = state.selected.toRange(state.model.data);
            const updatedData = applyItalicToCells(state.model.data, selectedRange, state.editable);
            return {
                ...state,
                model: new Model(state.model.createFormulaParser, updatedData),
            };
        }
        case BORDER_TYPE: {
            const { value, color } = action.payload;
            const selectedRange = state.selected.toRange(state.model.data);
            const updatedData = applyBorderToCells(state.model.data, selectedRange, value, color, state.editable);
            return {
                ...state,
                model: new Model(state.model.createFormulaParser, updatedData),
            };
        }
        case UNDERLINE_TYPE: {
            const selectedRange = state.selected.toRange(state.model.data);
            const updatedData = applyUnderlineToCells(state.model.data, selectedRange, state.editable);
            return {
                ...state,
                model: new Model(state.model.createFormulaParser, updatedData),
            };
        }
        case FONT_SIZE: {
            const { value } = action.payload;
            const selectedRange = state.selected.toRange(state.model.data);
            const updatedData = applyFontSize(state.model.data, selectedRange, value, state.editable);
            const updatedModel = new Model(state.model.createFormulaParser, updatedData);
            let newRowDimensions = { ...state.rowDimensions };
            // If single active cell, update only that row
            if (state.active && state.mode !== 'edit') {
                const rowIndex = state.active.row;
                const rowData = updatedData[rowIndex];
                if (rowData) {
                    let maxHeight = 32;
                    rowData.forEach((cell) => {
                        if (!cell)
                            return;
                        const fontSize = cell.style?.fontSize
                            ? parseInt(cell.style.fontSize.toString().replace('px', ''))
                            : 9;
                        const lineHeight = Math.max(fontSize * 1.2, 18);
                        const lines = (!['file', 'dropDown'].includes(cell?.inputType?.type ?? '')
                            ? String(cell.value).split(' ').length
                            : 0) +
                            (String(cell.value).split('\n').length - 1);
                        maxHeight = Math.max(maxHeight, lineHeight * lines);
                    });
                    newRowDimensions[rowIndex] = {
                        ...(newRowDimensions[rowIndex] || { top: 0, height: 32 }),
                        height: maxHeight,
                    };
                }
            }
            // Else bulk update rows (your existing behavior)
            else if (selectedRange) {
                for (let rowIndex = selectedRange.start.row; rowIndex <= selectedRange.end.row; rowIndex++) {
                    const rowData = updatedData[rowIndex];
                    if (!rowData)
                        continue;
                    let maxHeight = 32;
                    rowData.forEach((cell) => {
                        if (!cell)
                            return;
                        const fontSize = cell.style?.fontSize
                            ? parseInt(cell.style.fontSize.toString().replace('px', ''))
                            : 9;
                        const lineHeight = Math.max(fontSize * 1.2, 18);
                        const lines = (!['file', 'dropDown'].includes(cell?.inputType?.type ?? '')
                            ? String(cell.value).split(' ').length
                            : 0) +
                            (String(cell.value).split('\n').length - 1);
                        maxHeight = Math.max(maxHeight, lineHeight * lines);
                    });
                    newRowDimensions[rowIndex] = {
                        ...(newRowDimensions[rowIndex] || { top: 0, height: 32 }),
                        height: maxHeight,
                    };
                }
            }
            return {
                ...state,
                model: updatedModel,
                rowDimensions: newRowDimensions,
            };
        }
        case FONT_FAMILY: {
            const { value } = action.payload;
            const selectedRange = state.selected.toRange(state.model.data);
            const updatedData = applyFontFamily(state.model.data, selectedRange, value, state.editable);
            return {
                ...state,
                model: new Model(state.model.createFormulaParser, updatedData),
            };
        }
        case TEXT_ALIGN: {
            const { value } = action.payload;
            const selectedRange = state.selected.toRange(state.model.data);
            const updatedData = applyTextAlign(state.model.data, selectedRange, value, state.editable);
            return {
                ...state,
                model: new Model(state.model.createFormulaParser, updatedData),
            };
        }
        case COLOR: {
            const { value } = action.payload;
            const selectedRange = state.selected.toRange(state.model.data);
            const updatedData = applyColorToCells(state.model.data, selectedRange, value, state.editable);
            return {
                ...state,
                model: new Model(state.model.createFormulaParser, updatedData),
            };
        }
        case BACKGROUND_COLOR: {
            const { value } = action.payload;
            const selectedRange = state.selected.toRange(state.model.data);
            const updatedData = applyBackgroundColorToCells(state.model.data, selectedRange, value, state.editable);
            return {
                ...state,
                model: new Model(state.model.createFormulaParser, updatedData),
            };
        }
        case FORMATE_PAINTER: {
            if (!state.editable) {
                return state;
            }
            const copiedStyle = applyFormatePainter(state.model.data, state.active);
            const selectedRange = state.selected.toRange(state.model.data);
            if (state.formattedStyle.open) {
                return {
                    ...state,
                    selected: new EmptySelection(),
                    active: state.copied?.start || null,
                    copied: null,
                    formattedStyle: { open: false, style: undefined },
                };
            }
            else {
                return {
                    ...state,
                    selected: new EmptySelection(),
                    active: null,
                    copied: selectedRange,
                    formattedStyle: { open: true, style: copiedStyle },
                };
            }
        }
        case SET_DATA: {
            const { data } = action.payload;
            const nextActive = state.active && has(state.active, data) ? state.active : null;
            const nextSelected = state.selected.normalizeTo(data);
            return {
                ...state,
                model: new Model(state.model.createFormulaParser, data),
                active: nextActive,
                selected: nextSelected,
            };
        }
        case SET_CREATE_FORMULA_PARSER: {
            const { createFormulaParser } = action.payload;
            return {
                ...state,
                model: new Model(createFormulaParser, state.model.data),
            };
        }
        case SELECT_ENTIRE_ROW: {
            const { row, extend } = action.payload;
            const { active } = state;
            const newSelected = extend && active
                ? new EntireRowsSelection(active.row, row)
                : new EntireRowsSelection(row, row);
            const newActive = extend && active
                ? active
                : { ...ORIGIN, row };
            return {
                ...state,
                selected: newSelected,
                active: newActive,
                mode: 'view',
                selectedColumn: null,
                selectedRow: row,
            };
        }
        case SELECT_ENTIRE_COLUMN: {
            const { column, extend } = action.payload;
            const { active } = state;
            const newSelected = extend && active
                ? new EntireColumnsSelection(active.column, column)
                : new EntireColumnsSelection(column, column);
            const newActive = extend && active
                ? active
                : { ...ORIGIN, column };
            return {
                ...state,
                selected: newSelected,
                active: newActive,
                mode: 'view',
                selectedColumn: column,
                selectedRow: null,
            };
        }
        case SELECT_ENTIRE_WORKSHEET: {
            return {
                ...state,
                selected: new EntireWorksheetSelection(),
                active: ORIGIN,
                mode: 'view',
            };
        }
        case SET_SELECTION: {
            const { selection } = action.payload;
            const range = selection.toRange(state.model.data);
            const active = state.active && selection.has(state.model.data, state.active)
                ? state.active
                : range?.start;
            return {
                ...state,
                selected: selection,
                active: active || null,
                mode: 'view',
            };
        }
        case SELECT: {
            const { point } = action.payload;
            if (state.active && !isActive(state.active, point)) {
                return {
                    ...state,
                    selected: new RangeSelection(new PointRange(point, state.active)),
                    mode: 'view',
                };
            }
            return state;
        }
        case ACTIVATE: {
            const { point } = action.payload;
            return {
                ...state,
                selected: new RangeSelection(new PointRange(point, point)),
                active: point,
                mode: (isActive(state.active, point) && state.editable) ? 'edit' : 'view',
            };
        }
        case SET_CELL_DATA: {
            const { active, data: cellData } = action.payload;
            if (isActiveReadOnly(state) || !state.editable) {
                return state;
            }
            return {
                ...state,
                model: updateCellValue(state.model, active, cellData),
                lastChanged: active,
            };
        }
        case SET_CELL_DIMENSIONS: {
            const { point, dimensions } = action.payload;
            const prevRowDimensions = state.rowDimensions[point.row];
            const prevColumnDimensions = state.columnDimensions[point.column];
            if (prevRowDimensions &&
                prevColumnDimensions &&
                prevRowDimensions.top === dimensions.top &&
                prevRowDimensions.height === dimensions.height &&
                prevColumnDimensions.left === dimensions.left &&
                prevColumnDimensions.width === dimensions.width) {
                return state;
            }
            return {
                ...state,
                rowDimensions: {
                    ...state.rowDimensions,
                    [point.row]: { top: dimensions.top, height: dimensions.height },
                },
                columnDimensions: {
                    ...state.columnDimensions,
                    [point.column]: { left: dimensions.left, width: dimensions.width },
                },
            };
        }
        case COPY:
        case CUT: {
            const selectedRange = state.selected.toRange(state.model.data);
            return {
                ...state,
                copied: selectedRange,
                cut: action.type === CUT,
                hasPasted: false,
            };
        }
        case PASTE: {
            const { data: text } = action.payload;
            const { active } = state;
            if (!active || !state.editable) {
                return state;
            }
            const copied = split(text, (value) => ({ value }));
            const copiedSize = getSize(copied);
            const selectedRange = state.selected.toRange(state.model.data);
            // Check if paste destination overlaps with cut source
            let pasteRange = null;
            if (state.cut && state.copied) {
                pasteRange = new PointRange(active, {
                    row: active.row + copiedSize.rows - 1,
                    column: active.column + copiedSize.columns - 1,
                });
            }
            // Helper to check if a point is within the paste range (for cut overlap detection)
            const isInPasteRange = (point) => {
                if (!pasteRange)
                    return false;
                return (point.row >= pasteRange.start.row &&
                    point.row <= pasteRange.end.row &&
                    point.column >= pasteRange.start.column &&
                    point.column <= pasteRange.end.column);
            };
            if (selectedRange && copiedSize.rows === 1 && copiedSize.columns === 1) {
                const cell = get({ row: 0, column: 0 }, copied);
                let newData = state.model.data;
                // Only unset cut cells if they don't overlap with paste destination
                if (state.cut && state.copied) {
                    for (const point of state.copied) {
                        if (!isInPasteRange(point)) {
                            newData = unset(point, newData);
                        }
                    }
                }
                const commit = [];
                for (const point of selectedRange || []) {
                    const currentCell = get(point, state.model.data) || null;
                    const updateWithStyle = { ...currentCell, value: cell?.value };
                    commit.push({
                        prevCell: currentCell || EmptyCell,
                        nextCell: EmptyCell,
                    });
                    if (isPasteAllowed(currentCell)) {
                        newData = set(point, updateWithStyle, newData);
                    }
                }
                return {
                    ...state,
                    model: new Model(createFormulaParser, newData),
                    copied: null,
                    cut: false,
                    hasPasted: true,
                    mode: 'view',
                    lastCommit: commit,
                };
            }
            const requiredSize = {
                rows: active.row + copiedSize.rows,
                columns: active.column + copiedSize.columns,
            };
            const paddedData = pad(state.model.data, requiredSize);
            let acc = { data: paddedData, commit: [] };
            for (const [point, cell] of entries(copied)) {
                let commit = acc.commit || [];
                const nextPoint = {
                    row: point.row + active.row,
                    column: point.column + active.column,
                };
                let nextData = acc.data;
                if (state.cut && state.copied) {
                    const prevPoint = {
                        row: point.row + state.copied.start.row,
                        column: point.column + state.copied.start.column,
                    };
                    // Only unset if the source cell is not within the paste destination
                    if (!isInPasteRange(prevPoint)) {
                        nextData = unset(prevPoint, acc.data);
                    }
                    commit = [...commit, { prevCell: cell || null, nextCell: null }];
                }
                if (!has(nextPoint, paddedData)) {
                    acc = { data: nextData, commit };
                }
                const currentCell = get(nextPoint, nextData) || null;
                commit = [
                    ...commit,
                    {
                        prevCell: currentCell,
                        nextCell: cell || null,
                    },
                ];
                if (isPasteAllowed(currentCell)) {
                    acc.data = set(nextPoint, { ...currentCell, value: cell?.value ?? '' }, nextData);
                    acc.commit = commit;
                }
            }
            return {
                ...state,
                model: new Model(createFormulaParser, acc.data),
                selected: new RangeSelection(new PointRange(active, {
                    row: active.row + copiedSize.rows - 1,
                    column: active.column + copiedSize.columns - 1,
                })),
                copied: null,
                cut: false,
                hasPasted: true,
                mode: 'view',
                lastCommit: acc.commit,
            };
        }
        case EDIT: {
            return edit(state);
        }
        case VIEW: {
            return view(state);
        }
        case CLEAR: {
            return clear(state);
        }
        case BLUR: {
            return blur(state);
        }
        case KEY_PRESS: {
            const { event } = action.payload;
            if (isActiveReadOnly(state) || event.metaKey || !state.editable) {
                return state;
            }
            if (state.mode === 'view' && state.active) {
                const selectedRange = state.selected.toRange(state.model.data);
                if (selectedRange?.size() === 1) {
                    return edit(clear(state));
                }
                return edit(state);
            }
            return state;
        }
        case KEY_DOWN: {
            const { event } = action.payload;
            if (event.ctrlKey) {
                return { ...state, ctrl: !state.ctrl };
            }
            if (isActiveReadOnly(state) || event.metaKey || !state.editable) {
                return state;
            }
            const handler = getKeyDownHandler(state, event);
            if (handler) {
                return { ...state, ...handler(state, event) };
            }
            return state;
        }
        case SET_ROW_HEIGHT: {
            const { row, height } = action.payload;
            const prevDimensions = state.rowDimensions[row] || { top: 0};
            let updatedData = state.model.data; // Start with original data
            // Update all cells in the row with style.height
            if (updatedData[row]) { // Check if row exists
                const len = updatedData?.[row]?.length;
                for (let col = 0; col < len; col++) {
                    const point = { row, column: col };
                    const cell = get(point, updatedData) || EmptyCell;
                    const newCell = {
                        ...cell,
                        style: {
                            ...cell.style,
                            height, // Set the new height in cell style
                        },
                    };
                    updatedData = set(point, newCell, updatedData); // Immutable set
                }
            }
            const updatedModel = new Model(state.model.createFormulaParser, updatedData);
            return {
                ...state,
                rowDimensions: {
                    ...state.rowDimensions,
                    [row]: {
                        top: prevDimensions.top,
                        height,
                    },
                },
                model: updatedModel,
            };
        }
        case SET_COLUMN_WIDTH: {
            const { column, width } = action.payload;
            const prevDimensions = state.columnDimensions[column] || { left: 0};
            // Narrow first
            if (!state.model.data) {
                return {
                    ...state,
                    columnDimensions: {
                        ...state.columnDimensions,
                        [column]: {
                            left: prevDimensions.left,
                            width,
                        },
                    },
                };
            }
            let updatedData = state.model.data ?? [];
            for (let r = 0; r < updatedData.length; r++) {
                if (updatedData[r] && updatedData?.[r]?.length > column) {
                    const point = { row: r, column };
                    const cell = get(point, updatedData) ?? EmptyCell;
                    const newCell = {
                        ...cell,
                        style: {
                            ...(cell.style ?? {}),
                            width,
                        },
                    };
                    updatedData = set(point, newCell, updatedData);
                }
            }
            const updatedModel = new Model(state.model.createFormulaParser, updatedData);
            return {
                ...state,
                columnDimensions: {
                    ...state.columnDimensions,
                    [column]: {
                        left: prevDimensions.left,
                        width,
                    },
                },
                model: updatedModel,
            };
        }
        case SET_COLUMN_POSITION: {
            const { column, width } = action.payload;
            const prevDimensions = state.columnDimensions[column] || {
                left: 0};
            return {
                ...state,
                columnDimensions: {
                    ...state.columnDimensions,
                    [column]: {
                        left: prevDimensions.left,
                        width,
                    },
                },
            };
        }
        case DRAG_START: {
            return { ...state, dragging: true };
        }
        case ON_MOUSE_UP: {
            const { point } = action.payload;
            let updatedData = state.model.data;
            if (!state.dragging && state.formattedStyle.open) {
                updatedData = cellFormatePainter(state.model.data, state.formattedStyle, state.active);
            }
            return {
                ...state,
                copied: null,
                model: new Model(state.model.createFormulaParser, updatedData),
                formattedStyle: { open: false, style: undefined },
                active: point,
            };
        }
        case DRAG_END: {
            const selectedRange = state.selected.toRange(state.model.data);
            const activeCell = state.active;
            let updatedData = state.model.data;
            if (state.formattedStyle.open) {
                updatedData = dragEndFormatePainter(state.model.data, selectedRange, state.formattedStyle);
            }
            if (state.autoFill.open && state.editable && selectedRange) {
                updatedData = dragEndAutoFill(state.model.data, selectedRange, state.autoFill.cellValue, activeCell, state.ctrl);
                let { start, end } = selectedRange;
                const rowCount = start.row - end.row;
                const columnCount = start.column - end.column;
                let startPoint = { row: 0, column: 0 };
                let endPoint = { row: 0, column: 0 };
                if (Math.abs(rowCount) > Math.abs(columnCount)) {
                    startPoint = { row: Math.min(start.row, end.row), column: activeCell?.column ?? 0 };
                    endPoint = { row: Math.max(start.row, end.row), column: activeCell?.column ?? 0 };
                }
                else {
                    startPoint = { row: activeCell?.row ?? 0, column: Math.min(start.column, end.column) };
                    endPoint = { row: activeCell?.row ?? 0, column: Math.max(start.column, end.column) };
                }
                return {
                    ...state,
                    dragging: false,
                    autoFill: { open: false, cellValue: { value: '', style: {} } },
                    formattedStyle: { open: false, style: undefined },
                    model: new Model(state.model.createFormulaParser, updatedData),
                    selected: new RangeSelection(new PointRange(startPoint, endPoint)),
                };
            }
            return {
                ...state,
                dragging: false,
                autoFill: { open: false, cellValue: { value: '', style: {} } },
                formattedStyle: { open: false, style: undefined },
                model: new Model(state.model.createFormulaParser, updatedData),
            };
        }
        case COMMIT: {
            const { changes } = action.payload;
            return { ...state, ...commit(changes) };
        }
        default:
            throw new Error('Unknown action');
    }
}
// const reducer = createReducer(INITIAL_STATE, (builder) => {
//   builder.addMatcher(
//     (action) =>
//       action.type === Actions.copy.type || action.type === Actions.cut.type,
//     (state, action) => {
//     }
//   );
// });
// // Shared reducers

export { INITIAL_STATE, reducer as default };
//# sourceMappingURL=reducer.js.map
