<div id="package-add-modal" tabindex="-1" role="dialog" class="modal fade">
    <div class="modal-dialog modal-lg" role="document">
        <div class="modal-content">
            <form id="package-add-form" onsubmit="return false">
                <div class="modal-header">
                    <h4 class="modal-title">Add new packages</h4>
                    <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="close"></button>
                </div>
                <div class="modal-body">
                    <div class="form-group row">
                        <label for="package-add-repository-input" class="col-3 col-form-label">repository</label>
                        <div class="col-9">
                            <select id="package-add-repository-input" class="form-control" required>
                                {% for repository in repositories %}
                                    <option value="{{ repository.id }}" data-repository="{{ repository.repository }}" data-architecture="{{ repository.architecture }}">{{ repository.repository }} ({{ repository.architecture }})</option>
                                {% endfor %}
                            </select>
                        </div>
                    </div>
                    <div class="form-group row">
                        <label for="package-add-input" class="col-3 col-form-label">package</label>
                        <div class="col-9">
                            <input id="package-add-input" type="text" list="package-add-known-packages-dlist" autocomplete="off" class="form-control" placeholder="AUR package" required>
                            <datalist id="package-add-known-packages-dlist"></datalist>
                        </div>
                    </div>
                    <div class="form-group row">
                        <label class="col-3 col-form-label"></label>
                        <div class="col-9">
                            <input id="package-add-refresh-input" type="checkbox" class="form-check-input" value="" checked>
                            <label for="package-add-refresh-input" class="form-check-label">update pacman databases</label>
                        </div>
                    </div>
                    <div class="form-group row">
                        <div class="col-12">
                            <button id="package-add-variable-button" type="button" class="form-control btn btn-light rounded" onclick="packageAddVariableInputCreate()"><i class="bi bi-plus"></i> add environment variable </button>
                        </div>
                    </div>
                    <div id="package-add-variables-div" class="form-group row"></div>
                </div>
                <div class="modal-footer">
                    <button type="submit" class="btn btn-primary" onclick="packagesAdd()"><i class="bi bi-play"></i> add</button>
                    <button type="submit" class="btn btn-success" onclick="packagesRequest()"><i class="bi bi-plus"></i> request</button>
                </div>
            </form>
        </div>
    </div>
</div>

<script>
    const packageAddModal = document.getElementById("package-add-modal");
    const packageAddForm = document.getElementById("package-add-form");

    const packageAddInput = document.getElementById("package-add-input");
    const packageAddRepositoryInput = document.getElementById("package-add-repository-input");
    const packageAddKnownPackagesList = document.getElementById("package-add-known-packages-dlist");

    const packageAddVariablesDiv = document.getElementById("package-add-variables-div");

    const packageAddRefreshInput = document.getElementById("package-add-refresh-input");

    function packageAddVariableInputCreate() {
        const variableInput = document.createElement("div");
        variableInput.classList.add("input-group");
        variableInput.classList.add("package-add-variable");

        const variableNameInput = document.createElement("input");
        variableNameInput.type = "text";
        variableNameInput.classList.add("form-control");
        variableNameInput.classList.add("package-add-variable-name");
        variableNameInput.placeholder = "name";
        variableNameInput.ariaLabel = "variable name";

        const variableSeparator = document.createElement("span");
        variableSeparator.classList.add("input-group-text")
        variableSeparator.textContent = "=";

        const variableValueInput = document.createElement("input");
        variableValueInput.type = "text";
        variableValueInput.classList.add("form-control");
        variableValueInput.classList.add("package-add-variable-value");
        variableValueInput.placeholder = "value";
        variableValueInput.ariaLabel = "variable value";

        const variableButtonRemove = document.createElement("button");
        variableButtonRemove.type = "button";
        variableButtonRemove.classList.add("btn");
        variableButtonRemove.classList.add("btn-outline-danger");
        variableButtonRemove.innerHTML = "<i class=\"bi bi-trash\"></i>";
        variableButtonRemove.onclick = _ => { variableInput.remove(); };

        // bring them together
        variableInput.appendChild(variableNameInput);
        variableInput.appendChild(variableSeparator);
        variableInput.appendChild(variableValueInput);
        variableInput.appendChild(variableButtonRemove);

        packageAddVariablesDiv.appendChild(variableInput);
    }

    function patchesParse() {
        const patches = Array.from(packageAddVariablesDiv.getElementsByClassName("package-add-variable")).map(element => {
            return {
                key: element.querySelector(".package-add-variable-name").value,
                value: element.querySelector(".package-add-variable-value").value,
            };
        }).filter(patch => patch.key);
        return {patches: patches};
    }

    function packagesAdd(packages, patches, repository, data) {
        packages = packages ?? packageAddInput.value;
        patches = patches ?? patchesParse();
        repository = repository ?? getRepositorySelector(packageAddRepositoryInput);
        data = data ?? {refresh: packageAddRefreshInput.checked};

        if (packages) {
            bootstrap.Modal.getOrCreateInstance(packageAddModal).hide();
            const onSuccess = update => `Packages ${update} have been added`;
            const onFailure = error => `Package addition failed: ${error}`;
            const parameters = Object.assign({}, data, patches);
            doPackageAction("/api/v1/service/add", [packages], repository, onSuccess, onFailure, parameters);
        }
    }

    function packagesRequest(packages, patches) {
        packages = packages ?? packageAddInput.value;
        patches = patches ?? patchesParse();
        const repository = getRepositorySelector(packageAddRepositoryInput);

        if (packages) {
            bootstrap.Modal.getOrCreateInstance(packageAddModal).hide();
            const onSuccess = update => `Packages ${update} have been requested`;
            const onFailure = error => `Package request failed: ${error}`;
            doPackageAction("/api/v1/service/request", [packages], repository, onSuccess, onFailure, patches);
        }
    }

    ready(_ => {
        packageAddModal.addEventListener("shown.bs.modal", _ => {
            const option = packageAddRepositoryInput.querySelector(`option[value="${repository.architecture}-${repository.repository}"]`);
            option.selected = "selected";
        });
        packageAddModal.addEventListener("hidden.bs.modal", _ => {
            packageAddVariablesDiv.replaceChildren();
            packageAddForm.reset();
        });

        packageAddInput.addEventListener("keyup", _ => {
            clearTimeout(packageAddInput.requestTimeout);

            // do not update datalist if search string didn't change yet
            const value = packageAddInput.value;
            const previousValue = packageAddInput.dataset.previousValue;
            if (value === previousValue) {
                return;
            }

            // store current search string in attributes
            packageAddInput.dataset.previousValue = value;

            // perform data list update
            packageAddInput.requestTimeout = setTimeout(_ => {

                if (value.length >= 3) {
                    makeRequest(
                        "/api/v1/service/search",
                        {
                            query: {
                                for: value,
                            },
                            convert: response => response.json(),
                        },
                        data => {
                            const options = data.map(pkg => {
                                const option = document.createElement("option");
                                option.value = pkg.package;
                                option.innerText = `${pkg.package} (${pkg.description})`;
                                return option;
                            });
                            packageAddKnownPackagesList.replaceChildren(...options);
                        },
                    );
                }
            }, 500);
        });
    });
</script>
