import {ListProcessors} from "../../wailsjs/go/main/App";

import { Controller } from "@hotwired/stimulus"

import { textProcessor } from "../services.js";

export class CommandsController extends Controller {
    static targets = [
        "commandInput",
        "commandSelect",
    ];

    async connect() {
        this._lastCommand = null;

        let processors = await ListProcessors();
        processors.forEach((processor) => {
            let option = document.createElement("option");
            option.value = processor.name;
            option.text = processor.label;
            this.commandSelectTarget.appendChild(option);
        });
        this._options = Array.from(this.commandSelectTarget.options);
    }

    showCommands(ev) {
        ev.preventDefault();
        this.element.showModal();

        this.commandInputTarget.setSelectionRange(0, this.commandInputTarget.value.length, "forward");
        this.commandInputTarget.focus();
    }

    handleKeyup(ev) {
        this._filterOptions(this.commandInputTarget.value);
    }

    dismissDialog(ev) {
        ev.preventDefault();
        this.element.close();
    }

    focusSelect(ev) {
        this.commandSelectTarget.focus();
    }

    runCommand(ev) {
        ev.preventDefault();

        textProcessor.runTextCommand(this.commandSelectTarget.value);
        this._lastCommand = this.commandSelectTarget.value;

        this.element.close();
    }

    rerunLastCommand(ev) {
        ev.preventDefault();

        if (this._lastCommand === null) {
            return;
        }

        textProcessor.runTextCommand(this._lastCommand);
    }

    _filterOptions(filterText) {
        let inputText = filterText.toLowerCase();
        let inputTerms = filterText.toLowerCase().split(/\s+/).map(s => s.trim()).filter(s => s !== "");

        let visibleOptions = [];
        for (let opt of this._options) {
            if ((inputTerms.length === 0) || (inputTerms.every(term => opt.innerText.toLowerCase().includes(term)))) {
                visibleOptions.push(opt);
            }
        }

        let bestMatch = null;
        for (let i; i < this._options.length; i++) {
            if ((inputTerms.length === 0) || (opt.innerText.toLowerCase().includes(inputText))) {
                bestMatch = i;
            }
        }

        this.commandSelectTarget.replaceChildren(...visibleOptions);
        if (visibleOptions.length > 0)  {
            if (bestMatch != null) {
                this.commandSelectTarget.selectedIndex = bestMatch;
            } else {
                this.commandSelectTarget.selectedIndex = 0;
            }
        }
    }
}
