function revisionClicked(namespace, name, self) {
    let active = "active border-primary border-1 bg-white";
    let inactive = "border-secondary bg-secondary";
    revRow.find(".active").removeClass(active).addClass(inactive)
    self.removeClass(inactive).addClass(active)
    const elm = self.data("elm")
    setHashParam("revision", elm.revision)
    $("#sectionDetails span.rev").text("#" + elm.revision)
    statusStyle(elm.status, $("#none"), $("#sectionDetails .rev-details .rev-status"))

    const rdate = luxon.DateTime.fromISO(elm.updated);
    $("#sectionDetails .rev-date").text(rdate.toJSDate().toLocaleString())
    $("#sectionDetails .rev-tags .rev-chart").text(elm.chart)
    $("#sectionDetails .rev-tags .rev-app").text(elm.app_version)
    $("#sectionDetails .rev-tags .rev-ns").text(getHashParam("namespace"))
    if (getHashParam("context")) {
        $("#sectionDetails .rev-tags .rev-cluster").text(getHashParam("context"))
    } else {
        $("#sectionDetails .rev-tags .rev-cluster").parent().hide() // TODO: makes UI jumpy, change to showing
    }

    $("#revDescr").text(elm.description).removeClass("text-danger")
    if (elm.status === "failed") {
        $("#revDescr").addClass("text-danger")
    }

    const rev = $("#specRev").data("last-rev") == elm.revision ? elm.revision - 1 : elm.revision
    if (!rev || getHashParam("revision") === $("#specRev").data("first-rev")) {
        $("#btnRollback").hide()
    } else {
        $("#btnRollback").show().data("rev", rev).find("span").text("Rollback to #" + rev)
    }

    const tab = getHashParam("tab")
    if (!tab) {
        $("#nav-tab [data-tab=resources]").click()
    } else {
        $("#nav-tab [data-tab=" + tab + "]").click()
    }
}


function loadContentWrapper() {
    let revDiff = 0
    const revision = parseInt(getHashParam("revision"));
    if (revision === $("#specRev").data("first-rev")) {
        revDiff = 0
    } else if (getHashParam("mode") === "diff-prev") {
        revDiff = revision - 1
    } else if (getHashParam("mode") === "diff-rev") {
        revDiff = $("#specRev").val()
    }

    const flag = $("#userDefinedVals").prop("checked");
    loadContent(getHashParam("tab"), getHashParam("namespace"), getHashParam("chart"), revision, revDiff, flag)
}

function loadContent(mode, namespace, name, revision, revDiff, userDefined) {
    let qstr = "revision=" + revision
    if (revDiff) {
        qstr += "&revisionDiff=" + revDiff
    }

    if (userDefined) {
        qstr += "&userDefined=" + userDefined
    }

    let url = "/api/helm/releases/" + namespace + "/" + name + "/" + mode
    url += "?" + qstr
    const diffDisplay = $("#manifestText");
    diffDisplay.empty().append('<span class="spinner-border spinner-border-sm" role="status" aria-hidden="true"></span>')
    $.get(url).fail(function (xhr) {
        reportError("Failed to get diff of " + mode, xhr)
    }).done(function (data) {
        diffDisplay.empty();
        if (data === "") {
            diffDisplay.text("No differences to display")
        } else {
            if (revDiff) {
                const targetElement = document.getElementById('manifestText');
                const configuration = {
                    inputFormat: 'diff', outputFormat: 'side-by-side',

                    drawFileList: false, showFiles: false, highlight: true, //matching: 'lines',
                };
                const diff2htmlUi = new Diff2HtmlUI(targetElement, data, configuration);
                diff2htmlUi.draw()
            } else {
                data = hljs.highlight(data, {language: 'yaml'}).value
                const code = $("#manifestText").empty().append("<pre class='bg-white rounded p-3'></pre>").find("pre");
                code.html(data)
            }
        }
    })
}

$('#specRev').keyup(function (event) {
    let keycode = (event.keyCode ? event.keyCode : event.which);
    if (keycode == '13') {
        $("#diffModeRev").click()
    }
});

$("form").submit(function (e) {
    e.preventDefault();
});

$("#userDefinedVals").change(function () {
    const self = $(this)
    const flag = $("#userDefinedVals").prop("checked");
    setHashParam("udv", flag)
    loadContentWrapper()
})

$("#modePanel [data-mode]").click(function () {
    const self = $(this)
    const mode = self.data("mode")
    setHashParam("mode", mode)
    loadContentWrapper()
})

$("#nav-tab [data-tab]").click(function () {
    const self = $(this)
    setHashParam("tab", self.data("tab"))

    if (self.data("tab") === "values") {
        $("#userDefinedVals").parent().show()
    } else {
        $("#userDefinedVals").parent().hide()
    }

    const flag = getHashParam("udv") === "true";
    $("#userDefinedVals").prop("checked", flag)

    if (self.data("tab") === "resources") {
        showResources(getHashParam("namespace"), getHashParam("chart"), getHashParam("revision"))
    } else {
        const mode = getHashParam("mode")
        if (!mode) {
            $("#modePanel [data-mode=view]").trigger('click')
        } else {
            $("#modePanel [data-mode=" + mode + "]").trigger('click')
        }
    }
})


function showResources(namespace, chart, revision) {
    const resBody = $("#nav-resources .body");
    const interestingResources = ["STATEFULSET", "DEAMONSET", "DEPLOYMENT"];
    resBody.empty().append('<span class="spinner-border spinner-border-sm" role="status" aria-hidden="true"></span>');
    let url = "/api/helm/releases/" + namespace + "/" + chart + "/resources?health=true"
    $.getJSON(url).fail(function (xhr) {
        reportError("Failed to get list of resources", xhr)
    }).done(function (data) {
        const scanners = $("body").data("scanners");
        const scannableResKinds = new Set();
        for (let k in scanners) {
            scanners[k].SupportedResourceKinds.forEach(scannableResKinds.add, scannableResKinds)
        }

        resBody.empty();
        data = data.sort(function (a, b) {
            return interestingResources.indexOf(a.kind.toUpperCase()) - interestingResources.indexOf(b.kind.toUpperCase())
        }).reverse();
        for (let i = 0; i < data.length; i++) {
            const res = data[i]
            const resBlock = $(`
                    <div class="row px-3 py-2 mb-3 bg-white rounded">
                        <div class="col-2 res-kind text-break"></div>
                        <div class="col-3 res-name text-break fw-bold"></div>
                        <div class="col-2 res-status overflow-hidden"><span class="spinner-border spinner-border-sm" role="status" aria-hidden="true"></span></div>
                        <div class="col-3 res-statusmsg text-break"><span class="text-muted small">Getting status...</span></div>
                        <div class="col-2 res-actions"><button class='btn btn-sm ms-2 visually-hidden'>Vertical-sizer</button></div>
                    </div>
            `)

            resBlock.find(".res-kind").text(res.kind)
            resBlock.find(".res-name").text(res.metadata.name)

            resBody.append(resBlock)
            let ns = res.metadata.namespace ? res.metadata.namespace : namespace
            for (let k = 0; k < res.status.conditions.length; k++) {
                if (res.status.conditions[k].type !== "hdHealth") { // it's our custom condition type
                    continue
                }

                const cond = res.status.conditions[k]

                const badge = $("<span class='badge me-2 fw-normal'></span>").text(cond.reason);
                if (cond.status === "Unknown") {
                    badge.addClass("bg-secondary text-danger")
                } else if (cond.status === "Healthy") {
                    badge.addClass("bg-success text-dark")
                } else if (cond.status === "Progressing") {
                    badge.addClass("bg-warning")
                } else {
                    badge.addClass("bg-danger")
                }

                if (["Exists"].includes(cond.reason)) {
                    badge.addClass("bg-opacity-50")
                }

                const statusBlock = resBlock.find(".res-status");
                statusBlock.empty().append(badge).attr("title", cond.reason)
                const statusMessage = cond.message
                resBlock.find(".res-statusmsg").html("<span class='text-muted small me-2'>" + (statusMessage ? statusMessage : '') + "</span>")

                if (badge.text() !== "NotFound" && revision == $("#specRev").data("last-rev")) {
                    resBlock.find(".res-actions")

                    const btn = $("<button class=\"btn btn-sm btn-white border-secondary\">Describe</button>");
                    resBlock.find(".res-actions").append(btn)
                    btn.click(function () {
                        showDescribe(ns, res.kind, res.metadata.name, badge.clone())
                    })

                    if (scannableResKinds.has(res.kind)) {
                        const btn2 = $("<button class='btn btn-sm btn-white border-secondary ms-2'>Scan</button>");
                        resBlock.find(".res-actions").append(btn2)
                        btn2.click(function () {
                            scanResource(ns, res.kind, res.metadata.name, badge.clone())
                        })
                    }
                }

                if (badge.hasClass("bg-danger") || badge.hasClass("bg-warning")) {
                    resBlock.find(".res-statusmsg").append("<a href='" + KomodorCTALink + "' class='btn btn-primary btn-sm fw-normal fs-80' target='_blank'>Troubleshoot in Komodor <i class='bi-box-arrow-up-right'></i></a>")
                }
            }
        }
    })
}

function showDescribe(ns, kind, name, badge) {
    $("#describeModal .offcanvas-header p").text(kind)
    $("#describeModalLabel").text(name).append(badge.addClass("ms-3 small fw-normal"))
    $("#describeModalBody").empty().append('<span class="spinner-border spinner-border-sm" role="status" aria-hidden="true"></span>')

    const myModal = new bootstrap.Offcanvas(document.getElementById('describeModal'));
    myModal.show()
    $.get("/api/k8s/" + kind.toLowerCase() + "/describe?name=" + name + "&namespace=" + ns).fail(function (xhr) {
        reportError("Failed to describe resource", xhr)
    }).done(function (data) {
        data = hljs.highlight(data, {language: 'yaml'}).value
        $("#describeModalBody").empty().append("<pre class='bg-white rounded p-3'></pre>").find("pre").html(data)
    })
}

function scanResource(ns, kind, name, badge) {
    $("#describeModal .offcanvas-header p").text(kind)
    $("#describeModalLabel").text(name).append(badge.addClass("ms-3 small fw-normal"))
    const body = $("#describeModalBody");
    body.empty().append('<span class="spinner-border spinner-border-sm" role="status" aria-hidden="true"></span> Scanning...')

    const myModal = new bootstrap.Offcanvas(document.getElementById('describeModal'));
    myModal.show()
    $.get("/api/scanners/resource/" + kind.toLowerCase() + "?name=" + name + "&namespace=" + ns).fail(function (xhr) {
        reportError("Failed to scan resource", xhr)
    }).done(function (data) {
        body.empty()
        if ($.isEmptyObject(data)) {
            body.append("No information from scanners. Make sure you have installed some and scanned object is supported.")
        }

        const tabs = $('<ul class="nav nav-tabs mt-3" role="tablist"></ul>')
        const content = $('<div class="tab-content"></div>')

        for (let name in data) {
            const res = data[name]

            if (!res.OrigReport && !res.PassedCount) continue

            const hdr = $(`<li class="nav-item" role="presentation">
                <button class="nav-link" id="` + name + `-tab" data-bs-toggle="tab" data-bs-target="#` + name + `-tab-pane" type="button" role="tab">` + name + `</button>
              </li>`)

            if (res.FailedCount) {
                hdr.find('button').append("<span class='badge bg-danger ms-2'>" + res.FailedCount + " failed</span>")
            }

            if (res.PassedCount) {
                hdr.find('button').append("<span class='badge bg-info ms-2'>" + res.PassedCount + " passed</span>")
            }

            const hl = hljs.highlight(res.OrigReport, {language: 'yaml'}).value
            const pre = $("<pre class='bg-white rounded p-3' style='font-size: inherit; overflow: unset'></pre>").html(hl)
            const div = $('<div class="tab-pane fade" id="' + name + '-tab-pane" role="tabpanel" aria-labelledby="profile-tab" tabindex="0"></div>').append(pre)

            tabs.append(hdr)
            content.append(div)
        }

        body.append(tabs)
        body.append(content)
        tabs.find('li').first().find('button').click()
    })
}
