$(document).ready(function() {
    const programStarts = [];
    const templateData = [];
    var chartData = [];
    var prevIndex = -1;
    var ctx = $('#myChart');

    $('[data-tooltip="tooltip"]').tooltip({
        trigger: 'hover'
    });

    $('.selectpicker').datepicker({
        format: 'dd/mm/yyyy'
    }).on('changeDate', function(e) {
        let id = $("#temp_select").val();

        if (programStarts.length > 0)
            programStarts.length = 0;

        if (chartData.length > 0)
            chartData.length = 0;

        let chart = Chart.getChart(ctx);
        if (chart !== undefined) {
            chart.destroy();
            showChart(id);
        }

        if ($('#statistics').is(':visible'))
            $('#statistics').hide();

        if ($('.table-div').is(':visible')) {
            $('.table-div').hide();
            $('#data-body').html('');
        }
    });

    $('#startDate').datepicker('update', new Date('2020-01-01'));
    $('#endDate').datepicker('update', new Date());

    $('[data-tooltip="tooltip"]').on('click', function() {
        $(this).tooltip('hide');
    });

    $("#temp_select").change(function() {
        if (programStarts.length > 0)
            programStarts.length = 0;

        if ($('.table-div').is(':visible')) {
            $('.table-div').hide();
            $('#data-body').html('');
        }

        if ($(this).val() !== '') {
            $('#edit_template').show();
            $('#delete_template').show();

            let chart = Chart.getChart(ctx);
            if (chart !== undefined)
                chart.destroy();

            showChart($(this).val());
        } else {
            $('#edit_template').hide();
            $('#delete_template').hide();

            chartData.length = 0;
            let chart = Chart.getChart(ctx);

            if (chart !== undefined)
                chart.destroy();

            if ($('#statistics').is(':visible'))
                $('#statistics').hide();
        }
    });

    $("#new_template").click(function() {
        $('.error').each(function() {
            $(this).parent().html('');
        });

        $(".modal-title").html("New template");
        $("#template_name").val("");

        if ($("#temp_select").val() != '') {
            getTemplate($("#temp_select").val(), false, true);
        } else {
            $("#program_version").selectpicker("val", "");
            $("#program_type").selectpicker("val", "");
            $("#product").selectpicker("val", "");
            $("#country_code").selectpicker("val", "");
            $("#interval").selectpicker("val", "");
            $("#chart_type").selectpicker("val", "bar");
        }
    });

    $("#edit_template").click(function() {
        $('.error').each(function() {
            $(this).parent().html('');
        });

        $(".modal-title").html("Edit template");

        let id = $("#temp_select").val();
        getTemplate(id, true, false);
    });

    $("#delete_template").click(function() {
        if (confirm("Are you sure want to delete this template?") == true) {
            let id = $("#temp_select").val();
            deleteTemplate(id);
        }
    });

    $("#product").change(function() {
        if ($(this).val() == 2) {
            $("#type-div").hide();
            $("#ctr-div").hide();
        } else {
            $("#type-div").show();
            $("#ctr-div").show();
        }
    });

    $("#dist_select").change(function () {
        let chart = Chart.getChart(ctx);
        
        if (chart !== undefined) {
            if (programStarts.length > 0)
                programStarts.length = 0;

            chart.destroy();
            showChart($("#temp_select").val());
            $('.table-div').hide();
            $('#data-body').html('');
        }
    });

    $('#edit-template-btn').on('click', function(e) {
        e.preventDefault();

        if (validateForm('template-form')) {
            saveTemplate();

            if ($('.table-div').is(':visible')) {
                $('.table-div').hide();
                $('#data-body').html('');
            }

            $('#editTemplateModal').modal('hide');
        }
    });

    $(".sorted").click(function() {
        let id = $(this).attr('id');

        if ($(this).attr("data-order") == 'asc') {
            $(this).attr("data-order", 'desc');
            $(this).children().removeClass("fa-sort-amount-asc");
            $(this).children().addClass("fa-sort-amount-desc");
        } else {
            $(this).attr("data-order", 'asc');
            $(this).children().addClass("fa-sort-amount-asc");
            $(this).children().removeClass("fa-sort-amount-desc");
        }

        $('.sorted').each(function() {
            if ($(this).attr('id') != id && $(this).attr("data-order") != 'asc') {
                $(this).attr("data-order", '');
                $(this).children().addClass("fa-sort-amount-desc");
                $(this).children().removeClass("fa-sort-amount-asc");
            }

            if ($(this).attr('id') != id)
                $(this).children().hide();
            else
                $(this).children().show();
        });

        let name = $(this).attr("id") + '-' + $(this).attr("data-order");
        sort(name);
    });

    $("#appearance").change(function() {
        document.cookie = "appearance="+$(this).val()+"; expires=Fri, 31 Dec 9999 23:59:59 GMT";

        let id = $("#temp_select").val();

        populateSelect();

        if (id !== '') {
            if ($('.table-div').is(':visible')) {
                $('.table-div').hide();
                $('#data-body').html('');
            }

            let chart = Chart.getChart(ctx);
            if (chart !== undefined)
                chart.destroy();

            showChart(id);
        }
    });

    $.fn.serializeObject = function() {
        var o = {};
        var a = this.serializeArray();
        $.each(a, function() {
            if (o[this.name] !== undefined) {
                if (!o[this.name].push) {
                    o[this.name] = [o[this.name]];
                }
                o[this.name].push(this.value || '');
            } else {
                o[this.name] = this.value || '';
            }
        });
        return o;
    };

    function populateSelect() {
        let complex = getCookie('appearance') == 2;
        let option  = '<option value="0">All time</option>';

        if (!complex) {
            option += '<option value="1">Last week</option>';
            option += '<option value="2">Last 2 weeks</option>';
            option += '<option value="3">Last month</option>';
            option += '<option value="4">Last 2 months</option>';
            option += '<option value="5">Last 3 months</option>';
            option += '<option value="6">Last 6 months</option>';
            option += '<option value="7">Last year</option>';
            option += '<option value="8">Last 2 years</option>';
        } else {
            option += '<option value="1">Last week only</option>';
            option += '<option value="2">In the penultimate week</option>';
            option += '<option value="3">3 and 4 weeks ago only</option>';
            option += '<option value="4">In the penultimate month</option>';
            option += '<option value="5">3 month ago only</option>';
            option += '<option value="6">Between 4 and 6 months only</option>';
            option += '<option value="7">Between 7 and 12 months only</option>';
            option += '<option value="8">In the penultimate year</option>';
        }

        option += '<option value="9">3 years ago</option>';

        $('#interval')
            .find('option')
            .remove()
            .end()
            .append(option);

        $('#interval').selectpicker('refresh');
    }

    function getCookie(cname) {
        let name = cname + "=";
        let decodedCookie = decodeURIComponent(document.cookie);
        let ca = decodedCookie.split(';');
        for(let i = 0; i <ca.length; i++) {
          let c = ca[i];
          while (c.charAt(0) == ' ') {
            c = c.substring(1);
          }
          if (c.indexOf(name) == 0) {
            return c.substring(name.length, c.length);
          }
        }
        return "";
      }

    function getErrorMessage(element) {
        const errorArray = {
            "template_name": {
                "msg": "Please enter a name",
                "id": "name-error"
            },
            "product": {
                "msg": "Please select a product",
                "id": "product-error"
            },
            "interval": {
                "msg": "Please select an interval",
                "id": "interval-error"
            },
            "program_version": {
                "msg": "Please select a version",
                "id": "version-error"
            },
            "program_type": {
                "msg": "Please select a type",
                "id": "type-error"
            },
            "country_code": {
                "msg": "Please select a country code",
                "id": "country-code-error"
            }
        };

        return errorArray[element];
    }

    function getFormData(formid) {
        var form = document.getElementById(formid);
        let formdata = {};
        Array.from(form.querySelectorAll('input, select, textarea'))
            .filter(element => element.name)
            .forEach(element => {
                if (element.type === 'checkbox') {
                    formdata[element.name] = element.checked;
                } else if (element.options) {
                    var selected = [...element.selectedOptions].map(option => option.value);
                    if (selected.length > 1) {
                        formdata[element.name] = selected;
                    } else {
                        formdata[element.name] = element.value;
                    }
                } else {
                    formdata[element.name] = element.value;
                }
            });
        return formdata;
    }

    function validateForm(form) {
        let formData = getFormData(form);
        let error = '';
        let valid = true;

        for (const [key, value] of Object.entries(formData)) {
            if (key == 'template_id' || key == 'chart_type')
                continue;

            if (formData.product == '2' && (key == 'product' || key == 'country_code' || key == 'program_type'))
                continue;

            error = getErrorMessage(key);

            if (value == '') {
                $('#' + error.id).html('<label class="error" for="error">' + error.msg + '</label>');

                valid = false;
            } else {
                $('#' + error.id).html('');
            }
        }
        return valid;
    }

    function getLabels(interval) {
        let intervalNames = [];

        for (let i = 1; i <= interval; i++) {
            const opt = i == 10 ? '3+ year ago' : $('#interval option[value="' + i + '"]').html();

            intervalNames.push(opt);
        }
        return intervalNames;
    }

    function getSelectedLabel(id) {
        return id == 10 ? '3+ year ago' : $('#interval option[value="' + id + '"]').html();
    }

    function showChart(temp_id) {
        let distID = $("#dist_select").val() != undefined ? $("#dist_select").val() : '';
        let fromDate = dateFormat($('#startDate').datepicker('getDate'), 'yyyy-MM-dd');
        let endDate = dateFormat($('#endDate').datepicker('getDate'), 'yyyy-MM-dd');

        $.ajax({
            type: "POST",
            url: "/trialusage/getProgramStarts",
            data: {
                tmpID: temp_id,
                distID: distID,
                fromDate: fromDate,
                endDate: endDate
            },
            success: function(data) {
                checkSession();

                let response            = JSON.parse(data);
                let allProgramStarts    = response.programs.length;
                let complex             = getCookie('appearance') == 2;

                console.log(response.query);

                chartData = new Array(parseInt(response.interval)).fill(0);

                const intervalNames = getLabels(parseInt(response.interval));

                $.each(response.programs, function(index, element) {
                    if (programStarts[index] == undefined)
                        programStarts[index] = {};

                    let workingHour = element.workingMinutes == null ? 0 : parseInt(element.workingMinutes) / 60;

                    programStarts[index]['usPwd']       = element.usPwd;
                    programStarts[index]['startSum']    = element.startSum;
                    programStarts[index]['lastUsage']   = element.lastUsage;
                    programStarts[index]['trialUsage']  = element.trialUsage;
                    programStarts[index]['workingHour'] = workingHour;

                    for (let i = 0; i < chartData.length; i++) {
                        if (complex) {
                            if (element.trialUsage - 1 == i)
                                chartData[i] += 1;
                        } else {
                            if (element.trialUsage - 1 <= i)
                                chartData[i] += 1;
                        }
                    }
                });

                let myChart = new Chart(ctx, {
                    type: response.chart,
                    data: {
                        labels: intervalNames,
                        datasets: [{
                            label: '',
                            data: chartData,
                            backgroundColor: [
                                '#B22222',
                                '#228B22',
                                '#00BFFF',
                                '#008B8B',
                                '#2F4F4F',
                                '#DAA520',
                                '#778899',
                                '#FFE4B5',
                                '#9ACD32',
                                '#E0FFFF'
                            ],
                            hoverOffset: 4
                        }]
                    },
                    options: {
                        onClick: function(evt, chartElement) {
                            if (chartElement.length > 0 && (prevIndex != chartElement[0].index || !$('.table-div').is(':visible'))) {
                                let usageID = chartElement[0].index + 1;
                                const serials = [];

                                if ($('.table-div').is(':visible')) {
                                    $('.table-div').hide();
                                    $('#data-body').html('');
                                }

                                $('#data-body').html('');

                                for (let i = 0; i < programStarts.length; i++) {
                                    const element = programStarts[i];

                                    if (complex) {
                                        if (usageID == element.trialUsage) {
                                            if (serials[element.usPwd] == undefined)
                                                serials[element.usPwd] = {};
    
                                            serials[element.usPwd]['lastUsage'] = element.lastUsage;
                                            serials[element.usPwd]['startSum'] = element.startSum;
                                            serials[element.usPwd]['workingHour'] = element.workingHour;
                                        }
                                    } else {
                                        if (usageID >= element.trialUsage) {
                                            if (serials[element.usPwd] == undefined)
                                                serials[element.usPwd] = {};
    
                                            serials[element.usPwd]['lastUsage'] = element.lastUsage;
                                            serials[element.usPwd]['startSum'] = element.startSum;
                                            serials[element.usPwd]['workingHour'] = element.workingHour;
                                        }
                                    }
                                }
                                getUsers(serials);

                                prevIndex = chartElement[0].index;

                                let objLength = Object.keys(serials).length;

                                $('#table-label').html(getSelectedLabel(usageID) + ' ('+objLength+')');

                                templateData.length = 0;
                            }
                        },
                        onHover: function(evt, chartElement) {
                            evt.native.target.style.cursor = chartElement[0] ? 'pointer' : 'default';
                        }
                    }
                });

                $('#program_starts').html(allProgramStarts);

                if ($('#statistics').is(':hidden'))
                    $('#statistics').show();
            }
        });
    }

    function dateFormat(inputDate, format) {
        const date = new Date(inputDate);
        const day = date.getDate();
        const month = date.getMonth() + 1;
        const year = date.getFullYear();

        format = format.replace("MM", month.toString().padStart(2, "0"));

        if (format.indexOf("yyyy") > -1)
            format = format.replace("yyyy", year.toString());
        else if (format.indexOf("yy") > -1)
            format = format.replace("yy", year.toString().substr(2, 2));

        format = format.replace("dd", day.toString().padStart(2, "0"));

        return format;
    }

    function saveTemplate() {
        let $form = $("#template-form");

        let template = JSON.stringify({
            template: $form.serializeObject()
        });

        $.ajax({
            type: "POST",
            url: "/trialusage/saveTemplate",
            data: {
                data: template
            },
            success: function(data) {
                checkSession();

                let response = JSON.parse(data);

                if (response.newName && !response.addOption)
                    $('#temp_select option[value="' + response.temp_id + '"]').html(response.newName)

                if (response.addOption) {
                    $('#temp_select').append(`<option value="${response.temp_id}">${response.newName}</option>`);
                    $('#temp_select option[value="' + response.temp_id + '"]').attr('selected', true);
                    $('#edit_template').show();
                    $('#delete_template').show();
                }

                let chart = Chart.getChart(ctx);
                if (chart !== undefined)
                    chart.destroy();

                showChart(response.temp_id);
            }
        });
    }

    function deleteTemplate(id) {
        $.ajax({
            url: "/trialusage/deleteTemplate",
            type: "POST",
            data: {
                id: id
            },
            success: function(response) {
                checkSession();

                let data = JSON.parse(response);

                $("#temp_select option[value='" + data.tmpID + "']").remove();
                $('#edit_template').hide();
                $('#delete_template').hide();

                if ($('.table-div').is(':visible')) {
                    $('.table-div').hide();
                    $('#data-body').html('');
                }

                let chart = Chart.getChart(ctx);
                if (chart !== undefined)
                    chart.destroy();
            }
        });
    }

    function getTemplate(id, needName, newTmp) {
        $.ajax({
            url: "/trialusage/getTemplate",
            type: "POST",
            data: {
                id: id
            },
            success: function(response) {
                checkSession();

                let verArray = [];
                let typeArray = [];
                let ctrArray = [];

                let data = JSON.parse(response);
                let template = data.template;

                if (newTmp)
                    $("#template_id").val("");
                else
                    $("#template_id").val(data.tmp_id);

                if (needName)
                    $("#template_name").val(template.name);

                if (template.product == 2) {
                    $("#type-div").hide();
                    $("#ctr-div").hide();
                } else {
                    $("#type-div").show();
                    $("#ctr-div").show();
                }

                $(".selectpicker option").attr("selected", false);

                if (template.versions) {
                    $.each(template.versions, function(index, value) {
                        verArray.push(value);
                    });
                }

                if (template.types) {
                    $.each(template.types, function(index, value) {
                        typeArray.push(value);
                    });
                }

                if (template.country_code) {
                    $.each(template.country_code, function(index, value) {
                        ctrArray.push(value);
                    });
                }

                if ($("#chart_type").length) {
                    if (template.chart_type)
                        $("#chart_type").selectpicker("val", template.chart_type);
                    else
                        $("#chart_type").selectpicker("val", "bar");
                }

                $("#program_version").selectpicker("val", verArray);
                $("#program_type").selectpicker("val", typeArray);
                $("#product").selectpicker("val", template.product);
                $("#country_code").selectpicker("val", ctrArray);
                $("#interval").selectpicker("val", template.interval);
            }
        });
    }

    function SortByUserName(a, b) {
        let aName = a.userName;
        let bName = b.userName;
        return ((aName < bName) ? -1 : ((aName > bName) ? 1 : 0));
    }

    function SortBySaleDate(a, b) {
        let date1 = new Date(a.sellDate);
        let date2 = new Date(b.sellDate);
        return ((date1.getTime() < date2.getTime()) ? -1 : ((date1.getTime() > date2.getTime()) ? 1 : 0));
    }

    function SortByLastUse(a, b) {
        let date1 = new Date(a.lastUsage);
        let date2 = new Date(b.lastUsage);
        return ((date1.getTime() < date2.getTime()) ? -1 : ((date1.getTime() > date2.getTime()) ? 1 : 0));
    }

    function SortByStarts(a, b) {
        return a.startSum - b.startSum;
    }

    function SortByWt(a, b) {
        return a.workingHour - b.workingHour;
    }

    function sort(name) {
        let dataBody = '';

        switch (name) {
            case "name-asc":
                templateData.sort(SortByUserName);
                break;

            case "name-desc":
                templateData.sort(SortByUserName).reverse();
                break;

            case "sale_date-asc":
                templateData.sort(SortBySaleDate);
                break;

            case "sale_date-desc":
                templateData.sort(SortBySaleDate).reverse();
                break;

            case "last_use-asc":
                templateData.sort(SortByLastUse);
                break;

            case "last_use-desc":
                templateData.sort(SortByLastUse).reverse();
                break;

            case "starts-asc":
                templateData.sort(SortByStarts);
                break;

            case "starts-desc":
                templateData.sort(SortByStarts).reverse();
                break;

            case "wt-asc":
                templateData.sort(SortByWt);
                break;

            case "wt-desc":
                templateData.sort(SortByWt).reverse();
                break;

            default:
                break;
        }

        if (templateData.length > 0) {
            for (let i = 0; i < templateData.length; i++) {
                const element = templateData[i];
                let crm_url = $('#crm_url').val();
                let hlNum = element.serial.substr(0, 6);;

                let workingHour = element.workingHour;

                if (decimalCount(workingHour) > 2)
                    workingHour = workingHour.toFixed(2);

                dataBody += '<tr>';

                if (element.userID && crm_url != '')
                    dataBody += '<td><a href="'+crm_url+element.userID+'" target="_blank">' + element.customName + '</a></td>';
                else
                    dataBody += '<td><a href="https://partners.archlinexp.com/partners/key/'+hlNum+'" target="_blank">' + element.customName + '</a></td>';

                dataBody += '<td>' + element.sellDate + '</td>';
                dataBody += '<td>' + element.lastUsage + '</td>';
                dataBody += '<td>' + element.startSum + '</td>';
                dataBody += '<td>' + workingHour + '</td>';
                dataBody += '</tr>';
            }
            $('#data-body').html(dataBody);
        }
    }

    const decimalCount = num => {
        const numStr = String(num);

        if (numStr.includes('.'))
           return numStr.split('.')[1].length;

        return 0;
     }

    function getUsers(serials) {
        let keys = Object.keys(serials);
        let jsonString = JSON.stringify(keys);

        $.ajax({
            type: "POST",
            url: "/trialusage/getUsersFromPassword",
            data: {
                data: jsonString,
                tmpID: $("#temp_select").val()
            },
            success: function(data) {
                checkSession();

                let dataBody = '';
                let response = JSON.parse(data);
                var needSort = false;

                $.each(response.users, function(index, user) {
                    let serialData  = serials[user.prPass];
                    let crm_url     = $('#crm_url').val();
                    let userID      = user.nUserID != null ? user.nUserID : user.userID;
                    let hlNum       = user.prPass.substr(0, 6);
                    let customName  = '';

                    if (response.name_string) {
                        customName  = response.name_string.replace("%n", user.strName);
                        customName  = customName.replace("%k", hlNum);
                        customName  = customName.replace("%e", user.email);
                    } else {
                        customName = user.strName;
                    }

                    let workingHour = serialData.workingHour;

                    if (decimalCount(workingHour) > 2)
                        workingHour = workingHour.toFixed(2);

                    dataBody += '<tr>';

                    if (userID != null && crm_url != '')
                        dataBody += '<td><a href="'+crm_url+userID+'" target="_blank">' + customName + '</a></td>';
                    else
                        dataBody += '<td><a href="https://partners.archlinexp.com/partners/key/'+hlNum+'" target="_blank">' + customName + '</a></td>';

                    dataBody += '<td>' + user.prSellDate + '</td>';
                    dataBody += '<td>' + serialData.lastUsage + '</td>';
                    dataBody += '<td>' + serialData.startSum + '</td>';
                    dataBody += '<td>' + workingHour + '</td>';
                    dataBody += '</tr>';

                    templateData[index] = {
                        userName: user.strName,
                        sellDate: user.prSellDate,
                        lastUsage: serialData.lastUsage,
                        startSum: serialData.startSum,
                        workingHour: serialData.workingHour,
                        userID: userID,
                        serial:user.prPass,
                        customName: customName
                    };
                });

                $('.sorted').each(function() {
                    if ($(this).attr('data-order') != '') {
                        let id = $(this).attr('id');
                        let order = $(this).attr('data-order');
                        sort(id + '-' + order);

                        needSort = true;
                    }
                });

                if (!needSort)
                    $('#data-body').html(dataBody);

                if ($('.table-div').is(':hidden'))
                    $('.table-div').slideDown();
            }
        });

        function checkSession() {
            $.post("/resourcemanager/isSessionActive", {

            }, function(data) {
                let response = JSON.parse(data);

                if (!response.active) {
                    alert('Your session is expired. Please login.');
                    location.reload();
                }
            });
        }
    }
});