import resizableTable from './resizable_table';

/**
 * This file is used for datatable list only.
 * Contain all functions for datatable entity list usage.
 */

const FILTERS = {
    globalSearch: '',
    page: null,
    items: null,
    fieldFilters: {
        /*
        Example :
        id: {
            search: '',
            order: 'DESC'
        }
         */
    },
};

export const entityList = () => {
    // Initialization
    initializeFilters();
    applyFilterToView();
    initializeCheckbox();

    // Functional
    formHandling();
    resetAllFilterHandling();
    sortWidgetHandling();
    paginationWidgetHandling();
    headerSearchToggle();
    resizableTable();
    listenModifierKeyPress();
    groupActionsHandling();
    initEmptySearch();
};

function listenModifierKeyPress() {
    window.aaHasKeyboardModifierPressed = false;
    var modifierListener = (e) => {
        window.aaHasKeyboardModifierPressed = e.ctrlKey || e.shiftKey;
    };
    document.addEventListener('keydown', modifierListener);
    document.addEventListener('keyup', modifierListener);
}

function paginationWidgetHandling() {
    // link page & page_bis inputs to always have same value before forms serialization on submit of one of the forms
    let pageInput = document.querySelector('.pagination-widget.pagi-top input[name="page"]');
    let bisPageInput = document.querySelector('.pagination-widget.pagi-bot input[name="page_bis"]');

    if (!pageInput || !bisPageInput) {
        return;
    }

    let events = ['keyup', 'keydown'];
    events.forEach((ev) => {
        bisPageInput.addEventListener(ev, (e) => {
            pageInput.setAttribute('value', bisPageInput.value);
            bisPageInput.setAttribute('value', bisPageInput.value);// reflect val in attr
        });
    });
    events.forEach((ev) => {
        pageInput.addEventListener(ev, (e) => {
            pageInput.setAttribute('value', pageInput.value);// reflect val in attr
            bisPageInput.setAttribute('value', pageInput.value);
        });
    });
}

function sortWidgetHandling() {
    $('form.sorting-widget').on('click', function (e) {
        e.preventDefault();
        var elem = $(this);
        // if shift/control key is not pressed, replace sorts
        if (!window.aaHasKeyboardModifierPressed === true) {
            FILTERS.fieldFilters['sort'] = {};
            let inputs = $('.entity-list-table thead [name^="sort_"]');
            inputs = inputs.not(elem.find('[name^="sort_"]'));// remove current clicked sort
            inputs.val('');
        }
        invertSortFilter(elem);
        applyFilterToView();

        elem.submit();
    });
}

function initializeFilters() {
    FILTERS.globalSearch = getUrlParam('global_search') ? getUrlParam('global_search') : '';
    FILTERS.page = getUrlParam('page') ? getUrlParam('page') : 1;
    FILTERS.items = getUrlParam('items') ? getUrlParam('items') : 25;
    for (const [key, value] of Object.entries(getUrlParams())) {
        var matches = key.match(new RegExp('(search|sort)_([a-zA-Z0-9_]+)', 'i'));
        if (matches) {
            var queryName = matches[0];
            var prefix = matches[1];
            var propName = matches[2];
            if (typeof FILTERS.fieldFilters[prefix] === 'undefined') {
                FILTERS.fieldFilters[prefix] = {};
            }
            FILTERS.fieldFilters[prefix][propName] = value;
        }
    }
}

function applyFilterToView() {
    // Global search
    $('#global-search').val(FILTERS.globalSearch);

    // Apply order widgets
    for (const [key, value] of Object.entries(FILTERS.fieldFilters)) {
        if (key === 'sort' || key === 'search') {
            if (key === 'sort') {
                for (const [fieldName, fieldValue] of Object.entries(value)) {
                    updateOrderWidgetValue(fieldName, fieldValue);
                }
            } else if (key === 'search') {
                for (const [fieldName, fieldValue] of Object.entries(value)) {
                    updateSearchColumnValue(fieldName, fieldValue);
                }
            }
        }
    }
}

function invertSortFilter(elem) {
    let input = elem.find('input');
    let currentInputValue = input.val();
    let changingOrderingPattern = ['ASC', 'DESC', ''];
    let currentIndex = changingOrderingPattern.indexOf(currentInputValue);
    let selectedIndex = (currentIndex + 1) % 3;
    let currentKey = input.attr('name').substr(5);

    if (typeof FILTERS.fieldFilters['sort'] == 'undefined') {
        FILTERS.fieldFilters['sort'] = {};
    }
    FILTERS.fieldFilters['sort'][currentKey] = changingOrderingPattern[selectedIndex];
}

function updateOrderWidgetValue(key, direction) {
    let input = $('[name="sort_' + key + '"]');
    let form = input.closest('form');

    // Reset icons :
    form.find('i').removeClass('active');

    // Set value
    input.val(direction);

    // Set active on good icon
    form.find('i[data-value="' + direction + '"]').addClass('active');
}

function updateSearchColumnValue(key, search) {
    let input = $('[name="search_' + key + '"]');
    if (input) {
        input.val(search);
    }
}

// FORM
function queryStringToJson(qs) {
    return JSON.parse(
        '{"' + qs.replace(/&/g, '","').replace(/=/g, '":"') + '"}',
        function (key, value) {
            return key === "" ? value : decodeURIComponent(value)
        }
    );
}

function jsonToQueryString(json) {
    var s = "";
    for (var key in json) {
        if (s != "") {
            s += "&";
        }
        s += (key + "=" + encodeURIComponent(json[key]));
    }

    return s;
}

// for vanilla js serialization: https://stackoverflow.com/questions/11661187/form-serialize-javascript-no-framework
// new URLSearchParams(Array.from(new FormData(formElement))).toString()
function formHandling() {
    let forms = $('.multi-form-entity-table');

    forms.on('submit', function (e) {
        e.preventDefault();
        var serialized = forms.serialize();
        var queryString = serialized;
        var queryStringJson = queryStringToJson(serialized);
        var sortingOrder;
        if (!queryStringJson.sorting_order) {
            queryStringJson.sorting_order = '';
            sortingOrder = [];
        } else {
            sortingOrder = queryStringJson.sorting_order.split(',');
        }

        for (var k in queryStringJson) {
            var val = queryStringJson[k];
            if (val === '' && k.indexOf('_empty') === -1) {
                delete queryStringJson[k];
                // remove sorting order if we are actually not sorting on this field
                if (sortingOrder.indexOf(k) !== -1) {
                    sortingOrder.splice(sortingOrder.indexOf(k), 1)
                }
                continue;
            }

            if (k.indexOf('sort_') === 0) {
                if (sortingOrder.indexOf(k) === -1) {
                    if (val != '') {
                        sortingOrder.push(k);
                    }
                }
            }
        }
        queryStringJson.sorting_order = sortingOrder.join(',');
        queryString = jsonToQueryString(queryStringJson);

        document.location.href = document.location.pathname + '?' + queryString;
    });

    $('.submit-all-filters').on('click', (e) => {
        forms.first().trigger('submit');
    });
}

function resetAllFilterHandling() {
    $('.reset-all-filters').on('click', function (e) {
        e.preventDefault();
        resetAllFilters();
    });
}

function resetAllFilters() {
    document.location.href = document.location.pathname
}

// TOOLS
function readUrlQuery() {
    return new URLSearchParams(window.location.search);
}

function getUrlParam(sParam) {
    return readUrlQuery().get(sParam);
    let sPageURL = window.location.search.substring(1),
        sURLVariables = sPageURL.split('&'),
        sParameterName,
        i;

    for (i = 0; i < sURLVariables.length; i++) {
        sParameterName = sURLVariables[i].split('=');
        if (sParameterName[0] === sParam) {
            return sParameterName[1] === undefined ? true : decodeURIComponent(sParameterName[1]);
        }
    }
}

function getUrlParams() {
    const urlParams = readUrlQuery();
    const entries = urlParams.entries();

    var params = {};
    for (const entry of entries) {
        params[entry[0]] = entry[1];
    }

    return params;
}

function headerSearchToggle() {
    $('.header-search-row-toggler').on('click', function () {
        var searchRow = $('.header-search-row');
        var status = searchRow.hasClass('active')
        $(this).toggleClass('active', !status)
        searchRow.toggleClass('active', !status)
    });
}

function initializeCheckbox() {
    var groupActionsCheckboxAll = document.getElementById('group-actions-checkbox-all');
    var groupActionsCheckbox = document.querySelectorAll('.group-actions-checkbox');
    var groupActionsSelected = document.querySelectorAll('.group_actions_selected');

    if (groupActionsCheckboxAll) {
        // Check/uncheck all checkboxes
        groupActionsCheckboxAll.addEventListener('change', function () {
            for (var i = 0; i < groupActionsCheckbox.length; i++) {
                groupActionsCheckbox[i].checked = groupActionsCheckboxAll.checked;
                groupActionsCheckbox[i].closest('tr').classList.toggle('selected', groupActionsCheckboxAll.checked);
            }

            groupActionsSelected.forEach(function (element) {
                let actionsSelected = document.querySelectorAll('input.group-actions-checkbox:checked').length;
                let text = actionsSelected <= 1 ? element.dataset.textSingular : element.dataset.textPlural;
                element.innerHTML = text.replace('%itemsCount%', actionsSelected);
            });
        });
    }

    if (groupActionsCheckbox) {
        groupActionsCheckbox.forEach(function (checkbox) {
            checkbox.addEventListener('change', function () {
                this.closest('tr').classList.toggle('selected', this.checked);
                groupActionsSelected.forEach(function (element) {
                    let actionsSelected = document.querySelectorAll('input.group-actions-checkbox:checked').length;
                    let text = actionsSelected <= 1 ? element.dataset.textSingular : element.dataset.textPlural;
                    element.innerHTML = text.replace('%itemsCount%', actionsSelected);
                });
            });
        });
    }
}

function groupActionsHandling() {
    var groupActionsItems = document.querySelectorAll('.group-actions-item');

    if (!groupActionsItems) {
        return;
    }

    for (var i = 0; i < groupActionsItems.length; i++) {
        groupActionsItems[i].addEventListener('click', function () {
            var groupActionsItem = this;
            var groupActionsCheckboxChecked = document.querySelectorAll('input.group-actions-checkbox:checked');

            if (groupActionsItem.classList.contains('prevent')) {
                var preventModalConfirmationLink = document.querySelector('.preventModalConfirmationLink');

                preventModalConfirmationLink.addEventListener('click', function () {
                    fetchAction(groupActionsCheckboxChecked, groupActionsItem.dataset.action);
                    $('#preventModal').modal('hide');
                });
            } else {
                fetchAction(groupActionsCheckboxChecked, groupActionsItem.dataset.action);
            }
        });
    }
}

function fetchAction(groupActionsCheckboxChecked, action) {
    var ids = [];
    groupActionsCheckboxChecked.forEach(function (checkbox) {
        ids.push(checkbox.dataset.id);
    });

    fetch(action, {
        method: 'POST',
        body: JSON.stringify({ids: ids})
    }).then(() => {
        window.location.reload();
    })
}

function initEmptySearch() {
    document.querySelectorAll('.search-empty-input').forEach(elt => {
        elt.parentNode.querySelector('.search-empty-label').style.color = elt.checked ? '#4e73df' : '';
        elt.addEventListener('click', function (e) {
            e.target.parentNode.querySelector('.search-empty-label').style.color = e.target.checked ? '#4e73df' : '';
        })
    })
}
