<script>
    const packageRemoveButton = document.getElementById("package-remove-button");
    const packageUpdateButton = document.getElementById("package-update-button");

    let repository = null;

    // so far bootstrap-table only operates with jquery elements
    const table = $(document.getElementById("packages"));

    const dashboardButton = document.getElementById("dashboard-button");
    const versionBadge = document.getElementById("badge-version");

    const tableAutoReloadButton = document.getElementById("table-autoreload-button");
    const tableAutoReloadInput = document.getElementById("table-autoreload-input");
    let tableAutoReloadTask = null;

    function doPackageAction(uri, packages, repository, successText, failureText, data) {
        makeRequest(
            uri,
            {
                method: "POST",
                query: {
                    architecture: repository.architecture,
                    repository: repository.repository,
                },
                json: Object.assign({}, {packages: packages}, data || {}),
            },
            _ => {
                const message = successText(packages.join(", "));
                showSuccess("Success", message);
            },
            error => {
                showFailure("Action failed", failureText, error);
            },
        );
    }

    function filterListGroups() {
        return extractDataList(table.bootstrapTable("getData"), "groups");
    }

    function filterListLicenses() {
        return extractDataList(table.bootstrapTable("getData"), "licenses");
    }

    function filterListPackagers() {
        return extractDataList(table.bootstrapTable("getData"), "packager");
    }

    function getRepositorySelector(selector) {
        const selected = selector.options[selector.selectedIndex];
        return {
            architecture: selected.getAttribute("data-architecture"),
            repository: selected.getAttribute("data-repository"),
        };
    }

    function getSelection() {
        return table.bootstrapTable("getSelections").map(row => row.id);
    }

    function packagesLoad(onFailure) {
        makeRequest(
            "/api/v1/packages",
            {
                query: {
                    architecture: repository.architecture,
                    repository: repository.repository,
                },
                convert: response => response.json(),
            },
            data => {
                const payload = data
                    .map(description => {
                        const package_base = description.package.base;
                        const web_url = description.package.remote.web_url;
                        return {
                            id: package_base,
                            base: web_url ? safeLink(web_url, package_base, package_base).outerHTML : safe(package_base),
                            version: safe(description.package.version),
                            packager: description.package.packager ? safe(description.package.packager) : "",
                            packages: listToTable(Object.keys(description.package.packages)),
                            groups: listToTable(extractListProperties(description.package, "groups")),
                            licenses: listToTable(extractListProperties(description.package, "licenses")),
                            timestamp: new Date(1000 * description.status.timestamp).toISOStringShort(),
                            status: description.status.status,
                        };
                    });

                updateTable(table, payload, row => row.timestamp);
                table.bootstrapTable("hideLoading");
            },
            onFailure,
        );
    }

    function packagesRemove(packages) {
        packages = packages ?? getSelection();
        const onSuccess = update => `Packages ${update} have been removed`;
        const onFailure = error => `Could not remove packages: ${error}`;

        doPackageAction("/api/v1/service/remove", packages, repository, onSuccess, onFailure);
    }

    function packagesUpdate() {
        const currentSelection = getSelection();
        const [url, onSuccess] = currentSelection.length === 0
            ? ["/api/v1/service/update", _ => `Repository update has been run`]
            : ["/api/v1/service/add", update => `Run update for packages ${update}`];
        const onFailure = error => `Packages update failed: ${error}`;

        doPackageAction(url, currentSelection, repository, onSuccess, onFailure);
    }

    function refreshDatabases() {
        const onSuccess = _ => "Pacman database update has been requested";
        const onFailure = error => `Could not update pacman databases: ${error}`;
        const parameters = {
            refresh: true,
            aur: false,
            local: false,
            manual: false,
        };

        doPackageAction("/api/v1/service/update", [], repository, onSuccess, onFailure, parameters);
    }

    function reload() {
        table.bootstrapTable("showLoading");
        const onFailure = error => {
            if ((error.status === 401) || (error.status === 403)) {
                // authorization error
                const text = "In order to see statuses you must login first.";
                table.find("tr.unauthorized").remove();
                table.find("tbody").append(`<tr class="unauthorized"><td colspan="100%">${safe(text)}</td></tr>`);
                table.bootstrapTable("hideLoading");
            } else {
                // other errors
                const message = details => `Could not load list of packages: ${details}`;
                showFailure("Load failure", message, error);
            }
        };

        packagesLoad(onFailure);
        statusLoad();
    }

    function selectRepository() {
        const fragment = window.location.hash.replace("#", "") || "{{ repositories[0].id }}";
        document.getElementById(`${fragment}-link`).click();
    }

    function statusFormat(value) {
        const cellClass = status => {
            if (status === "pending") return "table-warning";
            if (status === "building") return "table-warning";
            if (status === "failed") return "table-danger";
            if (status === "success") return "table-success";
            return "table-secondary";
        };
        return {classes: cellClass(value)};
    }

    function toggleTableAutoReload(interval) {
        clearInterval(tableAutoReloadTask);
        tableAutoReloadTask = toggleAutoReload(tableAutoReloadButton, interval, tableAutoReloadInput, _ => {
            if (!hasActiveModal() &&
                !hasActiveDropdown()) {
                packagesLoad();
                statusLoad();
            }
        });
    }

    ready(_ => {
        const onCheckFunction = function () {
            if (packageRemoveButton) {
                packageRemoveButton.disabled = !getSelection().length;
            }
        };

        document.querySelectorAll("#repositories a").forEach(element => {
            element.onclick = _ => {
                repository = {
                    architecture: element.dataset.architecture,
                    repository: element.dataset.repository,
                };
                if (packageUpdateButton) {
                    packageUpdateButton.innerHTML = `<i class="bi bi-play"></i> update<span class="d-none d-sm-inline"> ${safe(repository.repository)} (${safe(repository.architecture)})</span>`;
                }
                bootstrap.Tab.getOrCreateInstance(document.getElementById(element.id)).show();
                reload();
            };
        });

        table.bootstrapTable({
            onCheck: onCheckFunction,
            onCheckAll: onCheckFunction,
            onClickRow: (data, row, cell) => {
                if (0 === cell || "base" === cell) {
                    const method = data[0] === true ? "uncheckBy" : "checkBy"; // fck javascript
                    table.bootstrapTable(method, {field: "id", values: [data.id]});
                } else showPackageInfo(data.id);
            },
            onCreatedControls: _ => {
                new easepick.create({
                    element: document.querySelector(".bootstrap-table-filter-control-timestamp"),
                    css: [
                        "https://cdn.jsdelivr.net/npm/@easepick/bundle@1.2.1/dist/index.css",
                    ],
                    grid: 2,
                    calendars: 2,
                    autoApply: false,
                    locale: {
                        cancel: "Clear",
                    },
                    RangePlugin: {
                        tooltip: false,
                    },
                    plugins: [
                        "RangePlugin",
                    ],
                    setup: picker => {
                        picker.on("select", _ => { table.bootstrapTable("triggerSearch"); });
                        // replace "Cancel" behaviour to "Clear"
                        picker.onClickCancelButton = element => {
                            if (picker.isCancelButton(element)) {
                                picker.clear();
                                picker.hide();
                                table.bootstrapTable("triggerSearch");
                            }
                        };
                    },
                });
            },
            onUncheck: onCheckFunction,
            onUncheckAll: onCheckFunction,
        });

        restoreAutoReloadSettings(tableAutoReloadButton, tableAutoReloadInput);

        selectRepository();
        {% if autorefresh_intervals %}
            toggleTableAutoReload();
        {% endif %}
    });
</script>
