import { action, computed, makeObservable, observable } from 'mobx';
import { ConditionalModalState, } from '@wix/bex-core';
import { ToolbarCollectionState } from '../ToolbarCollectionState';
import { TableState } from '../TableState';
import { CellInteractionState } from './CellInteractionState';
import { CellValueState } from './CellValueState';
import { ClipboardState } from './ClipboardState';
import { MutationState } from './MutationState';
import { FieldActionsState } from '../FieldActionsState';
export class EditableTableState {
    constructor(params) {
        this.deleteConfirmModal = new ConditionalModalState();
        this.addItemDisabled = false;
        this.updateItemDisabled = false;
        this.removeItemDisabled = false;
        this._allColumns = [];
        this.onAddItemActionComplete = (items) => {
            return this.tableState.onAddItemActionComplete(items);
        };
        this.onAddItemClick = (origin) => {
            this.toolbar.toolbarBIReporter.onAddItemClick(origin);
        };
        this.sort = (columnId, { forceDirection, multiple, } = {}) => {
            this.collection.sort({ id: columnId }, { forceDirection, clearResult: true, multiple });
        };
        this.toolbar =
            params.toolbar ??
                new ToolbarCollectionState({
                    collection: params.collection,
                    container: params.container,
                    componentType: 'EditableTable',
                });
        this.tableState = new TableState({
            collection: params.collection,
            container: params.container,
            toolbar: this.toolbar,
        });
        this.cellValue = new CellValueState(this, new Map(params.extraCellTypes?.map((ct) => [ct.type, ct])));
        this.cellInteraction = new CellInteractionState((editingValue, cell) => {
            this.cellValue.commitHandler(editingValue, cell);
        }, this);
        this.clipboard = new ClipboardState(this);
        this.mutation = new MutationState(this, params.mutations, params.createOptimisticActions);
        this.fieldActions = new FieldActionsState(params.collection.translate, params.fieldActions, params.permissions?.fieldActions, params.collection.showToast, params.refresh);
        makeObservable(this, {
            addItemDisabled: observable,
            updateItemDisabled: observable,
            removeItemDisabled: observable,
            _allColumns: observable.ref,
            editableColumns: computed,
            _columnMap: computed,
            init: action,
            confirmDeleteItems: action,
        });
        if (params.permissions) {
            this.addItemDisabled = params.permissions.addItemDisabled ?? false;
            this.updateItemDisabled = params.permissions.updateItemDisabled ?? false;
            this.removeItemDisabled = params.permissions.removeItemDisabled ?? false;
        }
    }
    get collection() {
        return this.tableState.collection;
    }
    get keyedItems() {
        return this.tableState.keyedItems;
    }
    get visibleColumns() {
        return this.tableState.visibleColumns;
    }
    get itemsToRenderCount() {
        return this.tableState.itemsToRenderCount;
    }
    get _columnMap() {
        return new Map(this._allColumns.map((c) => [c.id, c]));
    }
    _getKeyedItem(key) {
        return this.collection.getKeyedItem(key);
    }
    _toIndices(pos) {
        const row = this.keyedItems.findIndex((ki) => ki.key === pos.rowKey);
        const col = this.editableColumns.findIndex((c) => c.id === pos.columnId);
        return row === -1 || col === -1 ? null : { row, col };
    }
    _toPosition(row, col) {
        const ki = this.keyedItems[row];
        const c = this.editableColumns[col];
        return ki && c ? { rowKey: ki.key, columnId: c.id } : null;
    }
    get editableColumns() {
        const visibleIds = this.visibleColumns.map((c) => c.id);
        if (!visibleIds.length) {
            return this._allColumns;
        }
        return visibleIds
            .map((id) => this._allColumns.find((c) => c.id === id))
            .filter((c) => c !== undefined);
    }
    init(columns) {
        this._allColumns = columns;
        this.cellValue._buildCellTypeMap();
        return this.mutation.init();
    }
    addItem(afterItemKey) {
        return this.mutation.addItem(afterItemKey);
    }
    duplicateItem(rowKey) {
        this.mutation.duplicateItem(rowKey);
    }
    deleteItems(rowKeys) {
        this.mutation.deleteItems(rowKeys);
    }
    confirmDeleteItems(rowKeys) {
        const { translate: t } = this.collection;
        this.deleteConfirmModal.open({
            theme: 'destructive',
            title: t('cairo.deleteModal.title'),
            content: t('cairo.deleteModal.body'),
            primaryButtonText: t('cairo.delete.button'),
            secondaryButtonText: t('cairo.cancel.button'),
            primaryButtonOnClick: () => {
                this.deleteItems(rowKeys);
            },
        });
    }
    resolveCellTypeByColumnId(columnId) {
        return this.cellValue.resolveCellTypeByColumnId(columnId);
    }
    getCellDisplayValue(rowKey, columnId) {
        return this.cellValue.getCellDisplayValue(rowKey, columnId);
    }
    getCellValidation(rowKey, columnId) {
        return this.cellValue.getCellValidation(rowKey, columnId);
    }
    isCellEditable(rowKey, columnId) {
        return this.cellValue.isCellEditable(rowKey, columnId);
    }
    clearCells(cells) {
        this.cellValue.clearCells(cells);
    }
    handleCellClick(rowKey, columnId, shiftKey) {
        if (this.cellInteraction.isEditing) {
            if (this.cellInteraction.isCellEditing(rowKey, columnId)) {
                // Click landed inside the active editor — let the editor handle it.
                return;
            }
            // Shift-click while editing: ignore — extending a range selection during
            // an active edit is not a meaningful action.
            if (shiftKey) {
                return;
            }
            // Plain click on a different cell: commit the edit and move focus.
            this.cellInteraction.commitEdit();
            // If the target cell wants edit-on-click, enter edit directly.
            const col = this._columnMap.get(columnId);
            const res = col ? this.resolveCellTypeByColumnId(col.id) : null;
            if (res?.editOnClick) {
                const val = this.getCellDisplayValue(rowKey, columnId);
                if (res.editOnClick(val) && this.isCellEditable(rowKey, columnId)) {
                    this.cellInteraction.focusCell(rowKey, columnId);
                    this.cellInteraction.startEdit(rowKey, columnId, 'click');
                    return;
                }
            }
            this.cellInteraction.focusCell(rowKey, columnId);
            return;
        }
        const column = this._columnMap.get(columnId);
        const resolved = column ? this.resolveCellTypeByColumnId(column.id) : null;
        if (resolved?.toggleValue || resolved?.showEditWhenFocused) {
            // Toggle/showEditWhenFocused cells: click focuses the cell and shows the
            // EditComponent affordance. Keyboard navigation remains active.
            this.cellInteraction.focusCell(rowKey, columnId);
            return;
        }
        if (resolved?.editOnClick) {
            const value = this.getCellDisplayValue(rowKey, columnId);
            if (resolved.editOnClick(value) &&
                this.isCellEditable(rowKey, columnId)) {
                this.cellInteraction.focusCell(rowKey, columnId);
                this.cellInteraction.startEdit(rowKey, columnId, 'click');
                return;
            }
        }
        if (shiftKey && this.cellInteraction.selectionAnchor) {
            this.cellInteraction.selectRange(this.cellInteraction.selectionAnchor, {
                rowKey,
                columnId,
            });
        }
        else {
            this.cellInteraction.focusCell(rowKey, columnId);
        }
    }
    handleCellDoubleClick(rowKey, columnId) {
        if (this.updateItemDisabled) {
            return;
        }
        const column = this._columnMap.get(columnId);
        const resolved = column ? this.resolveCellTypeByColumnId(column.id) : null;
        // Toggle-value cells (e.g. boolean) activate on single click, not double-click.
        // Entering edit mode on double-click would apply the editing box-shadow
        // without any EditComponent being shown, causing a visual border glitch.
        if (resolved?.toggleValue || resolved?.showEditWhenFocused) {
            return;
        }
        if (this.isCellEditable(rowKey, columnId)) {
            this.cellInteraction.startEdit(rowKey, columnId, 'doubleClick');
        }
    }
}
//# sourceMappingURL=EditableTableState.js.map