"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.CellPopupService = void 0;
const tslib_1 = require("tslib");
const SystemRedux = tslib_1.__importStar(require("../../Redux/ActionsReducers/SystemRedux"));
/**
 * This service controls the interaction between notes and comments
 */
class CellPopupService {
    constructor(api) {
        this.api = api;
        this.adaptable = api.internalApi.getAdaptableInstance();
        this.adaptable.api.eventApi.on('AdaptableReady', () => this.handleAdaptableReady());
    }
    destroy() { }
    getAdaptableState() {
        return this.api.internalApi.getAdaptableState();
    }
    dispatchAction(action) {
        this.api.internalApi.dispatchReduxAction(action);
    }
    static isSameAddress(a, b) {
        if (!a || !b) {
            return false;
        }
        if ((a === null || a === void 0 ? void 0 : a.ColumnId) === (b === null || b === void 0 ? void 0 : b.ColumnId) && (a === null || a === void 0 ? void 0 : a.PrimaryKeyValue) === (b === null || b === void 0 ? void 0 : b.PrimaryKeyValue)) {
            return true;
        }
        // Primary keys retreived from the grid dom are always strings, so we must also consider them strings
        if ((typeof a.PrimaryKeyValue === 'number' && typeof b.PrimaryKeyValue === 'string') ||
            (typeof b.PrimaryKeyValue === 'string' && typeof a.PrimaryKeyValue === 'number')) {
            return (a.PrimaryKeyValue.toString() === b.PrimaryKeyValue.toString() && a.ColumnId === b.ColumnId);
        }
        return false;
    }
    handleAdaptableReady() {
        this.adaptable._on('MouseEnter', (event) => this.handleMouseEnter(event));
        this.api.eventApi.on('CellSelectionChanged', (params) => {
            var _a;
            const cells = params.selectedCellInfo.gridCells;
            if ((cells === null || cells === void 0 ? void 0 : cells.length) === 1 && ((_a = cells[0].column) === null || _a === void 0 ? void 0 : _a.columnId) && cells[0].primaryKeyValue) {
                const selectedCell = cells[0];
                const cellSelected = {
                    PrimaryKeyValue: selectedCell.primaryKeyValue,
                    ColumnId: selectedCell.column.columnId,
                };
                this.handleCellSelected(cellSelected);
            }
        });
    }
    getCellPositionFromEvent(event) {
        var _a, _b;
        const target = event.target;
        if (!((_b = (_a = target === null || target === void 0 ? void 0 : target.classList) === null || _a === void 0 ? void 0 : _a.contains) === null || _b === void 0 ? void 0 : _b.call(_a, 'ag-cell'))) {
            return null;
        }
        try {
            const PrimaryKeyValue = target.parentElement.getAttribute('row-id');
            return {
                PrimaryKeyValue,
                ColumnId: target.getAttribute('col-id'),
            };
        }
        catch (e) {
            return null;
        }
    }
    handleMouseEnter(event) {
        const editMode = this.getEditMode();
        if (editMode) {
            // ignore
            return;
        }
        const cellPosition = this.getCellPositionFromEvent(event);
        const openCellAddress = this.getOpenCellAddress();
        // Hovering over someting that is not a cell and there is no open note
        if (!cellPosition && openCellAddress) {
            // need to close if the new cell does not have a note
            this.hidePopup();
            return;
        }
        const cellNote = this.api.noteApi.getNoteForCell(cellPosition);
        const cellComments = this.api.commentApi.getCommentThread(cellPosition);
        const hasNotesOrComments = cellNote || cellComments;
        // call only if it is different
        if (CellPopupService.isSameAddress(openCellAddress, cellPosition)) {
            return;
        }
        if (hasNotesOrComments) {
            this.showPopup(cellPosition, false);
        }
    }
    handleCellSelected(cellAddress) {
        // if already opened - do nothing
        const openCellAddress = this.getOpenCellAddress();
        if (CellPopupService.isSameAddress(openCellAddress, cellAddress)) {
            return;
        }
        // if open but this has no note, close
        const cellNote = this.api.noteApi.getNoteForCell(cellAddress);
        const cellComments = this.api.commentApi.getCommentThread(cellAddress);
        const hasNotesOrComments = cellNote || cellComments;
        if (openCellAddress && !hasNotesOrComments) {
            // hide only if in edit mode
            // because if you select a cell and move the mouse fast over another cell
            // with a note, you do not want to close that note
            // the selection is debounced, so the moment goes over the new cell this event is triggered
            if (this.getEditMode()) {
                this.hidePopup();
            }
            return;
        }
        // if open but the new selection has a note open that one in edit mode (because of click)
        if (openCellAddress && hasNotesOrComments) {
            this.showPopup(cellAddress, true);
            return;
        }
    }
    getOpenCellAddress() {
        return SystemRedux.SystemCommentsAndNotesSelector(this.getAdaptableState().System);
    }
    getEditMode() {
        return SystemRedux.SystemCommentsAndNotesEditModeSelector(this.getAdaptableState().System);
    }
    hidePopup() {
        this.dispatchAction(SystemRedux.SystemCellPopupHide());
    }
    showPopup(cellAddress, editMode) {
        this.dispatchAction(SystemRedux.SystemCellPopupShow(cellAddress, editMode));
    }
    editFocusedEntity(entity) {
        this.dispatchAction(SystemRedux.SystemCellPopupEditFocusedEntity(entity));
    }
    getNotePopupEditMode() {
        return SystemRedux.SystemCommentsAndNotesEditModeSelector(this.getAdaptableState().System);
    }
}
exports.CellPopupService = CellPopupService;
