let searchReleases = [];
let searchProductArea = [];
let searchProduct = [];
let searchType = [];
let searchFields = [];
let searchFieldsText;
let searchFuzzy;
let defaultProduct = 'X3';
//return only unique values from an array
function onlyUnique(value, index, self) {
    return self.indexOf(value) === index;
}
////refactor here
function toggleColVis(table) {
    $('a.toggle-vis').on('click', function (e) {
        e.preventDefault();

        // Get the column API object
        var column = table.column($(this).attr('data-column'));

        // Toggle the visibility
        column.visible(!column.visible());
        $(this).css('font-weight', column.visible() ? 'bold' : 'normal');
    });
}

function cleanDiv() {
    searchReleases = [];
    searchProductArea = [];
    searchProduct = [];
    searchType = [];
    searchFields = [];
    searchFieldsText;
    searchFuzzy = '';

    $('#table').empty();
}

function getSearchProduct() {
    searchProduct = [];
    $("input[name='searchProduct']").each(function (index, elem) {
        if ($(elem).prop('checked')) searchProduct.push($(elem).val());
    });
    return searchProduct;
}

function getSearchReleases() {
    searchReleases = [];
    $('#searchReleases' + getSearchProduct()).each(function (index, elem) {
        searchReleases.push($(elem).val());
    });
    return searchReleases;
}

function getSearchType() {
    searchType = [];
    $("input[name='searchType']").each(function (index, elem) {
        if ($(elem).prop('checked')) {
            searchType.push($(elem).val());
        }
    });
    return searchType;
}

function getSearchFuzzy() {
    searchFuzzy = 0.2;
    $("input[name='searchFuzzy']").each(function (index, elem) {
        searchFuzzy = $(elem).prop('checked');
    });
    return searchFuzzy;
}

function getSearchFields() {
    searchFields = [];
    $("input[name='searchFields']").each(function (index, elem) {
        if ($(elem).prop('checked')) {
            searchFields.push($(elem).val());
        }
    });
    return searchFields;
}

function getSearchFieldsText() {
    searchFieldsText = '';
    searchFieldsText = $("input[name='searchFieldsText']").val();

    return encodeURIComponent(searchFieldsText);
}

function getSearchProductArea() {
    searchProductArea = [];
    $("input[name='searchProductArea']").each(function (index, elem) {
        if ($(elem).prop('checked')) {
            searchProductArea.push($(elem).val());
        }
    });
    return searchProductArea;
}

function createProductAreaInputs(arr) {
    let n = 0;
    let html = '';
    let printedProductArea = 0;
    let nullExists = 0;
    let maxBoxCol = 3;

    arr.forEach(element => {
        if (n == 0) html += '<div class="col-sm-3">';
        n++;
        if (element != null) {
            switch (element) {
                case 'Cloud Platforms':
                    break;
                case 'Automated Testing':
                    break;
                case 'Platform':
                    html +=
                        '<input type=checkbox  class="big-checkbox"  name="searchProductArea"  value="Cloud Platforms,Platform, Automated Testing" checked><label>Platform</label><br>';
                    printedProductArea++;
                    break;
                default:
                    html +=
                        '<input type=checkbox  class="big-checkbox"  name="searchProductArea"  value="' +
                        element +
                        '" checked><label>' +
                        element +
                        '</label><br>';
                    printedProductArea++;
            }
        } else nullExists++;

        if (printedProductArea == maxBoxCol) {
            html += '</div><div class="col-sm-3">';
            printedProductArea = 0;
        }

        if (n == arr.length) {
            if (nullExists != 0) {
                html +=
                    '<input type=checkbox  class="big-checkbox"  name="searchProductArea"  value="null" checked style="visibility:hidden"><label></label><br>';
            }
            html += '</div>';
        }
    });
    document.getElementById('searchModuleDiv').insertAdjacentHTML('beforeend', html);
}

function createTypeInputs(arr) {
    let n = 0;
    let printedTypes = 0;
    let otherExists = 0;
    let maxBoxCol = 3;
    let html = '';

    arr.forEach(element => {
        if (n == 0) html += '<div class="col-sm-3">';
        n++;
        switch (element) {
            case 'Improvement':
                break;
            case 'Enhancement':
                html +=
                    '<input type=checkbox  class="big-checkbox"  name="searchType"  value="Epic,Improvement" checked>' +
                    '<label>Enhancement</label><br>';
                printedTypes++;
                break;
            case 'Bug Story':
            case 'Hotfix':
            case 'Automated Test':
            case 'Support':
            case 'Task':
            case 'Story':
            case 'Unknown':
            case 'Assistance':
            case 'Enhancement request':
            case 'Cloud Service':
                otherExists++;
                break;
            default:
                html +=
                    '<input type=checkbox  class="big-checkbox"  name="searchType"  value="' +
                    element +
                    '" checked><label>' +
                    element +
                    '</label><br>';
                printedTypes++;
        }
        if (printedTypes == maxBoxCol) {
            html += '</div><div class="col-sm-3">';
            printedTypes = 0;
        }
        if (n == arr.length) {
            if (otherExists != 0) {
                html +=
                    '<input type=checkbox  class="big-checkbox"  name="searchType"  value="Story,Bug Story,Automated Test,Support,Task,Unknown,Assistance,Enhancement request,Cloud Service" checked>' +
                    '<label>Others</label><br>';
            }
            html += '</div>';
        }
    });
    document.getElementById('searchCriteria').insertAdjacentHTML('beforeend', html);
}

function sortByName(a, b) {
    var nameA = a.name.toUpperCase(); // ignore upper and lowercase
    var nameB = b.name.toUpperCase(); // ignore upper and lowercase
    if (nameA < nameB) {
        return -1;
    }
    if (nameA > nameB) {
        return 1;
    }

    // names must be equal
    return 0;
}
//create the ranged sliders (applied to each product)
function createSlider(arr, element) {
    arr.sort(sortByName);

    let productTabId = element.replace(/\s/g, '');
    return new Promise(function (resolve, reject) {
        let html = '';
        searchReleases = [];
        //console.log ("create sliders")
        let productName;
        switch (element) {
            case 'X3':
                productName = 'Sage X3';
                break;
            case 'HR':
                productName = 'Sage X3 HR & Payroll';
                break;
            case 'WH':
                productName = 'Sage X3 Warehousing';
                break;

            default:
                break;
        }

        html +=
            "<div class='row releaseLine '><div class='col-xs-3 form-check  form-check-inline'>" +
            '<input id ="' +
            element +
            '" class="form-check-input" name="searchProduct" type="radio" value ="' +
            element +
            '" ' +
            (element == defaultProduct ? 'checked' : '') +
            ' ><label  class="form-check-label" for ="' +
            element +
            '">' +
            productName +
            ' </label></div>' +
            " <div class='col-xs-5'> <div name='slider-range' class='slider-range' id='slider-range" +
            productTabId +
            "'></div>";
        html +=
            '     </div><div class="col-xs-4">       <div   class="rangeSearchDisplay" style="width:320px;" id="amount' +
            productTabId +
            '"  "></div> </div>';
        html +=
            '  <input name="searchReleases" type="text" hidden=true id="searchReleases' +
            productTabId +
            '" readonly"></div>';
        document.getElementById('searchReleaseDiv').insertAdjacentHTML('beforeend', html);

        $(function () {
            $('#slider-range' + productTabId).slider({
                range: false,
                min: 0,
                max: arr.length - 1,
                values: [0, arr.length - 1],

                slide: function (event, ui) {
                    let minIdx = ui.values[0];
                    var maxIdx = ui.values[1];
                    if (minIdx > maxIdx) {
                        let tmpIdx = iReleaseMin;
                        tmpIdx = minIdx;
                        minIdx = maxIdx;
                        maxIdx = tmpIdx;
                    }

                    minVal = arr[minIdx]['name'];
                    maxVal = arr[maxIdx]['name'];

                    $('#amount' + productTabId).html(
                        'From <strong>' + minVal + '</strong> to <strong>' + maxVal + '</strong>',
                    );

                    searchReleases = [];
                    for (let i = minIdx; i <= maxIdx; i++) {
                        searchReleases.push(arr[i].name);
                    }
                    $('#searchReleases' + productTabId).val(searchReleases);

                    setTimeout(function () {
                        if (arr[ui.values[0]]['name'] < arr[ui.values[1]]['name']) {
                            minVal = arr[ui.values[0]]['name'];
                            maxVal = arr[ui.values[1]]['name'];
                            $('#slider-range' + productTabId)
                                .children('.ui-slider-handle')
                                .first()
                                .attr('title', minVal)
                                .tooltip('fixTitle')
                                .tooltip('show');
                            $('#slider-range' + productTabId)
                                .children('.ui-slider-handle')
                                .last()
                                .attr('title', maxVal)
                                .tooltip('fixTitle')
                                .tooltip('show');
                        } else {
                            minVal = arr[ui.values[1]]['name'];
                            maxVal = arr[ui.values[0]]['name'];
                            $('#slider-range' + productTabId)
                                .children('.ui-slider-handle')
                                .last()
                                .attr('title', minVal)
                                .tooltip('fixTitle')
                                .tooltip('show');
                            $('#slider-range' + productTabId)
                                .children('.ui-slider-handle')
                                .first()
                                .attr('title', maxVal)
                                .tooltip('fixTitle')
                                .tooltip('show');
                        }
                    }, 50);
                },
            });

            var iReleaseMin = $('#slider-range' + productTabId).slider('values', 0);
            var iReleaseMax = $('#slider-range' + productTabId).slider('values', 1);

            var releaseMin = arr[iReleaseMin]['name'];
            var releaseMax = arr[iReleaseMax]['name'];

            $('#slider-range' + productTabId).ready(function () {
                {
                    $(function () {
                        $('[data-toggle="tooltipRange"]').tooltip({
                            trigger: 'manual',
                            animation: false,
                        });
                        $('[data-toggle="tooltipRange"]').tooltip('show');
                    });
                }
            });

            $('#slider-range' + productTabId)
                .children('.ui-slider-handle')
                .first()
                .attr('data-toggle', 'tooltipRange');
            $('#slider-range' + productTabId)
                .children('.ui-slider-handle')
                .first()
                .attr('title', releaseMin);
            $('#slider-range' + productTabId)
                .children('.ui-slider-handle')
                .last()
                .attr('data-toggle', 'tooltipRange');
            $('#slider-range' + productTabId)
                .children('.ui-slider-handle')
                .last()
                .attr('title', releaseMax);

            //display releases value according to  sliders' values
            $('#amount' + productTabId).html(
                'From <strong>' + releaseMin + '</strong> to <strong>' + releaseMax + '</strong>',
            );

            // add the span element to the handle

            searchReleases = [];
            for (let i = iReleaseMin; i <= iReleaseMax; i++) {
                searchReleases.push(arr[i].name);
            }

            $('#searchReleases' + productTabId).val(searchReleases);
        });
        resolve();
    });
}

function createDatatable(json) {
    console.info(json);

    return new Promise(function (resolve, reject) {
        var today = new Date();
        var date = today.getFullYear() + '-' + (today.getMonth() + 1) + '-' + today.getDate();
        var exportFileName = 'Patchfinder results  ' + date;

        var table = $('#table').DataTable({
            data: json,
            destroy: true,
            columns: [
                {
                    data: 'key',
                },
                {
                    data: 'issueType',
                    render: function (data, type, full) {
                        switch (data) {
                            case 'Epic':
                            case 'Improvement':
                                return 'Enhancement';
                            case 'Bug Story':
                            case 'Hotfix':
                            case 'Story':
                            case 'Task':
                            case 'Support':
                            case 'Automated Test':
                            case 'Unknown':
                            case 'Assistance':
                            case 'Cloud Service':
                            case 'Enhancement request':
                                return 'Others';
                            default:
                                return data;
                        }
                    },
                },
                {
                    data: 'summary',
                },
                {
                    data: 'solutionDetails',
                },
                {
                    data: 'productArea',
                    render: function (data, type, full) {
                        switch (data) {
                            case 'Cloud Platforms':
                            case 'Platform':
                            case 'Automated Testing':
                                return 'Platform';
                            default:
                                return data;
                        }
                    },
                },
                {
                    data: 'objects',

                    render: function (data, type, full) {
                        return (
                            '<ul>' +
                            $.map(data, function (d, i) {
                                return '<li>' + d.meta + '/' + d.name + '</li> ';
                            }).join('') +
                            '</ul>'
                        );
                    },
                },
                {
                    data: 'fixVersion',
                },
                {
                    data: 'behaviourChange',
                    render: function (data, type, full) {
                        return data == true ? 'Yes' : 'No';
                    },
                },
            ],
            columnDefs: [
                {
                    title: 'Key',
                    targets: 0,
                    orderable: true,
                    type: 'html-num-fmt',
                },
                {
                    title: 'Type',
                    targets: 1,
                    orderable: false,
                },
                {
                    title: 'Summary',
                    targets: 2,
                    orderable: false,
                },
                {
                    title: 'Solution details',
                    targets: 3,
                    orderable: false,
                },
                {
                    title: 'Product area',
                    targets: 4,
                    orderable: true,
                },
                {
                    title: 'Objects',
                    targets: 5,
                    orderable: false,
                },
                {
                    title: 'Release',
                    targets: 6,
                    orderable: true,
                },
                {
                    title: 'Behavior Change',
                    targets: 7,
                    orderable: true,
                },
            ],

            mark: {
                wildcards: 'enabled',
            },

            dom: 'Bfrtip',
            buttons: [
                {
                    extend: 'copy',
                    title: '',
                },
                {
                    extend: 'csv',
                    title: exportFileName,
                },
                {
                    extend: 'excel',
                    title: exportFileName,
                },
                {
                    extend: 'pdf',
                    title: exportFileName,
                },
                'print',
            ],
            responsive: true,
            pageLength: 50,
            paging: true,

            fixedHeader: {
                header: true,
                footer: true,
            },
            oLanguage: {
                sSearch:
                    '<i id = "searchIcon"class="glyphicon glyphicon-search" title="Filter and highlight results" "></i>',
                sSearchPlaceholder: 'Filter and highlight results...',
                sLengthMenu: 'Show _MENU_',
                sInfo: 'Showing _START_ to _END_ of _TOTAL_ results',
            },

            dom: '<"top"Biflp<"clear">>rt<"bottom"ip<"clear">>',

            //uncomment for live column search
            /*
                "fnInitComplete": function(oSettings, json) {
                    
                    $('#table thead th').each( function () {
                        var title=$(this).html()
                        $(this).html( '<input type="text" placeholder="Search '+title+'" />' );
                    } );
                    $('#table tfoot tr').appendTo('#table thead');
                    
                }*/

            fnInitComplete: function (oSettings, json) {
                $('.sorting_asc').click(function () {
                    $.fn.dataTable.ext.type.order['html-num-fmt-pre'] = function (data) {
                        data = data.replace(/X3-/g, '');

                        return data * 1;
                    };
                });
            },
        });

        resolve(table);
    });
}

function updateTable(table) {
    // Apply column search
    table.columns().every(function () {
        var that = this;
        $('input', this.header()).on('keyup change clear', function () {
            if (that.search() !== this.value) {
                that.search(this.value).draw();
            }
        });
    });
}

function generateReleaseForm() {
    return new Promise(function (resolve, reject) {
        ////CREATE FORM DYNAMICALLY WHEN  GETTING RELEASES JSON

        var listProducts = [];
        var listReleases = [];
        var listReleasesAllProduct = [];
        var listReleasesAllProductArea = [];
        var listAllTypes = [];
        var listTechnicalComponents = [];

        $.get('http://localhost:3000/releasesload').done(function (data) {
            //console.log(listReleasesAllProductArea)

            if (
                data.filter(obj => {
                    return obj.product === 'X3';
                }).length == 0
            ) {
                //set the first one by default (no spec)
                defaultProduct = data[0]['product'];
            }

            data.forEach(element => {
                // console.log(element)
                listReleases.push(element);
                listProducts.push(element.product);

                if (element.product == defaultProduct) {
                    element.items.forEach(issue => {
                        listReleasesAllProductArea.push(issue.productArea);
                        if (issue.issueType == 'Epic') listAllTypes.push('Enhancement');
                        else listAllTypes.push(issue.issueType);
                    });
                }

                if (element.name === 'technicalComponents') {
                    element.releases.forEach(release => {
                        listTechnicalComponents.push(release);
                    });
                }
            });

            createTechnicalComponentsGrid(listTechnicalComponents);

            listProducts = listProducts.filter(onlyUnique);

            listReleasesAllProductArea = listReleasesAllProductArea.filter(onlyUnique);

            createProductAreaInputs(listReleasesAllProductArea);

            listAllTypes = listAllTypes.filter(onlyUnique);
            createTypeInputs(listAllTypes);

            listProducts.forEach(element => {
                var listReleasesProduct = [];
                listReleases.forEach(release => {
                    if (release.product == element) {
                        listReleasesProduct.push(release);
                    }
                });
                listReleasesAllProduct.push(listReleasesProduct);

                createSlider(listReleasesProduct, element).then(
                    $("input[name='searchProduct']").change(function () {
                        $('#searchModuleDiv').empty();
                        $('#searchCriteria').empty();
                        let productAreas = [];
                        let types = [];
                        data.forEach(element => {
                            if (element.product == $(this).val()) {
                                element.items.forEach(issue => {
                                    productAreas.push(issue.productArea);
                                    if (issue.issueType == 'Epic') types.push('Enhancement');
                                    else types.push(issue.issueType);
                                });
                            }
                        });
                        productAreas = productAreas.filter(onlyUnique);
                        createProductAreaInputs(productAreas);
                        types = types.filter(onlyUnique);
                        createTypeInputs(types);
                    }),
                );
            });
        });
        resolve();
    });
}

function createTechnicalComponentsGrid(releases) {
    return new Promise(function (resolve, reject) {
        formatComponents(releases);
        componentTitles = [];
        releases[0].components.forEach(component => {
            componentTitles.push(component.name);
        });
    console.info(componentTitles);

        var grid = $('#technicalComponentsGrid').DataTable({
            data: releases,
            destroy: true,
            responsive: true,
            paging: false,
            searching: false,
            ordering: false,
            info: false,
            columns: [
                { data: 'name', title: 'Release' },
                { data: 'date', title: 'Date' },
                {
                    // Syracuse
                    data: 'components.8.version',
                    title: componentTitles[8],
                    render: function (data, type, row, meta) {
                        if (row.components[8].newVersion) {
                            return '<b>' + data + '</b>';
                        } else {
                            return data;
                        }
                    },
                },
                {
                    // Runtime
                    data: 'components.7.version',
                    title: componentTitles[7],
                    render: function (data, type, row, meta) {
                        if (row.components[7].newVersion) {
                            return '<b>' + data + '</b>';
                        } else {
                            return data;
                        }
                    },
                },
                {
                    // MongoDB
                    data: 'components.5.version',
                    title: componentTitles[5],
                    render: function (data, type, row, meta) {
                        if (row.components[5].newVersion) {
                            return '<b>' + data + '</b>';
                        } else {
                            return data;
                        }
                    },
                },
                {
                    // Print Server
                    data: 'components.6.version',
                    title: componentTitles[6],
                    render: function (data, type, row, meta) {
                        if (row.components[6].newVersion) {
                            return '<b>' + data + '</b>';
                        } else {
                            return data;
                        }
                    },
                },
                {
                    // Console
                    data: 'components.1.version',
                    title: componentTitles[1],
                    render: function (data, type, row, meta) {
                        if (row.components[1].newVersion) {
                            return '<b>' + data + '</b>';
                        } else {
                            return data;
                        }
                    },
                },
                {
                    // Eclipse Studio
                    data: 'components.3.version',
                    title: componentTitles[3],
                    render: function (data, type, row, meta) {
                        if (row.components[3].newVersion) {
                            return '<b>' + data + '</b>';
                        } else {
                            return data;
                        }
                    },
                },
                {
                    // Web Server
                    data: 'components.9.version',
                    title: componentTitles[9],
                    render: function (data, type, row, meta) {
                        if (row.components[9].newVersion) {
                            return '<b>' + data + '</b>';
                        } else {
                            return data;
                        }
                    },
                },
                {
                    // ATP
                    data: 'components.0.version',
                    title: componentTitles[0],
                    render: function (data, type, row, meta) {
                        if (row.components[0].newVersion) {
                            return '<b>' + data + '</b>';
                        } else {
                            return data;
                        }
                    },
                },
                {
                    // X3 Services
                    data: 'components.11.version',
                    title: componentTitles[11],
                    render: function (data, type, row, meta) {
                        if (row.components[11].newVersion) {
                            return '<b>' + data + '</b>';
                        } else {
                            return data;
                        }
                    },
                },
                {
                    // X3 Mobile Automation
                    data: 'components.10.version',
                    title: componentTitles[10],
                    render: function (data, type, row, meta) {
                        if (row.components[10].newVersion) {
                            return '<b>' + data + '</b>';
                        } else {
                            return data;
                        }
                    },
                },
                {
                    // Java Server
                    data: 'components.4.version',
                    title: componentTitles[4],
                    render: function (data, type, row, meta) {
                        if (row.components[4].newVersion) {
                            return '<b>' + data + '</b>';
                        } else {
                            return data;
                        }
                    },
                },
            ],
            columnDefs: [{ targets: '_all', orderable: false }],
        });

        resolve(grid);
    });
}

function formatComponents(releases) {
    let componentTitles = [];
    let isFound = false;

    // 1st pass to determine each unique component
    releases.forEach(release => {
        release.components.forEach(component => {
            if (componentTitles.indexOf(component.name) == -1) {
                componentTitles.push(component.name);
            }
        });
    });

    // console.info(componentTitles);

    // 2nd pass to add empty component where needed + sort
    releases.forEach(release => {
        componentTitles.forEach(uniqueComponent => {
            isFound = false;
            release.components.forEach(component => {
                if (component.name === uniqueComponent) {
                    isFound = true;
                }
            });
            if (isFound === false) {
                release.components.push({
                    name: uniqueComponent,
                    version: '',
                    newVersion: false,
                });
            }
        });
        // sorting the components alphabetically according to the name
        release.components.sort(function (a, b) {
            var x = a.name.toLowerCase();
            var y = b.name.toLowerCase();
            if (x < y) {
                return -1;
            }
            if (x > y) {
                return 1;
            }
            return 0;
        });
    });
    // sorting the releases alphabetically descending (the newest first) according to the name
    releases.sort(function (a, b) {
        var x = a.name.toLowerCase();
        var y = b.name.toLowerCase();
        if (x < y) {
            return -1;
        }
        if (x > y) {
            return 1;
        }
        return 0;
    });
    releases.reverse();

    return releases;
}
