"use strict";
import getTpl from "../libs/gettpl";

var monthDiff = function (d1, d2) {
//get number of months between two dates if > 0
    var months;
    months = (d2.getFullYear() - d1.getFullYear()) * 12;
    months -= d1.getMonth() + 1;
    months += d2.getMonth();
    return months <= 0 ? 0 : months;
};

function pad(n) {
    // add 0 to n if <10
    return (n < 10) ? ("0" + n) : n;
}

var showForHuman = function (result) {
    //convert date to : monthName/year format
    let year = new Date(filterDateFrom);
    year.setMonth((result >> 0) + filterMonthFrom);
    let monthName = tabMonths[Math.abs(result % 12 + filterMonthFrom) % 12];
    return monthName + '/' + year.getFullYear();
};
var showForServer = function (result) {
    //convert date to : year/monthName format
    let year = new Date(filterDateFrom);
    year.setMonth((result >> 0) + filterMonthFrom);
    let monthName = Math.abs(result % 12 + filterMonthFrom) % 12;
    return year.getFullYear() + '/' + (pad(monthName + 1));
};

var getStepDate = function (dateFromTo, dateMinMax) {
    // get number of months betweek two dates
    var dateFrom = new Date(dateFromTo);
    var dateMin = new Date(dateMinMax);
    return monthDiff(dateMin, dateFrom) + 1;
};


let currentPageIndex = 1;
let maxPerPage = 8;
let filterDateFrom;
let filterMonthFrom;
let currentFilterCities;
let currentFilterGenre;
let currentFilterPrice;
let currentFilterDate;
let currentCity = window.currentCity ? window.currentCity : '';

class SPECTACLEFILTER {

    constructor(el) {

        this.el = $(el);

        this.tabMonths = typeof tabMonths == 'undefined' ? [] : tabMonths;
        this.$perPageFilter = $('.spectacle-list-header .form-nb-item select');
        this.i18nGenre = {};

        $(".spectacle-filter-date-range").show();
        var $dateInner = $('#date-range');
        var $priceInner = $('#price-range');
        var dateMin = new Date($dateInner.data('date-min')),
            dateMax = new Date($dateInner.data('date-max')),
            priceMax = $('#price-range').data('price-max'),
            optionPriceFrom = $("input[name$='pricefrom']").val(),
            optionPriceTo = $("input[name$='priceto']").val(),
            showsCurrency = $priceInner.data('price-currency'),
            optionDateFrom = getStepDate($("input[name$='datefrom']").val(), dateMin),
            optionDateTo = getStepDate($("input[name$='dateto']").val(), dateMin);

        filterDateFrom = new Date(dateMin.getFullYear(), dateMin.getMonth());
        filterMonthFrom = filterDateFrom.getMonth();
        this.initRangeSlider({
            date: {
                min: 0,
                max: monthDiff(dateMin, dateMax) + 1,
                startMonth: dateMin.getMonth(),
                from: optionDateFrom || 0,
                to: optionDateTo || monthDiff(dateMin, dateMax) + 1
            },
            price: {
                min: 0,
                max: priceMax,
                from: optionPriceFrom || 0,
                to: optionPriceTo || priceMax,
                currency: showsCurrency
            }
        });
        this.bindEvents();
    }
    // init date filer slider with user interface parameters to update results
    // two hidden inputs (datefrom and dateto) are updated when the slider is moved
    // on "onUpdate" and "onFinish" events the filterDisplayDateSelected function is called to display the selected dates
    // >> and after the getPage is used to load the updated spectacles results in ajax/html

    initRangeSlider(options) {
        var context = this;
        let dateMin = options.date.min;
        let dateMax = options.date.max;
        $("#date-range").ionRangeSlider({
            type: "double",
            grid: true,
            grid_num: 10,
            grid_snap: true,
            min: dateMin,
            max: dateMax,
            from: options.date.from,
            to: options.date.to,
            step: 1,
            drag_interval: true,
            prefix: "",
            prettify: function (num) {
                return context.tabMonths[(num + options.date.startMonth) % 12];
            },
            onUpdate: function (data) {
                var isFilter = !(data.min === data.from && data.max === data.to);
                currentFilterDate = {min: data.from, max: data.to};
                $("input[name$='datefrom']").val(showForServer(data.from));
                $("input[name$='dateto']").val(showForServer(data.to));
                context.filterDisplayDateSelected(isFilter);
                context.getPage(context.buildUrl());
            },
            onChange: function (data) {
                currentFilterDate = {min: data.from, max: data.to};
                $("input[name$='datefrom']").val(showForServer(data.from));
                $("input[name$='dateto']").val(showForServer(data.to));
            },
            onFinish: function (data) {
                var isFilter = !(data.min === data.from && data.max === data.to);
                context.filterDisplayDateSelected(isFilter);
                context.getPage(context.buildUrl());
            }
        });

        let priceMin = options.price.min;
        let priceMax = options.price.max;
        let priceFrom = options.price.from;
        let priceTo = options.price.to;
        let currency = options.price.currency;
        let showsCurrency = typeof showsCurrency != 'undefined' ? showsCurrency : '';

        // same system of range but with prices
        $("#price-range").ionRangeSlider({
            type: "double",
            grid: true,
            grid_num: 50,
            grid_snap: true,
            min: priceMin,
            max: priceMax,
            from: priceFrom,
            to: priceTo,
            step: 10,
            drag_interval: true,
            prettify: function (num) {
                let s = num == 0 ? i18n.free : num + ' ' + currency;
                return s;
            },
            onUpdate: function (data) {
                var isFilter = !(data.min === data.from && data.max === data.to);
                currentFilterPrice = {min: data.from, max: data.to};
                $("input[name$='pricefrom']").val(currentFilterPrice.min);
                $("input[name$='priceto']").val(currentFilterPrice.max);
                context.filterDisplayPriceSelected(isFilter);
                context.getPage(context.buildUrl());
            },
            onChange: function (data) {
                currentFilterPrice = {min: data.from, max: data.to};
                $("input[name$='pricefrom']").val(currentFilterPrice.min);
                $("input[name$='priceto']").val(currentFilterPrice.max);

            },
            onFinish: function (data) {
                var isFilter = !(data.min === data.from && data.max === data.to);
                context.filterDisplayPriceSelected(isFilter);
                context.getPage(context.buildUrl());
            }
        });
    }

    bindEvents(param) {
        var context = this;
        // CHANGE ITEM PER PAGE
        /*context.$perPageFilter.on('change changesetup', function () {//todo a voir si ca sert a quelquechose
         //context.filtermanager.filter.perPage(this.value)
         }).val(param.perpage || 8).trigger('changesetup');*/

        //FILTERS Changes onclick on checkboxs
        var TIMEOUTgenreFilter;
        $("#spectaclefiltergenrelist .input").on('change', function (e) {
            let notSetup = e.type !== 'changesetup';

            let $spectaclefiltergenrelist = $('#spectaclefiltergenrelist .input');
            // tes if all filters are enabled or not
            if (notSetup && this.value === 'allgenre') {
                $spectaclefiltergenrelist.not(this).attr('checked', false);
            }
            else {
                $spectaclefiltergenrelist.filter('#allgenre').attr('checked', false);
            }

            var serializeArray = $spectaclefiltergenrelist
                .serializeArray()
                .filter(filter => filter.value !== 'allgenre');

            currentFilterGenre = serializeArray
                .map(o => o.value)
                .join('|');

            context.filterDisplayGenreSelected(serializeArray.length > 0);
        });

        $("#spectaclefiltergenrelist .input").each((i, o) => {
            this.i18nGenre[o.value] = $('label[for="' + o.id + '"]').text();
        });
        //serialize and update spectacle filtered list
        $("#spectaclefiltercitieslist .input").on('change changesetup', function () {

            let $spectaclefiltergenrelist = $('#spectaclefiltercitieslist .input');

            var serializeArray = $spectaclefiltergenrelist.serializeArray();
            currentFilterCities = serializeArray.map(function (o) {
                return o.value;
            }).join('|');

            context.filterDisplayCitiesSelected(!!serializeArray.length);

        });
        // on click event on "discover" button  > open spectacle page
        $("#spectacles-list").on('click', '.js-pagination a', function (e) {
            //context.filtermanager.filter.setPage(this.hash.substr(1), true);//todo change page encapsulation
            e.preventDefault();
            context.goTo(this.getAttribute("data-page"));
        });

        // CHANGE VIEW
        let $switchView = $('.js-switch-show-view');
        $switchView.on('click', function () {
            $switchView.not(this).removeClass('active');
            $(this).addClass('active');
            return false;
        });

        // RESET FILTER PARAMETERS AND RESULTS
        $('.spectacle-filter-selected-list').on('click', '.js-reset-filter', function () {

            let filterType = $(this).data('filter');

            if (filterType === 'date') {
                let slider = $("#date-range").data("ionRangeSlider");
                slider.update({
                    from: slider.options.min,
                    to: slider.options.max
                });
            }
            else if (filterType === 'price') {
                let slider = $("#price-range").data("ionRangeSlider");
                slider.update({
                    from: slider.options.min,
                    to: slider.options.max
                });
            }
            else if (filterType === 'genre') {
                $('#spectaclefiltergenrelist .input').attr('checked', false).first().trigger('change');
            }
            else if (filterType === 'cities') {
                $('#spectaclefiltercitieslist .input').attr('checked', false).first().trigger('change');
            }

            return false;
        });
        // update results page on filter form submission
        $('.form').on('change submit', function (e) {
            e.preventDefault();
            if((e.target.type === 'checkbox') || (e.type === 'change' && e.target.nodeName === 'SELECT') || (e.type === 'submit')) {
                context.getPage(context.buildUrl());
            }

        });
        $(window).on('popstate', function () {
            context.getPage(history.state.url);
            /* $($('.form').prop('elements')).each(function () {//todo
             var $input = $(this);
             var name = $input.attr('name');
             var value = $input.val();
             var type = $input.attr('type');
             var matchOthers = history.state.formState.filter(function (o) {
             return name === o.name;
             });
             var matchCheck = matchOthers.filter(function (o) {
             return value === o.value;
             });

             if (matchOthers.length && /text|hidden|select/.test(type)) {
             $input.val(matchOthers[0].value);
             }
             else {
             $input.val('');
             }
             console.log(matchCheck);
             if (matchCheck.length && /checkbox/.test(type)) {
             $input.prop('checked', 'checked');
             }
             else {
             $input.removeAttr('checked');
             }

             });*/

        });
        var formState = $('.form').serializeArray();

        var urlVal = location.href;

        window.history.replaceState({
            formState: formState,
            url: urlVal,
            title: $(document).find('title').text()
        }, $('html').find('title').text(), urlVal);

    }

    // function to display Genres choices to filter results under filter options after validation
    filterDisplayGenreSelected(isFilterEnabled) {
        var $fGenre = $('.js-filter-genre');
        $fGenre.toggleClass('active', isFilterEnabled);

        if (isFilterEnabled) {
            $fGenre[0].innerHTML = getTpl({genre: currentFilterGenre.replace(/\|/g, ' - ')}, 'spectaclefilterselectedgenre');
        }
    }

    // function to display Dates choices to filter results under filter options after validation
    filterDisplayDateSelected(fDate) {
        var $fDate = $('.js-filter-date');

        $fDate.toggleClass('active', fDate);
        if (fDate) {
            $fDate[0].innerHTML = getTpl(currentFilterDate, 'spectaclefilterselecteddate')
                .replace(/\$(\d+)/g, function (search, result) {
                    return showForHuman(result);
                });
        }
    }
    // function to display prices choices to filter results under filter options after validation
    filterDisplayPriceSelected(fPrice) {
        var $fPrice = $('.js-filter-price');
        $fPrice.toggleClass('active', fPrice);

        if (fPrice) {
            //task #BCW-308
            let isFree = currentFilterPrice.min == 0;
            let tpl = isFree ? 'spectaclefilterselectedprice-free' : 'spectaclefilterselectedprice';
            let _priceDisplay = {
                min: isFree ? i18n.free : currentFilterPrice.min,
                max: currentFilterPrice.max
            };
            $fPrice[0].innerHTML = getTpl(_priceDisplay, tpl);
        }

    }
    // function to display Cities choices to filter results under filter options after validation
    filterDisplayCitiesSelected(fCities) {
        var $fCities = $('.js-filter-cities');

        $fCities.toggleClass('active', fCities);

        if (fCities) {
            $fCities[0].innerHTML = getTpl({cities: currentFilterCities.replace(/\|/g, ' - ')}, 'spectaclefilterselectedcities');
        }
    }

    buildUrl(page) {
        page = page ? page : $('.js-pagination .active').html();
        var formState = this.buildState(page);
        var urlVal = location.pathname + '?' + $.param(formState);
        return urlVal;
    }

    buildState(page) {
        var formState = $('.form').serializeArray();
        formState.push({name: 'page', value: page});
        return formState;
    }

    goTo(page) {
        var urlVal = this.buildUrl(page);
        window.history.pushState({
            page: page,
            url: urlVal,
            title: $('html').find('title').text()
        }, $('html').find('title').text(), urlVal);
        this.getPage(urlVal);
    }

    getPage(url) {
        // update results spectacles list dynamicly with ajax
        $.get(url).done(function (result) {
            var html = $(result).find('#spectacles-list').html();
            $('#spectacles-list').html(html);
        });
    }


}

export default SPECTACLEFILTER;
