import { ExcelEditCellKeyboardResponse } from "@visactor/vtable-plugins";

export class FormulaAutocomplete {
    constructor(container, sheet) {
        this.dropdown = null, this.items = [], this.selectedIndex = -1, this.isVisible = !1, 
        this.inputElement = null, this.container = container, this.sheet = sheet, this.createDropdown();
    }
    createDropdown() {
        this.dropdown = document.createElement("div"), this.dropdown.className = "vtable-formula-autocomplete", 
        this.dropdown.style.display = "none", this.container.appendChild(this.dropdown);
    }
    attachTo(input, onSelect, customPositioning) {
        this.inputElement = input, this.onSelectCallback = onSelect, this.customPositioning = customPositioning, 
        input.addEventListener("input", this.handleInput.bind(this)), input.addEventListener("keydown", this.handleKeydown.bind(this), !0), 
        input.addEventListener("blur", (() => {
            setTimeout((() => this.hide()), 10);
        }));
    }
    handleInput(event) {
        const input = event.target, value = input.value, cursorPos = input.selectionStart || 0, context = this.parseInputContext(value, cursorPos);
        context.shouldShowAutocomplete ? (this.updateSuggestions(context), this.show()) : this.hide();
    }
    parseInputContext(value, cursorPos) {
        if (!value.startsWith("=")) return {
            shouldShowAutocomplete: !1,
            searchTerm: "",
            type: "all",
            insertPosition: 0
        };
        const textBeforeCursor = value.substring(1, cursorPos), lastOperatorMatch = textBeforeCursor.match(/[\+\-\*\/\(\,\s]([A-Za-z0-9]*)$/);
        return lastOperatorMatch && "" !== lastOperatorMatch[1] ? {
            shouldShowAutocomplete: !0,
            searchTerm: lastOperatorMatch[1],
            type: /^[A-Za-z]/.test(lastOperatorMatch[1]) ? "function" : "cell",
            insertPosition: cursorPos - lastOperatorMatch[1].length
        } : textBeforeCursor.match(/^[A-Za-z0-9]*$/) ? {
            shouldShowAutocomplete: !0,
            searchTerm: textBeforeCursor,
            type: "all",
            insertPosition: 1
        } : {
            shouldShowAutocomplete: !1,
            searchTerm: "",
            type: "all",
            insertPosition: 0
        };
    }
    updateSuggestions(context) {
        const {searchTerm: searchTerm, type: type} = context;
        if (this.items = [], "function" === type || "all" === type) {
            const functionItems = this.sheet.formulaManager.getAvailableFunctions().filter((fn => fn.toUpperCase().startsWith(searchTerm.toUpperCase()))).slice(0, 10).map((fn => ({
                type: "function",
                value: fn,
                label: fn,
                description: this.getFunctionDescription(fn),
                signature: this.getFunctionSignature(fn)
            })));
            this.items.push(...functionItems);
        }
        if ("cell" === type || "all" === type) {
            const cellSuggestions = this.generateCellSuggestions(searchTerm);
            this.items.push(...cellSuggestions);
        }
        this.renderDropdown();
    }
    generateCellSuggestions(searchTerm) {
        const suggestions = [], cellMatch = searchTerm.match(/^([A-Za-z]*)([0-9]*)$/);
        if (cellMatch) {
            const [, colPart, rowPart] = cellMatch;
            if (colPart && !rowPart) for (let row = 1; row <= 5; row++) suggestions.push({
                type: "cell",
                value: `${colPart.toUpperCase()}${row}`,
                label: `${colPart.toUpperCase()}${row}`,
                description: "单元格引用"
            });
            if (colPart && rowPart) {
                const address = `${colPart.toUpperCase()}${rowPart}`;
                suggestions.push({
                    type: "cell",
                    value: address,
                    label: address,
                    description: "单元格引用"
                }), suggestions.push({
                    type: "range",
                    value: `${address}:`,
                    label: `${address}:...`,
                    description: "开始选择范围"
                });
            }
        }
        return suggestions.slice(0, 5);
    }
    getFunctionDescription(functionName) {
        return {
            SUM: "计算数值总和",
            AVERAGE: "计算平均值",
            COUNT: "计数数值单元格",
            MAX: "返回最大值",
            MIN: "返回最小值",
            IF: "条件判断",
            VLOOKUP: "垂直查找",
            CONCATENATE: "连接文本"
        }[functionName] || "";
    }
    getFunctionSignature(functionName) {
        return {
            SUM: "(number1, [number2], ...)",
            AVERAGE: "(number1, [number2], ...)",
            COUNT: "(value1, [value2], ...)",
            MAX: "(number1, [number2], ...)",
            MIN: "(number1, [number2], ...)",
            IF: "(logical_test, value_if_true, value_if_false)",
            VLOOKUP: "(lookup_value, table_array, col_index_num, [range_lookup])",
            CONCATENATE: "(text1, [text2], ...)"
        }[functionName] || "()";
    }
    renderDropdown() {
        if (!this.dropdown) return;
        if (this.dropdown.innerHTML = "", 0 === this.items.length) {
            const emptyEl = document.createElement("div");
            return emptyEl.className = "vtable-formula-autocomplete-empty", emptyEl.textContent = "没有匹配的函数", 
            void this.dropdown.appendChild(emptyEl);
        }
        const groups = this.groupItems(this.items);
        groups.forEach((group => {
            if (groups.length > 1) {
                const groupEl = document.createElement("div");
                groupEl.className = "vtable-formula-autocomplete-group", groupEl.textContent = this.getGroupTitle(group.type), 
                this.dropdown.appendChild(groupEl);
            }
            group.items.forEach(((item, index) => {
                const globalIndex = this.items.indexOf(item), itemEl = document.createElement("div");
                itemEl.className = "vtable-formula-autocomplete-item", globalIndex === this.selectedIndex && itemEl.classList.add("selected");
                const nameEl = document.createElement("div");
                nameEl.className = "item-name";
                const labelEl = document.createElement("span");
                labelEl.textContent = item.label, nameEl.appendChild(labelEl);
                const typeEl = document.createElement("span");
                if (typeEl.className = `item-type ${item.type}`, typeEl.textContent = this.getTypeLabel(item.type), 
                nameEl.appendChild(typeEl), itemEl.appendChild(nameEl), item.signature) {
                    const signatureEl = document.createElement("div");
                    signatureEl.className = "item-signature", signatureEl.textContent = item.signature, 
                    itemEl.appendChild(signatureEl);
                }
                if (item.description) {
                    const descEl = document.createElement("div");
                    descEl.className = "item-description", descEl.textContent = item.description, itemEl.appendChild(descEl);
                }
                itemEl.addEventListener("mousedown", (() => this.selectItem(globalIndex))), itemEl.addEventListener("mouseenter", (() => {
                    this.selectedIndex = globalIndex, this.renderDropdown();
                })), this.dropdown.appendChild(itemEl);
            }));
        }));
        const footerEl = document.createElement("div");
        footerEl.className = "vtable-formula-autocomplete-footer", footerEl.innerHTML = '\n    <div class="shortcut">\n      <span class="key">↑↓</span>\n      <span>选择</span>\n    </div>\n    <div class="shortcut">\n      <span class="key">Enter</span>\n      <span>确认</span>\n    </div>\n    <div class="shortcut">\n      <span class="key">Esc</span>\n      <span>取消</span>\n    </div>\n  ', 
        this.dropdown.appendChild(footerEl), this.positionDropdown();
    }
    groupItems(items) {
        const groups = {};
        items.forEach((item => {
            groups[item.type] || (groups[item.type] = []), groups[item.type].push(item);
        }));
        return [ "function", "cell", "range" ].filter((type => groups[type])).map((type => ({
            type: type,
            items: groups[type]
        })));
    }
    getGroupTitle(type) {
        return {
            function: "函数",
            cell: "单元格",
            range: "范围"
        }[type] || type;
    }
    getTypeLabel(type) {
        return {
            function: "fx",
            cell: "A1",
            range: "A:B"
        }[type] || type;
    }
    positionDropdown() {
        if (this.customPositioning) return void this.customPositioning();
        if (!this.dropdown || !this.inputElement) return;
        const inputRect = this.inputElement.getBoundingClientRect(), containerRect = this.container.getBoundingClientRect();
        this.dropdown.style.position = "absolute", this.dropdown.style.left = inputRect.left - containerRect.left + "px", 
        this.dropdown.style.top = inputRect.bottom - containerRect.top + 2 + "px", this.dropdown.style.width = `${Math.max(300, inputRect.width)}px`;
    }
    handleKeydown(event) {
        if (this.isVisible) switch (event.key) {
          case "ArrowDown":
            event.preventDefault(), this.selectedIndex = Math.min(this.selectedIndex + 1, this.items.length - 1), 
            this.renderDropdown(), this.scrollToSelectedItem();
            break;

          case "ArrowUp":
            event.preventDefault(), this.selectedIndex = Math.max(this.selectedIndex - 1, 0), 
            this.renderDropdown(), this.scrollToSelectedItem();
            break;

          case "Enter":
            this.selectedIndex >= 0 && (event.preventDefault(), this.selectItem(this.selectedIndex));
            break;

          case "Escape":
            event.preventDefault(), this.hide(), this.inputElement && this.inputElement.focus();
            break;

          case "Tab":
            this.selectedIndex >= 0 ? (event.preventDefault(), this.selectItem(this.selectedIndex)) : this.hide();
        }
    }
    scrollToSelectedItem() {
        if (!this.dropdown || this.selectedIndex < 0) return;
        const items = this.dropdown.querySelectorAll(".vtable-formula-autocomplete-item");
        if (items[this.selectedIndex]) {
            items[this.selectedIndex].scrollIntoView({
                behavior: "smooth",
                block: "nearest"
            });
        }
    }
    selectItem(index) {
        const item = this.items[index];
        if (item && this.inputElement) {
            if (this.onSelectCallback) this.onSelectCallback(item); else {
                const value = this.inputElement.value, cursorPos = this.inputElement.selectionStart || 0, context = this.parseInputContext(value, cursorPos), newValue = value.substring(0, context.insertPosition) + item.value + ("function" === item.type ? "(" : "") + value.substring(cursorPos);
                this.inputElement.value = newValue;
                const newCursorPos = context.insertPosition + item.value.length + ("function" === item.type ? 1 : 0);
                this.inputElement.setSelectionRange(newCursorPos, newCursorPos);
                const inputEvent = new Event("input", {
                    bubbles: !0
                });
                this.inputElement.dispatchEvent(inputEvent);
            }
            this.hide(), this.inputElement && setTimeout((() => {
                this.inputElement.focus();
            }), 50);
        }
    }
    show() {
        if (this.dropdown && this.items.length > 0) {
            const excelEditCellKeyboardPlugin = this.sheet.getActiveSheet().tableInstance.pluginManager.getPlugin("excel-edit-cell-keyboard");
            excelEditCellKeyboardPlugin && excelEditCellKeyboardPlugin.deleteResponseKeyboard([ ExcelEditCellKeyboardResponse.ARROW_DOWN, ExcelEditCellKeyboardResponse.ARROW_UP, ExcelEditCellKeyboardResponse.ENTER ]), 
            this.dropdown.style.display = "block", this.isVisible = !0, this.selectedIndex = 0, 
            this.renderDropdown();
        }
    }
    hide() {
        const excelEditCellKeyboardPlugin = this.sheet.getActiveSheet().tableInstance.pluginManager.getPlugin("excel-edit-cell-keyboard");
        excelEditCellKeyboardPlugin && excelEditCellKeyboardPlugin.addResponseKeyboard([ ExcelEditCellKeyboardResponse.ARROW_DOWN, ExcelEditCellKeyboardResponse.ARROW_UP, ExcelEditCellKeyboardResponse.ENTER ]), 
        this.dropdown && (this.dropdown.style.display = "none", this.isVisible = !1, this.selectedIndex = -1);
    }
    release() {
        this.dropdown && this.dropdown.parentNode && this.dropdown.parentNode.removeChild(this.dropdown);
    }
}
//# sourceMappingURL=formula-autocomplete.js.map