import graphology from "graphology";
import Sigma from "sigma";
import {random} from 'graphology-layout';
import { Coordinates, EdgeDisplayData, NodeDisplayData } from "sigma/types";
import forceAtlas2 from 'graphology-layout-forceatlas2';

"use strict";

(function ($) {


    $(document).on('change', '#wpil_sitemap_table_filter [name=sitemap_type]', changeShowMapButton);
    function changeShowMapButton(){
        var button = $(this).val();

        if(button > 0){
            // enable the "show map" button
            $('.wpil-sitemap-display-map').removeClass('disabled').attr('disabled', false);
        }else{
            // disable the "show map" button
            $('.wpil-sitemap-display-map').addClass('disabled').attr('disabled', true);
        }
    }

    var renderer;
    function createSitemapGraph(){
        var button = $(this);
        var id = $('#wpil_sitemap_table_filter [name=sitemap_type]').val();
        var labelsToggled = $('[data-wpil-sitemap-label-toggle="1"]').is(':visible');

        if(!id || id < 1 || button.hasClass('disabled')){
            return;
        }

        // clear any existing charts
        clearChart();

        // Create a graphology graph
        const graph = new graphology.Graph();
        var $searchInput = $("#wpil-sitemap-search");


        var data = JSON.parse($('#wpil-sitemap-' + id).val());

        data.nodes.forEach(element => {
            element.label = stripslashes(element.label);
            graph.addNode(element.id, element);
        });

        data.edges.forEach(element => {
            const type = (element.type) ? element.type: 'line';
            graph.addEdge(element.source, element.target, {type: type, size: 2});
        });


        // To directly assign the positions to the nodes:
        random.assign(graph);

    // const sensibleSettings = forceAtlas2.inferSettings(graph);

        const sensibleSettings = {
        scalingRatio: 2,
        gravity: 0.1,
        strongGravityMode: true,
        barnesHutOptimize: true,
        barnesHutTheta: 0.5,
        adjustSizes: true,
        edgeWeightInfluence: 0};

        forceAtlas2.assign(graph, {
        iterations: 50,
        settings: sensibleSettings
        });

        // Initialize the Sigma.js renderer
        renderer = new Sigma(graph, document.getElementById('container'));

        // Render the graph
        renderer.refresh();

        // Internal state:
        var state = {
            hoveredNode: null,
            clickedNode: null,
            searchQuery: "",
            selectedNode: null,
            suggestions: null,
            hoveredNeighbors: null,
            clickedNeighbors: null,
            sitemapType: data.type
        };

        // Actions:
        function setSearchQuery(query) {
            state.searchQuery = query;

            if ($searchInput.val() !== query) $searchInput.val(query);

            if (query) {
                var lcQuery = query.toLowerCase();
                var suggestions = graph.nodes().map(function(n) {
                    return { id: n, label: graph.getNodeAttribute(n, 'label') };
                }).filter(function(suggestion) {
                    return suggestion.label.toLowerCase().includes(lcQuery);
                });

                if (suggestions.length === 1 && suggestions[0].label === query) {
                    state.selectedNode = suggestions[0].id;
                    state.suggestions = null;

                    var nodePosition = renderer.getNodeDisplayData(state.selectedNode);
                    renderer.getCamera().animate(nodePosition, { duration: 500 });
                } else {
                    state.selectedNode = null;
                    state.suggestions = new Set(suggestions.map(function(suggestion) { return suggestion.id; }));
                }
            } else {
                state.selectedNode = null;
                state.suggestions = null;
            }

            renderer.refresh({ skipIndexation: true });
        }

        function setHoveredNode(node) {
            if (node) {
                var neighbors = graph.neighbors(node);
                if(state.clickedNode){
                    // see if the hovered node is a neighbor to the clicked node
                    if(-1 === neighbors.indexOf(state.clickedNode)){
                        // if it's not, exit
                        return;
                    }

                    // get the hovered neighbors of the clicked node
                    var clickedNeighbors = graph.neighbors(state.clickedNode);
                    var sharedNeighbors = [];

                    clickedNeighbors.map(function(id){
                        if(-1 !== neighbors.indexOf(id)){
                            sharedNeighbors.push(id);
                        }
                    });

                    // push the clicked node too to make sure that it stays on
                    sharedNeighbors.push(state.clickedNode);

                    neighbors = sharedNeighbors;
                }

                state.hoveredNode = node;
                state.hoveredNeighbors = new Set(neighbors);
            } else if (state.clickedNode && !node) {
                state.hoveredNode = JSON.parse(JSON.stringify(state.clickedNode));
                state.hoveredNeighbors = state.clickedNeighbors;
            } else {
                state.hoveredNode = null;
                state.hoveredNeighbors = null;
            }

            renderer.refresh({ skipIndexation: true });
        }

        function setClickedNode(node) {

            if (node && node !== state.clickedNode) {
                state.clickedNode = node;
                state.clickedNeighbors = new Set(graph.neighbors(node));                
                state.hoveredNode = node;
                state.hoveredNeighbors = new Set(graph.neighbors(node));
            } else {
                state.clickedNode = null;
                state.clickedNeighbors = null;
                state.hoveredNode = null;
                state.hoveredNeighbors = null;
            }

            renderer.refresh({ skipIndexation: true });

            // do a second refresh to make sure the chart is updated when the node is unclicked
            if(!state.clickedNode){
                setTimeout(function(){renderer.refresh();}, 20);
            }
        }

        // Bind search input interactions:
        $searchInput.on("input", function() {
            setSearchQuery($searchInput.val() || "");
        });
        $searchInput.on("blur", function() {
            setSearchQuery("");
        });

        // Bind graph interactions:
        var hoverNodeWait;
        renderer.on("enterNode", function(event) {
            if(hoverNodeWait){
                clearTimeout(hoverNodeWait);
                setHoveredNode(null);
            }
            
            setHoveredNode(event.node);
        });
        renderer.on("leaveNode", function() {
            hoverNodeWait = setTimeout(function(){
                setHoveredNode(null);
            }, 200);
        });

        var clickNodeWait;
        renderer.on("clickNode", function(event) {
            if(clickNodeWait){
                setHoveredNode(null);
            }
            setClickedNode(event.node);
        });
/*
Todo: rework, can't pan the camera with this
        renderer.on("clickStage", function() {
            clickNodeWait = setTimeout(function(){
                setClickedNode(null);
            }, 200);
        });

        renderer.on("downStage", function() {
            clickNodeWait = setTimeout(function(){
                setClickedNode(null);
            }, 200);
        });
*/

        // Render edges accordingly to the internal state:
        renderer.setSetting("edgeReducer", function(edge, data) {
            var res = Object.assign({}, data),
                activeNode = ((state.hoveredNode) ? state.hoveredNode : (state.clickedNode) ? state.clickedNode: false),
                pointy = true,
                color = null;

            if(activeNode && state.sitemapType && state.sitemapType !== 'ai_sitemap'){
                // get the edge's direction
                var source = graph.source(edge),
                    target = graph.target(edge),
                    inbound = target === activeNode,
                    outbound = source === activeNode,
                    external = (graph.getNodeAttributes(target).external);
                if(state.sitemapType === 'link_sitemap_inbound' && outbound){
                    pointy = false;
                }else if(state.sitemapType === 'link_sitemap_outbound' && inbound){
                    pointy = false;
                }
                
                if(external){
                    color = '#9600e1ab';
                }else if(inbound){
                    color = '#026495ab';
                }else if(outbound){
                    color = '#027402ab';
                }

                if(color){
                    res.color = color;
                }
            }

            if( state.hoveredNode && !graph.hasExtremity(edge, state.hoveredNode) || !pointy)
            {
                res.hidden = true;
            }

            if (state.clickedNode && state.hoveredNode && state.clickedNode !== state.hoveredNode && state.clickedNeighbors){
                var found = false,
                    click = Array.from(state.clickedNeighbors),
                    hover = Array.from(state.hoveredNeighbors),
                    combined = click.filter(value => hover.includes(value));

                    combined.push(state.clickedNode);

                for (var i = 0; i < combined.length; i++) {
                    if(graph.hasExtremity(edge, combined[i])){
                        found = true;
                        break;
                    }
                }

                if(!found) {
                    res.hidden = true;
                }else{
                    if(!color){
                        res.color = "#7646b0ab";
                    }
                }
            }

            if (state.suggestions &&
                (!state.suggestions.has(graph.source(edge)) || !state.suggestions.has(graph.target(edge)))) {
                res.hidden = true;
            }

            return res;
        });


        // Render nodes accordingly to the internal state:
        renderer.setSetting("nodeReducer", function(node, data) {
            var res = Object.assign({}, data),
                inactive = false;

            // Determine the active node
            var activeNode = (state.hoveredNode) ? state.hoveredNode : (state.clickedNode) ? state.clickedNode : null;

            // Remove any nodes that are not going to have any visible edges
            if (activeNode && activeNode !== node) {
                if (state.sitemapType === 'link_sitemap_inbound') { // if this is an inbound mape
                    if(!graph.hasDirectedEdge(node, activeNode)){   // and there are no edges pointing from the specific node to the active one
                        inactive = true;                            // say that it's inactive so we can hide the node
                    }
                } else if (state.sitemapType === 'link_sitemap_outbound') {
                    if(!graph.hasDirectedEdge(activeNode, node)){
                        inactive = true;
                    }
                }
            }

            if (inactive || state.hoveredNeighbors && !state.hoveredNeighbors.has(node) && state.hoveredNode !== node) {
                res.label = "";
                res.color = "#f6f6f6";
            }

            if (state.selectedNode === node) {
                res.highlighted = true;
            } else if (state.suggestions) {
                if (state.suggestions.has(node)) {
                    res.forceLabel = true;
                } else {
                    res.label = "";
                    res.color = "#f6f6f6";
                }
            }

            // if the user is hiding lables and this isn't the active node
            if (labelsToggled && (!activeNode || activeNode !== node)) {
                res.label = '';
            }

            return res;
        });

        // Context menu logic
        const contextMenu = document.getElementById('wpil-sitemap-context-menu');
        const outboundLinkTemplate = document.getElementById('wpil-sitemap-outbound-links-url');
        const inboundLinkTemplate = document.getElementById('wpil-sitemap-inbound-links-url');

        function positionContextMenu(nodeId) {
            const nodeData = renderer.getNodeDisplayData(nodeId);
            const { x, y } = renderer.framedGraphToViewport(nodeData);

            const camera = renderer.getCamera();

            // Adjust for context menu dimensions
            const menuWidth = contextMenu.offsetWidth;
            const menuHeight = (-1 === nodeId.indexOf('term_')) ? contextMenu.offsetHeight : (contextMenu.offsetHeight * 2 - 5);
            const nodeSize = nodeData.size;

            //const adjustedX = x - menuWidth / 2;
            const adjustedX = x - menuWidth + 20;
            const adjustedY = y + ((nodeSize/camera.getState().ratio) + 15 + menuHeight * 2); // Position 5px below the bottom edge of the node

            // Set the position of the context menu
            contextMenu.style.left = `${adjustedX}px`;
            contextMenu.style.top = `${adjustedY}px`;
        }

        renderer.on('rightClickNode', (event) => {
            event.event.preventSigmaDefault();
            const node = event.node;

            // don't show context menu for external links
            if(!node || (-1 === node.indexOf('post_') && -1 === node.indexOf('term_'))){
                return;
            }

            // if this is the same node that the user just clicked
            if(contextMenu.getAttribute('data-node-id') === node && contextMenu.style.display === 'block'){
                // hide the context menu and exit
                contextMenu.style.display = 'none';
                return;
            }

            // Display the context menu at the node's position
            contextMenu.style.display = 'block';
            contextMenu.setAttribute('data-node-id', node);

            var bits = node.split('_');
            var type = bits[0];
            var id = bits[1];

            var inboundURL = inboundLinkTemplate.value.replace('{REPLACE_ID}', id).replace('{REPLACE_TYPE}', type);
            var outboundURL = outboundLinkTemplate.value.replace('{REPLACE_ID}', id).replace('{REPLACE_TYPE}', type);

            contextMenu.setAttribute('data-wpil-inbound-link-url', inboundURL);
            contextMenu.setAttribute('data-wpil-outbound-link-url', outboundURL);

            if(type === 'term'){
                $('.wpil-sitemap-context-menu-add-outbound').css({'display': 'none'});
            }else{
                $('.wpil-sitemap-context-menu-add-outbound').css({'display': 'list-item'});
            }

            positionContextMenu(node);
        });

        // Hide context menu on click elsewhere
        document.addEventListener('click', (event) => {
            if (contextMenu.style.display === 'block') {
                contextMenu.style.display = 'none';
            }
        });

        // Prevent default context menu on Sigma container
        container.addEventListener('contextmenu', (event) => {
            event.preventDefault();
        });

        // Update context menu position on camera events (pan/zoom)
        renderer.getCamera().on('updated', () => {
            if (contextMenu.style.display === 'block') {
                const nodeId = contextMenu.getAttribute('data-node-id');
                positionContextMenu(nodeId);
            }
        });

        // re-disable the "show map" button
        $('.wpil-sitemap-display-map').addClass('disabled').attr('disabled', true);

        var labelWait = false;
        function toggleLabels() {
            clearTimeout(labelWait);
            labelWait = setTimeout(function(){
            // Toggle button visibility
            $('[data-wpil-sitemap-label-toggle="0"]').toggle();
            $('[data-wpil-sitemap-label-toggle="1"]').toggle();
            labelsToggled = $('[data-wpil-sitemap-label-toggle="1"]').is(':visible');

            // and refresh the map
            renderer.refresh();
            }, 20);
        }

        // Attach click events to the buttons
        $(document).off('click', '.wpil-sitemap-label-toggle').on('click', '.wpil-sitemap-label-toggle', toggleLabels);
    }
    createSitemapGraph();

    $(document).on('click', '.wpil-sitemap-context-menu-add-inbound, .wpil-sitemap-context-menu-add-outbound', function(){
        var button = $(this),
            menu = $('#wpil-sitemap-context-menu'),
            link = null;
        if(button.hasClass('wpil-sitemap-context-menu-add-inbound')){
            link = menu.attr('data-wpil-inbound-link-url');
        }else{
            link = menu.attr('data-wpil-outbound-link-url');
        }

        if(link){
            window.open(link, '_blank').focus();
        }
    });

    $(document).on('click', '#wpil_sitemap_table_filter .wpil-sitemap-display-map.button-primary', createSitemapGraph);

    function clearChart(){
        if(!renderer){
            return;
        }

        renderer.kill();
        document.getElementById('container').innerHTML = '';
    }

    $('#wpil_generate_link_sitemaps_form').on('submit', generateLinkSitemaps);

    /**
     * 
     **/
    function generateLinkSitemaps(e){
        e.preventDefault();
        var form = $(this);
        var nonce = form.find('[name="nonce"]').val();
        if(!nonce || form.attr('disabled')){
            return;
        }
        
        // disable the generate button
        form.attr('disabled', true);
        // add a color change to the button indicate it's disabled
        form.find('button.button-primary').addClass('wpil_button_is_active');
        generateSitemaps(nonce, form);
    }

    /**
     * Makes the ajax call to clear the click data from the site
     **/
    function generateSitemaps(nonce = null, form = null, lastSitemap = ''){
        if(!nonce){
            return;
        }

        jQuery.ajax({
            type: 'POST',
            url: ajaxurl,
            data: {
                action: 'wpil_generate_link_sitemaps',
                last_sitemap: lastSitemap,
                nonce: nonce,
            },
            error: function (jqXHR, textStatus) {
                var wrapper = document.createElement('div');
                $(wrapper).append('<strong>' + textStatus + '</strong><br>');
                $(wrapper).append(jqXHR.responseText);
                wpil_swal({"title": "Error", "content": wrapper, "icon": "error"}).then(function(){
                    form.attr('disabled', false);
                    form.find('button.button-primary').removeClass('wpil_button_is_active');
                });
            },
            success: function(response){
                if(!isJSON(response)){
                    response = extractAndValidateJSON(response, ['error', 'success', 'continue']);
                }

                // if there was an error
                if(response.error){
                    wpil_swal(response.error.title, response.error.text, 'error').then(function(){
                        form.attr('disabled', false);
                        form.find('button.button-primary').removeClass('wpil_button_is_active');
                    });
                    return;
                }
                
                // if the clicks have been successfully cleared
                if(response.success){
                    wpil_swal(response.success.title, response.success.text, 'success').then(function(){
                        form.attr('disabled', false);
                        form.find('button.button-primary').removeClass('wpil_button_is_active');
                        location.reload();
                    });
                    return;
                }

                if(response.continue){
                    generateSitemaps(nonce, form, response.continue.data.sitemap);
                }
            }
        });
    }

    $(document).on('change', '.wpil-sitemap-management-controls select', changeSitemapManagementMethod);
    function changeSitemapManagementMethod(){
        var selected = $(this).val();

        if(!selected || selected == 0){
            $('.wpil-sitemap-import-container, .wpil-sitemap-delete-container').addClass('hidden');
            $('.wpil-sitemap-managment-notice-container').removeClass('hidden');
        }else if(selected == 1){
            $('.wpil-sitemap-import-container').removeClass('hidden');
            $('.wpil-sitemap-delete-container, .wpil-sitemap-managment-notice-container').addClass('hidden');
        }else if(selected == 2){
            $('.wpil-sitemap-import-container, .wpil-sitemap-managment-notice-container').addClass('hidden');
            $('.wpil-sitemap-delete-container').removeClass('hidden');
        }
    }

    $(document).on('click', '#wpil_sitemap_table_filter .wpil-sitemap-manage-map', showSitemapManagementInterface);
    function showSitemapManagementInterface(){
        // unset any CSV files
        $('#wpil-sitemap-import-file').val(null);
        // show the background
        $('.wpil-sitemap-manage-background').removeClass('hidden');
        // show the interface
        $('.wpil-sitemap-manage-wrapper').removeClass('hidden');
    }

    $(document).on('click', '#wpil-sitemap-manage-close, .wpil-sitemap-manage-background', hideSitemapManagementInterface);
    function hideSitemapManagementInterface(){
        // unset any CSV files
        $('#wpil-sitemap-import-file').val(null);
        // remove the sitemap title
        $('#wpil-sitemap-import-name').val('');
        // hide the background
        $('.wpil-sitemap-manage-background').addClass('hidden');
        // hide the interface
        $('.wpil-sitemap-manage-wrapper').addClass('hidden');
        // disable the import buttons
        $('.wpil-sitemap-csv-import, .wpil-sitemap-delete-button').removeClass('disabled').addClass('disabled');
        // hide the "big file" message
        $('.wpil-sitemap-many-rows').removeClass('hidden').addClass('hidden');
    }

    /**
     * Enables the file import button if there's a file to import.
     * Disables the button if there's no file
     **/
    function toggleFileImportButton(){
        var button = $('.wpil-sitemap-import .wpil-sitemap-csv-import'),
            file = $('#wpil-sitemap-import-file'),
            name = $('#wpil-sitemap-import-name');

        if(!file.val() || name.val().length < 1){
            button.removeClass('disabled').addClass('disabled');
        }else{
            button.removeClass('disabled');
        }
    }
    $(document).on('change', '#wpil-sitemap-import-file', toggleFileImportButton);
    $(document).on('keyup', '#wpil-sitemap-import-name', toggleFileImportButton);


    $(document).on('click', '.wpil-sitemap-csv-import', bulkImportData);
    var sitemapImportData = [],
        stepped = 0,
        rowCount = 0,
        errorCount = 0,
        firstError = undefined;

    function bulkImportData(){
        sitemapImportData = [];
        getCSVImportData();
    }

    function getCSVImportData(){
        if($('.wpil-sitemap-import .wpil-sitemap-csv-import').hasClass('disabled')){
            return;
        }

        var files = $('#wpil-sitemap-import-file').get()[0].files;
        var file = files[0];
        if(file){
            var rows = 0;
            var reader = new FileReader();
            reader.readAsText(file);
            reader.onload = function(event){
                if('undefined' !== typeof reader.result && reader.result !== null){
                    rows = (reader.result.match(/,/g)||[]).length
                }
            };

            if(rows > 500){
                $('.wpil-sitemap-many-rows').removeClass('hidden');
            }
        }

        var config = buildConfig();

        $('#wpil-sitemap-import-file').parse({
            config: config,
            error: function(err, file)
            {
                console.log("ERROR:", err, file);
                firstError = firstError || err;
                errorCount++;
            },
            complete: function()
            {
                saveImportedSitemapData();
            }
        });
    }

    function saveImportedSitemapData(sitemapId = 0, lastEnd = 0){
        if(sitemapImportData.length < 1){
            wpil_swal({"title": "Data Error", "text": "The entered data couldn't be processed, please check the data source and try again.", "icon": "error"});
            return;
        }

        var button = $('.wpil-sitemap-csv-import'),
            sitemapName = $('#wpil-sitemap-import-name').val(),
            limit = (($('#wpil-sitemap-max-input').val()/2) - 50),
            partial = (sitemapImportData.length > limit) ? 1: 0,
            length = sitemapImportData.length,
            start = (lastEnd) ? lastEnd: 0,
            end = ((start + limit) > sitemapImportData.length) ? sitemapImportData.length: (start + limit);

        button.addClass('wpil_button_is_active');

        jQuery.ajax({
            type: 'POST',
            url: ajaxurl,
            data: {
                action: 'wpil_save_custom_sitemap_data',
                sitemap_id: sitemapId,
                sitemap_name: sitemapName,
                sitemap_data: (partial) ? sitemapImportData.slice(start, end): sitemapImportData,
                partial: partial,
                finishing: (end >= length) ? 1: 0,
                nonce: $('.wpil-sitemap-import-nonce').val(),
            },
            error: function (jqXHR, textStatus) {
                hideSitemapManagementInterface();
                var wrapper = document.createElement('div');
                $(wrapper).append('<strong>' + textStatus + '</strong><br>');
                $(wrapper).append(jqXHR.responseText);
                wpil_swal({"title": "Error", "content": wrapper, "icon": "error"}).then(function(){
                    button.removeClass('wpil_button_is_active');
                });
            },
            success: function(response){
                if(!isJSON(response)){
                    response = extractAndValidateJSON(response, ['error', 'success', 'continue']);
                }

                //hideSitemapManagementInterface();

                // if there was an error
                if(response.error){
                    wpil_swal(response.error.title, response.error.text, 'error').then(function(){
                        button.removeClass('wpil_button_is_active');
                    });
                    return;
                }
                
                // if the sitemap is completely saved
                if(response.success){
                    wpil_swal(response.success.title, response.success.text, 'success').then(function(){
                        button.removeClass('wpil_button_is_active');
                        location.reload();
                    });
                    return;
                }

                // if the sitemap needs more saving
                if(response.continue){
                    // go around for another pass
                    saveImportedSitemapData(response.continue.data.sitemap_id, end);
                    return;
                }
            }
        });
    }


    var start, end;
    function printStats(msg)
    {
        if (msg)
            console.log(msg);
        console.log("       Time:", (end-start || "(Unknown; your browser does not support the Performance API)"), "ms");
        console.log("  Row count:", rowCount);
        if (stepped)
            console.log("    Stepped:", stepped);
        console.log("     Errors:", errorCount);
        if (errorCount)
            console.log("First error:", firstError);
    }
        
    function buildConfig()
    {
        // consult: papaparse.com/docs#config
        return {
            //header: $('#header').prop('checked'),
            header: true,
            dynamicTyping: $('#dynamicTyping').prop('checked'),
            skipEmptyLines: $('#skipEmptyLines').prop('checked'),
            preview: parseInt($('#preview').val() || 0),
            step: false, //stepProcessCSV,
            skipEmptyLines: true,
            encoding: $('#encoding').val(),
            worker: $('#worker').prop('checked'),
            comments: $('#comments').val(),
            complete: completeFn,
            error: errorFn,
            download: false
        };
    }
    
    function stepFn(results, parser)
    {
        stepped++;
        if (results)
        {
            if (results.data)
                rowCount += results.data.length;
            if (results.errors)
            {
                errorCount += results.errors.length;
                firstError = firstError || results.errors[0];
            }
        }
    }
    
    function completeFn(results)
    {
        end = now();

        if (results && results.errors)
        {
            if (results.errors)
            {
                errorCount = results.errors.length;
                firstError = results.errors[0];
            }
            if (results.data && results.data.length > 0)
                rowCount = results.data.length;
        }

        if(results && results.data && results.data.length){
            for(var i in results.data){
                var dat = results.data[i];

                if(dat.length < 1){
                    continue;
                }

                var source = (undefined !== dat['Source']) ? 'Source': (undefined !== dat['source']) ? 'source': false;
                var target = (undefined !== dat['Target']) ? 'Target': (undefined !== dat['target']) ? 'target': false;

                // if there's no source or target, or this is the second header
                if( !source ||
                    !target ||
                    dat[source].length < 1 ||
                    dat[target].length < 1 ||
                    typeof dat[source] !== 'string' ||
                    typeof dat[target] !== 'string' || 
                    dat[source].toLowerCase() === 'source' && dat[target].toLowerCase() === 'target')
                {
                    // skip to the next item
                    continue;
                }

                // lowercase the strings so that we're using consistent keys
                var newData = {};
                for(var j in results.data[i]){
                    newData[j.toLowerCase()] = results.data[i][j];
                }
                sitemapImportData.push(newData);
            }
        }

        printStats("Parse complete");
        console.log("    Results:", results);
    }

    function errorFn(err, file)
    {
        end = now();
        console.log("ERROR:", err, file);
        enableButton();
    }

    function enableButton()
    {
        $('#submit').prop('disabled', false);
    }
    
    function now()
    {
        return typeof window.performance !== 'undefined'
                ? window.performance.now()
                : 0;
    }

    $('.wpil-sitemap-delete select').on('change', toggleMapDeleteButton);
    function toggleMapDeleteButton(){
        var select = $(this).val();

        if(!select || select == 0){
            $('.wpil-sitemap-delete-button').addClass('disabled').attr('disabled', true);
        }else{
            $('.wpil-sitemap-delete-button').removeClass('disabled').attr('disabled', false);
        }
    }

    $('.wpil-sitemap-delete-button').on('click', deleteCustomSitemap);
    function deleteCustomSitemap(){
        var button = $(this);
        wpil_swal({
            title: 'Notice',
            text: 'You are about to delete the selected sitemap, please confirm that you want to delete the sitemap.',
            icon: 'info',
            buttons: {
                cancel: true,
                confirm: true,
            },
            }).then((deleteSitemap) => {
                if(deleteSitemap){
                    button.addClass('wpil_button_is_active');
                    var sitemapId = $('.wpil-sitemap-delete select').val();

                    jQuery.ajax({
                        type: 'POST',
                        url: ajaxurl,
                        data: {
                            action: 'wpil_delete_custom_sitemap',
                            sitemap_id: sitemapId,
                            nonce: $('.wpil-sitemap-delete-nonce').val(),
                        },
                        error: function (jqXHR, textStatus) {
                            hideSitemapManagementInterface();
                            var wrapper = document.createElement('div');
                            $(wrapper).append('<strong>' + textStatus + '</strong><br>');
                            $(wrapper).append(jqXHR.responseText);
                            wpil_swal({"title": "Error", "content": wrapper, "icon": "error"}).then(function(){
                                button.removeClass('wpil_button_is_active');
                            });
                        },
                        success: function(response){
                            if(!isJSON(response)){
                                response = extractAndValidateJSON(response, ['error', 'success']);
                            }

                            //hideSitemapManagementInterface();
            
                            // if there was an error
                            if(response.error){
                                wpil_swal(response.error.title, response.error.text, 'error').then(function(){
                                    button.removeClass('wpil_button_is_active');
                                });
                                return;
                            }
                            
                            // if the clicks have been successfully cleared
                            if(response.success){
                                wpil_swal(response.success.title, response.success.text, 'success').then(function(){
                                    button.removeClass('wpil_button_is_active');
                                    $('.wpil-sitemap-delete select option[value="'+sitemapId+'"]').remove();
                                    $('#wpil_sitemap_table_filter .wpil-sitemap-filter-select option[value="'+sitemapId+'"]').remove();
                                });
                                return;
                            }
                        }
                    });
                }
        });
    }

    function stripslashes(str) {
        return str.replace(/\\(.?)/g, function (match, group1) {
            switch (group1) {
                case '\\':
                    return '\\';
                case '0':
                    return '\0';
                case '':
                    return '';
                default:
                    return group1;
            }
        });
    }

})(jQuery);

