<script>
    const keyImportButton = $("#key-import-button");
    const packageAddButton = $("#package-add-button");
    const packageRebuildButton = $("#package-rebuild-button");
    const packageRemoveButton = $("#package-remove-button");
    const packageUpdateButton = $("#package-update-button");

    const packageInfoRemoveButton = $("#package-info-remove-button");
    const packageInfoUpdateButton = $("#package-info-update-button");

    let repository = null;

    const table = $("#packages");

    const statusBadge = $("#badge-status");
    const versionBadge = $("#badge-version");

    function doPackageAction(uri, packages, repository, successText, failureText, data) {
        const queryParams = $.param({
            architecture: repository.architecture,
            repository: repository.repository,
        }); // it will never be empty btw

        $.ajax({
            url: `${uri}?${queryParams}`,
            data: JSON.stringify(Object.assign({}, {packages: packages}, data || {})),
            type: "POST",
            contentType: "application/json",
            success: _ => {
                const message = successText(packages.join(", "));
                showSuccess("Success", message);
            },
            error: (jqXHR, _, errorThrown) => {
                showFailure("Action failed", failureText, jqXHR, errorThrown);
            },
        });
    }

    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.find(":selected");
        return {
            architecture: selected.data("architecture"),
            repository: selected.data("repository"),
        };
    }

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

    function hideControls(hidden) {
        keyImportButton.attr("hidden", hidden);
        packageAddButton.attr("hidden", hidden);
        packageRebuildButton.attr("hidden", hidden);
        packageRemoveButton.attr("hidden", hidden);
        packageUpdateButton.attr("hidden", hidden);
    }

    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 reload() {
        table.bootstrapTable("showLoading");

        const badgeClass = status => {
            if (status === "pending") return "btn-outline-warning";
            if (status === "building") return "btn-outline-warning";
            if (status === "failed") return "btn-outline-danger";
            if (status === "success") return "btn-outline-success";
            return "btn-outline-secondary";
        };

        $.ajax({
            url: "/api/v1/packages",
            data: {
                architecture: repository.architecture,
                repository: repository.repository,
            },
            type: "GET",
            dataType: "json",
            success: response => {
                const payload = response.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,
                    };
                });

                table.bootstrapTable("load", payload);
                table.bootstrapTable("uncheckAll");
                table.bootstrapTable("hideLoading");
                hideControls(false);
            },
            error: (jqXHR, _, errorThrown) => {
                if ((jqXHR.status === 401) || (jqXHR.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 = error => `Could not load list of packages: ${error}`;
                    showFailure("Load failure", message, jqXHR, errorThrown);
                }
                hideControls(true);
            },
        });

        $.ajax({
            url: "/api/v1/status",
            data: {
                architecture: repository.architecture,
                repository: repository.repository,
            },
            type: "GET",
            dataType: "json",
            success: response => {
                versionBadge.html(`<i class="bi bi-github"></i> ahriman ${safe(response.version)}`);

                statusBadge
                    .popover("dispose")
                    .attr("data-bs-content", `${response.status.status} at ${new Date(1000 * response.status.timestamp).toISOStringShort()}`)
                    .popover();
                statusBadge.removeClass();
                statusBadge.addClass("btn");
                statusBadge.addClass(badgeClass(response.status.status));
            },
        });
    }

    function selectRepository() {
        const fragment = window.location.hash.replace("#", "") || "{{ repositories[0].id }}";
        const element = $(`#${fragment}-link`);
        element.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)};
    }

    $(_ => {
        $("#repositories a").on("click", event => {
            const element = event.target;
            repository = {
                architecture: element.dataset.architecture,
                repository: element.dataset.repository,
            };
            packageUpdateButton.html(`<i class="bi bi-play"></i> update<span class="d-none d-sm-inline"> ${safe(repository.repository)} (${safe(repository.architecture)})</span>`);
            $(`#${element.id}`).tab("show");
            reload();
        });

        table.on("check.bs.table uncheck.bs.table check-all.bs.table uncheck-all.bs.table", _ => {
            packageRemoveButton.prop("disabled", !table.bootstrapTable("getSelections").length);
        });
        table.on("click-row.bs.table", (self, 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);
        });
        table.on("created-controls.bs.table", _ => {
            const pickerInput = $(".bootstrap-table-filter-control-timestamp");
            pickerInput.daterangepicker({
                autoUpdateInput: false,
                locale: {
                    cancelLabel: "Clear",
                },
            });

            pickerInput.on("apply.daterangepicker", (event, picker) => {
                pickerInput.val(`${picker.startDate.format("YYYY-MM-DD")} - ${picker.endDate.format("YYYY-MM-DD")}`);
                table.bootstrapTable("triggerSearch");
            });

            pickerInput.on("cancel.daterangepicker", _ => {
                pickerInput.val("");
                table.bootstrapTable("triggerSearch");
            });
        });

        statusBadge.popover();
        selectRepository();
    });
</script>
