"use strict";

Object.defineProperty(exports, "__esModule", {
    value: !0
}), exports.FormulaUIManager = void 0;

const formula_helper_1 = require("./formula-helper");

class FormulaUIManager {
    constructor(sheet) {
        this.formulaBarElement = null, this.formulaInput = null, this.isFormulaBarShowingResult = !1, 
        this.isEnterKeyPressed = !1, this.sheet = sheet;
    }
    createFormulaBar() {
        const formulaBar = document.createElement("div");
        formulaBar.className = "vtable-sheet-formula-bar";
        const cellAddressBox = document.createElement("div");
        cellAddressBox.className = "vtable-sheet-cell-address", cellAddressBox.textContent = "", 
        formulaBar.appendChild(cellAddressBox);
        const formulaIcon = document.createElement("div");
        formulaIcon.className = "vtable-sheet-formula-icon", formulaIcon.textContent = "fx", 
        formulaIcon.title = "插入函数", formulaBar.appendChild(formulaIcon);
        const formulaInput = document.createElement("input");
        this.formulaInput = formulaInput, formulaInput.className = "vtable-sheet-formula-input", 
        formulaInput.placeholder = "输入公式...";
        [ "click", "mouseup", "keyup", "select", "input", "focus" ].forEach((eventType => {
            formulaInput.addEventListener(eventType, (e => {
                const cursorPos = formulaInput.selectionStart;
                null != cursorPos && (this.sheet.formulaManager.lastKnownCursorPosInFormulaInput = cursorPos, 
                this.sheet.formulaManager.inputingElement = formulaInput);
            }));
        })), formulaInput.addEventListener("input", (e => this.handleFormulaInput(e))), 
        formulaInput.addEventListener("keydown", (e => this.handleFormulaKeydown(e))), formulaInput.addEventListener("focus", (() => {
            this.activateFormulaBar();
            const activeWorkSheet = this.sheet.getActiveSheet();
            if (activeWorkSheet) {
                const editingCell = activeWorkSheet.editingCell;
                if (editingCell && !this.sheet.formulaManager.formulaWorkingOnCell) {
                    const formula = this.sheet.formulaManager.getCellFormula({
                        sheet: editingCell.sheet,
                        row: editingCell.row,
                        col: editingCell.col
                    });
                    if (formula) {
                        this.sheet.formulaManager.formulaWorkingOnCell = editingCell;
                        const displayFormula = formula.startsWith("=") ? formula : `=${formula}`;
                        formulaInput.value = displayFormula, this.sheet.formulaManager.cellHighlightManager.highlightFormulaCells(displayFormula), 
                        this.sheet.formulaManager.inputIsParamMode = (0, formula_helper_1.detectFunctionParameterPosition)(formulaInput.value, this.sheet.formulaManager.lastKnownCursorPosInFormulaInput);
                    }
                }
            }
        })), formulaInput.addEventListener("blur", (() => {
            var _a;
            if (this.sheet.formulaManager.formulaWorkingOnCell) return;
            this.deactivateFormulaBar(), this.sheet.formulaManager.cellHighlightManager.clearHighlights();
            const activeWorkSheet = this.sheet.getActiveSheet();
            if (activeWorkSheet) {
                const selection = activeWorkSheet.getSelection();
                if (selection) {
                    const result = this.sheet.formulaManager.getCellValue({
                        sheet: activeWorkSheet.getKey(),
                        row: selection.startRow,
                        col: selection.startCol
                    });
                    null === (_a = activeWorkSheet.tableInstance) || void 0 === _a || _a.changeCellValue(selection.startCol, selection.startRow, result.error ? "#ERROR!" : result.value);
                }
            }
        })), formulaBar.appendChild(formulaInput);
        const formulaActions = document.createElement("div");
        formulaActions.className = "vtable-sheet-formula-actions";
        const cancelButton = document.createElement("button");
        cancelButton.className = "vtable-sheet-formula-button vtable-sheet-formula-cancel", 
        cancelButton.innerHTML = '<svg viewBox="0 0 24 24" width="16" height="16"><path fill="currentColor" d="M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z"/></svg>', 
        cancelButton.title = "取消", cancelButton.addEventListener("click", (() => this.cancelFormulaEdit())), 
        formulaActions.appendChild(cancelButton);
        const confirmButton = document.createElement("button");
        return confirmButton.className = "vtable-sheet-formula-button vtable-sheet-formula-confirm", 
        confirmButton.innerHTML = '<svg viewBox="0 0 24 24" width="16" height="16"><path fill="currentColor" d="M9 16.17L4.83 12l-1.42 1.41L9 19 21 7l-1.41-1.41z"/></svg>', 
        confirmButton.title = "确认", confirmButton.addEventListener("click", (() => this.confirmFormulaEdit())), 
        formulaActions.appendChild(confirmButton), formulaBar.appendChild(formulaActions), 
        this.formulaBarElement = formulaBar, formulaBar;
    }
    activateFormulaBar() {
        const formulaBar = this.formulaBarElement;
        formulaBar && formulaBar.classList.add("active");
    }
    deactivateFormulaBar() {
        const formulaBar = this.formulaBarElement;
        formulaBar && formulaBar.classList.remove("active"), this.sheet.formulaManager.cellHighlightManager.clearHighlights();
    }
    cancelFormulaEdit() {
        this.formulaInput && this.updateFormulaBar();
    }
    confirmFormulaEdit() {
        var _a;
        const formulaInput = this.formulaInput, activeWorkSheet = this.sheet.getActiveSheet();
        if (formulaInput && activeWorkSheet) {
            const selection = activeWorkSheet.editingCell;
            if (!selection) return;
            const value = formulaInput.value;
            if (value.startsWith("=") && value.length > 1) try {
                const currentCellAddress = activeWorkSheet.addressFromCoord(selection.row, selection.col);
                if (new RegExp(`(^|[^A-Za-z0-9])${currentCellAddress}([^A-Za-z0-9]|$)`).test(value)) return activeWorkSheet.setCellValue(selection.row, selection.col, "#CYCLE!"), 
                null === (_a = activeWorkSheet.tableInstance) || void 0 === _a || _a.changeCellValue(selection.col, selection.row, "#CYCLE!"), 
                formulaInput.value = "", void formulaInput.blur();
                this.sheet.formulaManager.setCellContent({
                    sheet: activeWorkSheet.getKey(),
                    row: selection.row,
                    col: selection.col
                }, value);
                const result = this.sheet.formulaManager.getCellValue({
                    sheet: activeWorkSheet.getKey(),
                    row: selection.row,
                    col: selection.col
                });
                activeWorkSheet.setCellValue(selection.row, selection.col, result.value);
            } catch (error) {
                activeWorkSheet.setCellValue(selection.row, selection.col, "#ERROR!");
            } else activeWorkSheet.setCellValue(selection.row, selection.col, value);
        }
    }
    updateFormulaBar() {
        if (!this.formulaBarElement) return;
        const activeWorkSheet = this.sheet.getActiveSheet();
        if (!activeWorkSheet) return void this.clearFormula();
        const selection = activeWorkSheet.getSelection();
        if (selection) try {
            const rowCount = activeWorkSheet.getRowCount(), colCount = activeWorkSheet.getColumnCount();
            if (selection.startRow < 0 || selection.startRow >= rowCount || selection.startCol < 0 || selection.startCol >= colCount) return void this.clearFormula();
            const cellAddressBox = this.formulaBarElement.querySelector(".vtable-sheet-cell-address");
            cellAddressBox && (cellAddressBox.textContent = activeWorkSheet.addressFromCoord(selection.startRow, selection.startCol));
            const formulaInput = this.formulaInput;
            if (formulaInput) {
                if (this.sheet.formulaManager.inputIsParamMode = (0, formula_helper_1.detectFunctionParameterPosition)(formulaInput.value, this.sheet.formulaManager.lastKnownCursorPosInFormulaInput), 
                this.sheet.formulaManager.inputIsParamMode.inParamMode) return;
                if (this.isFormulaBarShowingResult) return;
                try {
                    const formula = this.sheet.formulaManager.getCellFormula({
                        sheet: activeWorkSheet.getKey(),
                        row: selection.startRow,
                        col: selection.startCol
                    });
                    if (formula) {
                        const displayFormula = formula.startsWith("=") ? formula : "=" + formula;
                        formulaInput.value = displayFormula;
                    } else {
                        const cellValue = activeWorkSheet.getCellValue(selection.startRow, selection.startCol);
                        formulaInput.value = null != cellValue ? String(cellValue) : "";
                    }
                } catch (e) {
                    formulaInput.value = "";
                }
            }
        } catch (e) {
            this.clearFormula();
        } else this.clearFormula();
    }
    handleFormulaInput(event) {
        const activeWorkSheet = this.sheet.getActiveSheet();
        if (!activeWorkSheet) return;
        const editingCell = activeWorkSheet.editingCell;
        if (!editingCell) return;
        const input = event.target, value = input.value;
        this.sheet.getActiveSheet().tableInstance.editorManager.editingEditor || this.sheet.getActiveSheet().tableInstance.startEditCell(editingCell.col, editingCell.row, value);
        const editingEditor = this.sheet.getActiveSheet().tableInstance.editorManager.editingEditor;
        if (editingEditor && "getInputElement" in editingEditor && "function" == typeof editingEditor.getInputElement) {
            const inputElement = editingEditor.getInputElement();
            inputElement && (inputElement.value = value, input.focus());
        }
        value.startsWith("=") && this.sheet.formulaManager.cellHighlightManager.highlightFormulaCells(value), 
        event.isFormulaInsertion || (this.sheet.formulaManager.inputIsParamMode = (0, formula_helper_1.detectFunctionParameterPosition)(value, this.sheet.formulaManager.lastKnownCursorPosInFormulaInput), 
        value.startsWith("=") ? (this.sheet.formulaManager.cellHighlightManager.highlightFormulaCells(value), 
        this.isFormulaBarShowingResult = !1, this.sheet.formulaManager.setCellContent({
            sheet: activeWorkSheet.getKey(),
            row: editingCell.row,
            col: editingCell.col
        }, value)) : this.sheet.formulaManager.cellHighlightManager.clearHighlights(), this.sheet.formulaManager.formulaWorkingOnCell = activeWorkSheet.editingCell);
    }
    handleFormulaKeydown(event) {
        var _a, _b, _c, _d;
        const activeWorkSheet = this.sheet.getActiveSheet();
        if (!activeWorkSheet) return;
        const input = event.target;
        if ("Enter" === event.key) {
            const editingCell = activeWorkSheet.editingCell;
            if (!editingCell) return;
            const value = input.value;
            if (value.startsWith("=") && value.length > 1) try {
                const currentCellAddress = activeWorkSheet.addressFromCoord(editingCell.row, editingCell.col);
                if (new RegExp(`(^|[^A-Za-z0-9])${currentCellAddress}([^A-Za-z0-9]|$)`).test(value)) return activeWorkSheet.setCellValue(editingCell.row, editingCell.col, "#CYCLE!"), 
                null === (_a = activeWorkSheet.tableInstance) || void 0 === _a || _a.changeCellValue(editingCell.col, editingCell.row, "#CYCLE!"), 
                this.sheet.formulaManager.formulaWorkingOnCell = null, input.value = "", void input.blur();
                this.sheet.formulaManager.setCellContent({
                    sheet: activeWorkSheet.getKey(),
                    row: editingCell.row,
                    col: editingCell.col
                }, value);
                const result = this.sheet.formulaManager.getCellValue({
                    sheet: activeWorkSheet.getKey(),
                    row: editingCell.row,
                    col: editingCell.col
                });
                null === (_b = activeWorkSheet.tableInstance) || void 0 === _b || _b.changeCellValue(editingCell.col, editingCell.row, result.error ? "#ERROR!" : result.value), 
                this.isFormulaBarShowingResult = !0, input.blur(), setTimeout((() => {
                    this.sheet.formulaManager.formulaWorkingOnCell = null, activeWorkSheet.tableInstance.clearSelected(), 
                    this.sheet.formulaManager.cellHighlightManager.clearHighlights(), activeWorkSheet.tableInstance.selectCell(editingCell.col, editingCell.row);
                }), 0);
            } catch (error) {
                activeWorkSheet.setCellValue(editingCell.row, editingCell.col, "#ERROR!"), null === (_c = activeWorkSheet.tableInstance) || void 0 === _c || _c.changeCellValue(editingCell.col, editingCell.row, "#ERROR!"), 
                this.sheet.formulaManager.formulaWorkingOnCell = null;
            } else activeWorkSheet.setCellValue(editingCell.row, editingCell.col, value), null === (_d = activeWorkSheet.tableInstance) || void 0 === _d || _d.changeCellValue(editingCell.col, editingCell.row, value), 
            this.sheet.formulaManager.formulaWorkingOnCell = null;
            this.isEnterKeyPressed = !0, event.preventDefault(), event.stopPropagation();
        }
    }
    clearFormula() {
        var _a;
        const cellAddressBox = null === (_a = this.formulaBarElement) || void 0 === _a ? void 0 : _a.querySelector(".vtable-sheet-cell-address");
        cellAddressBox && (cellAddressBox.textContent = "");
        const formulaInput = this.formulaInput;
        formulaInput && (formulaInput.value = "");
    }
    release() {
        this.formulaBarElement = null, this.formulaInput = null;
    }
}

exports.FormulaUIManager = FormulaUIManager;