const REQUEST_INTERVAL_MS = 3000;

const IN_PROGRESS_STR = 'in progress ';
const GET_STATUS_STR = 'get_status';
const SCALE_UP_STR = 'scale_up';
const SCALE_DOWN_STR = 'scale_down';

function runCommand(command, callback = null) {
    var response_element = $('#responseText');
    var loader_id = response_element.data('loader-id');
    $('#'+loader_id).attr("class","topLeftLoader visible");

    postRequest("/scaler/", "/0?run_command="+command, function(response) {
        
        var json = JSON.parse(response);
        var is_error = !json.hasOwnProperty('status') || json.status != "ok";
        var message = json.hasOwnProperty('message') ? json.message : "bad response (see console)";
        var params = null;

        if (!is_error) {
            if (json.hasOwnProperty("message") && json.message.startsWith(IN_PROGRESS_STR)) {
                if (json.message.startsWith(IN_PROGRESS_STR + command) || json.message.startsWith(IN_PROGRESS_STR + GET_STATUS_STR)) {
                    printResponse(json.message, false);
                    setTimeout(runCommand, REQUEST_INTERVAL_MS, command, callback);
                    return;
                }
                // Если сейчас в процессе скейлинг в обратную сторону
                else {
                    $('#'+loader_id).attr("class","topLeftLoader invisible");
                    printResponse(json.message, false);
                    setTimeout(updateDataTable, REQUEST_INTERVAL_MS);
                    return;
                }
            }

            if (json.hasOwnProperty('params')) {
                message += "\n\n";
                message += "Params: ";
                message += JSON.stringify(json.params, null, '    ');
                params = json.params;
            }
        }
        else {
            updateScaleBtn("fail");
        }

        $('#'+loader_id).attr("class","topLeftLoader invisible");
        printResponse(message, is_error);

        if (callback != null && params != null) {
            callback(params, command);
        }
    });
}

function updateScaleBtn(status) {
    var btn = $('#scaleBtn');
    var icon = "fa fa-spinner fa-spin";
    var style = "btn btn-secondary";
    var title = "Scale UP or DOWN";

    if (status == "on") {
        icon = "fa fa-toggle-on";
        style = "btn btn-success"
        title = "[ON] Push to scale DOWN";
        $('#sandboxStatus').text("✅ All good in the sandbox");
    } else if (status == "off") {
        icon = "fa fa-toggle-off";
        style = "btn btn-danger"
        title = "[OFF] Push to scale UP";
        $('#sandboxStatus').text("❌ Sandbox is off");
    } else if (status == "warning") {
        icon = "fas fa-exclamation-triangle";
        style = "btn btn-dark"
        title = "[WARNING]";
        $('#sandboxStatus').text("🚨 Trouble in the sandbox");
    } else if (status == "fail") {
        icon = "fas fa-exclamation-triangle";
        style = "btn btn-danger"
        title = "[FAIL]";
        $('#sandboxStatus').text("🚑 Trouble in the scaler");
    }

    btn.attr("data-status", status);
    btn.attr("class", style);
    btn.find("i").attr("class", icon);

    var tooltip = bootstrap.Tooltip.getInstance(btn);
    tooltip.setContent({".tooltip-inner" : title});
    tooltip.update();
}

function determineStatus(pods) {
    var status = "on";

    var total_count = 0;
    var scaler_count = 0;
    var disabled_count = 0;

    pods.forEach(pod => {
        if (!pod.is_cron_job) {
            ++total_count;

            if (pod.is_scaler_pod)
                ++scaler_count;

            if (!pod.isok) {
                status = "warning";
                ++disabled_count;                
            }
        }
    });

    if (total_count <= 5 || disabled_count >= (total_count - scaler_count))
        status = "off";

    return status;
}

function afterScaleResult(params, command) {
    var data_table = $('#dataTable').find('tbody');
    var scale_table = $('#scaleInfoTable').find('tbody');
    var all_is_ok = true;
    data_table.html("");
    scale_table.html("");

    params.forEach(pod => {
        let icon = "fas fa-check-circle green-color";
        if (pod.success > 0) {
            icon = "fas fa-exclamation-circle red-color";
            all_is_ok = false;
        }

        scale_table.append($('<tr>')
            .append($('<td>')
                .append($('<span>')
                    .attr('class', 'robotoFont')
                    .text(pod.app)
                )
            )                                    
            .append($('<td>')
                .append($('<span>')
                    .attr('class', 'robotoFont')
                    .text(pod.status)
                )
            )
            .append($('<td>')
                .append($('<i>')
                    .attr('class', icon)
                )
            )
        );
    });
    
    if (all_is_ok) {        
        $('#scaleInfoHeader').text("Scaling result - OK ✅");
        printResponse("OK", false);
        if (command == "scale_up") {
            window.location.pathname = "/";
        }
    } else {
        $('#scaleInfoHeader').text("Scaling result - WARNING ⛔");
        printResponse("WARNING", true);
    }

    var information = new bootstrap.Modal(document.getElementById('scaleInfoModal'));
    information.show();    
}

function updateDataTable() {
    var loader = $('#dataLoader');
    var data_table = $('#dataTable').find('tbody');

    $('#sandboxStatus').text("⏳ Fetching data...");
    printResponse("...", false);

    function afterLoader() {
        postRequest("/scaler/", "/0?run_command=get_status", function(response) { 
            data_table.html("");
            var json = JSON.parse(response);
            if (json.hasOwnProperty('status') && json.status == "ok") {
                if (json.hasOwnProperty("message") && json.message.startsWith(IN_PROGRESS_STR)) {
                    printResponse(json.message, false);
                    setTimeout(afterLoader, REQUEST_INTERVAL_MS);
                    return;
                }

                printResponse(json.message, false);

                const pods = json.params.items.map(pod => {
                    const name = pod.metadata.name;
                    const first_container_image = pod.spec.containers[0].image;
                    const image_parts = first_container_image.split(":");
                    const image_tag = image_parts.length > 1 ? image_parts[1] : "latest";
                    const creation_timestamp = formatDetailedDate(pod.metadata.creationTimestamp);
                    const phase = pod.status.phase;
                    let error_text = "Unknown status";
                    let is_cron_job = false;
                    let is_scaler_pod = false;
                    let color = "red";
                    let icon = "";
                    let isok = false;

                    if (pod.status.conditions) {
                        const error_condition = pod.status.conditions.find(condition => condition.status === "False");
                        if (error_condition) {
                            error_text = error_condition.message;
                            icon = "fas fa-exclamation-triangle";
                        }
                    } else if (pod.status.containerStatuses) {
                        const waiting_status = pod.status.containerStatuses.find(status => status.state.waiting);
                        if (waiting_status) {
                            error_text = waitingStatus.state.waiting.message;
                            icon = "fas fa-exclamation-circle";
                        }
                    }

                    if (pod.metadata.labels && pod.metadata.labels["nx.sandbox.scaler"] === "false") {
                        is_scaler_pod = true;
                    }

                    if (pod.metadata.ownerReferences) {
                        is_cron_job = pod.metadata.ownerReferences.some(ref => ref.kind === "Job");
                    }

                    if (icon.length == 0) {
                        if (phase !== "Running") {
                            icon = "far fa-hourglass";
                        } else {
                            icon = "fas fa-check-circle";
                            color = "green";
                            error_text = "OK";
                            isok = true;
                        }
                    }

                    icon = icon + " " + color + "-color";

                    return {
                        name,
                        image_tag,
                        creation_timestamp,
                        is_scaler_pod,
                        is_cron_job,
                        phase,
                        error_text,
                        icon,
                        isok
                    };
                });

                const phase_order = ['Running', 'Pending', 'Failed', 'Succeeded', 'Unknown'];
                pods.sort((a, b) => {
                    const index_a = phase_order.indexOf(a.phase);
                    const index_b = phase_order.indexOf(b.phase);

                    if (index_a < index_b) {
                        return -1;
                    } else if (index_a > index_b) {
                        return 1;
                    }

                    if (a.image_tag < b.image_tag) {
                        return -1;
                    } else if (a.image_tag > b.image_tag) {
                        return 1;
                    }

                    return 0;
                });

                console.log(pods);

                pods.forEach(pod => {
                    let tr_color = pod.isok ? "table-dark" : "table-danger";
                    data_table.append($('<tr>')
                        .attr('class', tr_color)
                        .append($('<td>')
                            .append($('<span>')
                                .attr('class', 'robotoFont')
                                .text(pod.name)
                            )
                        )                                    
                        .append($('<td>')
                            .append($('<span>')
                                .attr('class', 'robotoFont')
                                .text(pod.image_tag)
                            )
                        )
                        .append($('<td>')
                            .append($('<span>')
                                .attr('class', 'robotoFont')
                                .text(pod.creation_timestamp)
                            )
                        )
                        .append($('<td>')
                            .append($('<span>')
                                .attr('class', 'robotoFont')
                                .text(pod.phase)
                            )
                        )
                        .append($('<td>')
                            .append($('<i>')
                                .attr('class', pod.icon)
                                .attr('title', pod.error_text)
                            )
                        )
                    );
                });
                
                updateScaleBtn(determineStatus(pods));                         
            }
            else {
                printResponse(json.message, true);
                updateScaleBtn("fail");  
            }

            loader.hide();
        });         
    }

    loader.show();
    data_table.html("");
    updateScaleBtn("none");
    afterLoader.defer(300)();                
}

$('#reloadStateBtn').click(function() {
    $(this).tooltip('hide');
    updateDataTable();
});

$('#scaleBtn').click(function() {
    $(this).tooltip('hide');

    var scale_btn = $('#scaleBtn');
    var status = scale_btn.attr('data-status');    
    var is_confirmation = true;
    
    if (status == "on") {        
        $('#confirmationText').text("Are you sure you want to turn OFF [🔴] the Sandbox?");
    } else if (status == "off") {
        $('#confirmationText').text("Are you sure you want to turn ON [🟢] the Sandbox?");
    } else if (status == "warning") {        
        $('#confirmationText').text("It looks like there are some troubles with the Sandbox 🚨");
        is_confirmation = false;
    } else if (status == "fail") {        
        $('#confirmationText').text("It looks like there are some troubles with the Scaler 🚑");
        is_confirmation = false;
    } else {
        return;
    }
    
    if (is_confirmation) {
        $('#confirmationHeader').text("💡 Сonfirmation");
        $('#confirmationBtns').show();
    } else {
        $('#confirmationHeader').text("ℹ️ Information");
        $('#confirmationBtns').hide();
    }
    
    var confirmation = new bootstrap.Modal(document.getElementById('confirmationModal'));
    confirmation.show();
});

$('#confirmationYes').click(function() {
    var scale_btn = $('#scaleBtn');
    var status = scale_btn.attr('data-status');
    $('#sandboxStatus').text("🔄 Processing request...");
    
    if (status == "on") {
        runCommand("scale_down", afterScaleResult);
    } else if (status == "off") {
        runCommand("scale_up", afterScaleResult);
    }
   
    var confirmation = bootstrap.Modal.getInstance(document.getElementById('confirmationModal'));
    confirmation.hide();

    updateScaleBtn("none");
});

$(document).ready(function() {
    var tooltip_trigger_list = [].slice.call(document.querySelectorAll('[data-bs-toggle="tooltip"]'))
    var tooltip_list = tooltip_trigger_list.map(function (tooltipTriggerEl) {
        return new bootstrap.Tooltip(tooltipTriggerEl)
    });

    const info_modal = document.getElementById('scaleInfoModal');
    info_modal.addEventListener('hidden.bs.modal', event => {
        $('#reloadStateBtn').click();
    });

    $('#reloadStateBtn').click();
});

function sortTable(column) {
    var current_row, next_row;
    var swapped, should_swap, swap_count = 0;
    var direction = "asc";
    do {
        swapped = false;
        var rows = document.getElementById("dataTable").rows;
        for (var i = 1; i < (rows.length - 1); i++) {
            should_swap = false;
            current_row = rows[i].getElementsByTagName("TD")[column];
            next_row = rows[i + 1].getElementsByTagName("TD")[column];
            if (direction == "asc") {
                if (current_row.innerHTML.toLowerCase() > next_row.innerHTML.toLowerCase()) {
                    should_swap = true;
                    break;
                }
            }
            else if (direction == "desc") {
                if (current_row.innerHTML.toLowerCase() < next_row.innerHTML.toLowerCase()) {
                    should_swap = true;
                    break;
                }
            }
        }
        if (should_swap) {
            rows[i].parentNode.insertBefore(rows[i + 1], rows[i]);
            swapped = true;
            swap_count++;
        }
        else {
            if (swap_count == 0 && direction == "asc") {
                direction = "desc";
                swapped = true;
            }
        }
    } while (swapped);
}
