/*!
 * AW Eshop Filters
 *
 *
 * @author  Roman Janko <janko@andweb.cz>
 * @since  30.01.2019 09:59:25
 * @version  1.0.0
 *
 */

;(function() {
    'use strict';

    function awEshopFilters(element, options) {
        this.self            = $(element);
        this.settings        = $.extend(true, {}, $.fn.awEshopFilters.defaults, options);
        
        this.mainButton            = $(this.settings.mainButton);
        this.filterBody            = $(this.settings.filterBody);
        this.filterList            = $(this.settings.filterList);
        this.filterGroups          = $(this.settings.filterGroups);
        this.selectedFilterWrapper = $(this.settings.selectedFilterWrapper);
        this.selectedFilterHeading = $(this.settings.selectedFilterHeading);
        this.selectedFilterSet     = $(this.settings.selectedFilterSet);
        this.deleteAllFiltersBtn   = $(this.settings.deleteAllFiltersBtn);
    }


    awEshopFilters.prototype = {
        
        /* PRIVATE METHODS */
        _create: function() { 
            this._bindMainButton();
            this._bindFilterLinkClick();
            this._bindFilterGroupItemClick();
            this._bindFilterGroupItemSliderChange();
            this._bindDeleleteAllFiltersBtn();

            this._updateFilterSetState();
        },

        _bindMainButton: function() {
            var that = this;

            this.mainButton.on('click', function(e) {
                e.preventDefault();
                
                var $this = $(this);
                var opened = $this.data('state') || 'closed'; // default state
                var effect = that.settings.animation ? 'slideToggle' : 'toggle';
                if (opened == 'closed') {
                    $this.data('state', 'opened');
                    $this.find('i').removeClass().addClass(that.settings.mainButtonClasses.opened);
                } else {            
                    $this.data('state', 'closed');
                    $this.find('i').removeClass().addClass(that.settings.mainButtonClasses.closed);
                }

                that.filterBody[effect]();
                
            });
        },

        /**
         * Current active list item from filter on left side
         */
        _getGroup: function(groupId) {
            var item = this.filterList
                .find('li[data-groupid="'+groupId+'"]')
                .children('a');

            return {
                'rank': item.parent().data('rank'),
                'id': item.parent().data('groupid'),
                'text': item.text(),
                'item': item
            }
        },

        _bindFilterLinkClick: function() {
            var that = this;

            this.filterList.find('a').on('click', function(e) {
				e.preventDefault();
				
				$('html, body').animate({
					scrollTop: that.filterList.offset().top - 100
				});

                var $this = $(this);
                var $parent = $this.parent();
                var hasChildren = $parent.data('has-children') || 0;
                var id = $parent.data('groupid');

                that.filterList
                    .find('li')
                    .removeClass('active');
                
                 $parent
                    .addClass('active');
                
                that.filterGroups
                    .hide();

                that.filterGroups
                    .children()
                    .hide();

                if (hasChildren) {
                    $parent
                        .children('ul')
                        .toggle();

                    var isVisible = $parent.children('ul').is(":visible") || 0;

                    $parent
                        .children('a')
                        .children('i')
                        .removeClass(function(i, s) {
                            $(this)
                                .removeClass(that.settings.filterLinkChildrenClass.closed)
                                .removeClass(that.settings.filterLinkChildrenClass.opened)
                                .addClass(
                                            !isVisible ? that.settings.filterLinkChildrenClass.opened : that.settings.filterLinkChildrenClass.closed);
                        });
                }    

                var foundedSomeGroup = that.filterGroups
                    .find('[data-groupid="'+id+'"]');

                if (foundedSomeGroup.length) {
                    that.filterGroups.show();
                    foundedSomeGroup.show();
                }                   
                
            }).filter(':first').trigger('click');
        },

        _group: function() {
            var that = this;

            var add = function(group) {
                var newGroup = $('<div>').attr('data-group', group.id)
                                    .attr('data-rank', group.rank)
                                    .html('<div>' + group.text + '</div>')
                                    .appendTo(that.selectedFilterSet);
                newGroup.append('<div>');  

                return newGroup;
            };

            var exists = function(groupId) {
                var group = that.selectedFilterSet.find('[data-group="'+groupId+'"]');
                return group.length > 0;
            };

            var remove = function(group) {
                group.remove();
            };  

            var removeGroupIsEmpty = function(groupId) {
                var group = that.selectedFilterSet.find('[data-group="'+groupId+'"]');
                if (group.find('a').length === 0) {
                    remove(group);
                }
            };

            return {
                add: add,
                exists: exists,
                remove: remove,
                removeGroupIsEmpty: removeGroupIsEmpty
            }
            
        },

        _bindFilterGroupItemSliderChange: function() {
            var that = this;

            that.filterGroups.on('change', '.range-slider-default', function(e) {
                var $slider = $(this);
                var from = $slider.data("from"); 
                var to = $slider.data("to"); 
                var value = $slider.prop("value").split(';'); // human readable values = text values
                var group = that._getGroup($slider.data('groupid')); // curent active group
                var dataValues = $slider.data('values').split(',');

       
                // group doesnt exist yet, so we will add it   
                if (!that._group().exists(group.id)) {
                    var newGroup = that._group().add(group);
                }

                // target place for inserting a new selected range values
                var targetPlace = $(that.selectedFilterSet).find('[data-group="'+group.id+'"]').find('div').eq(1);
                // flush old value
                targetPlace.empty();

                // reset to default, because we are selecting default range, so we dont want to show it
                if ($slider.data('range').length === dataValues.length) {
                    that._group().removeGroupIsEmpty(group.id);
                    that._showOrHideDeleteAllFiltersBtn();
                    that._updateFilterSetState();

                    return; // SKIP ...
                }
                var tpl         = that.settings.selectedFilterItemTemplate; 
                var compiledTpl = tpl
                    .replace('{{name}}', value[0] + ' - ' + value[1])
                    .replace('{{itemid}}', $slider.data('itemid'));


                var $filterItem = $(compiledTpl);
                $filterItem.on('click.eshop-filter-item-slider', function(e) {
                    e.preventDefault();       
                    
                    that._resetSliderToDefault($slider);
                    that._removeFilterSlider($filterItem);
                    that._group().removeGroupIsEmpty(group.id);
                    that._showOrHideDeleteAllFiltersBtn();
                    that._updateFilterSetState();

                    //@TODO: callback will be applied from outside when we remove this

                }).appendTo(targetPlace);

                that._showOrHideDeleteAllFiltersBtn();
                that._updateFilterSetState();
            });
        },

        _bindFilterGroupItemClick: function() {
            var that = this;

            that.filterGroups.on('click filter:init', 'input[type="checkbox"]', function(e) {
                
                var $checkbox = $(this);
                var $label =  $checkbox.parent().next('label');
                var group = that._getGroup($checkbox.data('groupid')); // curent active group
                
                // Has been added? 
                var $hasBeenAdded = that.selectedFilterSet
                    .find('[data-itemid="'+$checkbox.data('itemid')+'"]');

                // group doesnt exist yet, so we will add it   
                if (!that._group().exists(group.id)) {
                    var newGroup = that._group().add(group);
                }

                // item has been already added?
                if ($hasBeenAdded.length > 0) {
                    that._removeFilter($hasBeenAdded);
                    that._unselectCheckbox($checkbox);
                    that._group().removeGroupIsEmpty(group.id);
                    that._updateFilterSetState();

                    that.settings.selectedFilterItemClick.apply(that, [$hasBeenAdded, $checkbox, $label]);

                    return;
                }

                var tpl         = that.settings.selectedFilterItemTemplate; 
                var compiledTpl = tpl
                    .replace('{{name}}', $label.text())
                    .replace('{{itemid}}', $checkbox.data('itemid'));

                var $filterItem = $(compiledTpl);
                $filterItem.on('click.eshop-filter-item', function(e, skipClick) {
                    e.preventDefault();       
                    
                    that._removeFilter($filterItem);
                    that._unselectCheckbox($checkbox);
                    that._group().removeGroupIsEmpty(group.id);
                    that._updateFilterSetState();

                    if(!skipClick)                    
                        that.settings.selectedFilterItemClick.apply(that, [$filterItem, $checkbox, $label]);

                }).appendTo($(that.selectedFilterSet).find('[data-group="'+group.id+'"]').find('div').eq(1));

                that._showOrHideDeleteAllFiltersBtn();
                that._updateFilterSetState();
                
            }).find('input[type="checkbox"]:checked').trigger('filter:init');
        },

        _bindDeleleteAllFiltersBtn: function() {
            var that = this;
            
            this.deleteAllFiltersBtn.on('click', function(e) {
                var selectedFilterItems = that._getSelectedFilterItems();
                selectedFilterItems.each(function() {
                    var $item = $(this);
                    $item.trigger('click.eshop-filter-item', [true]);
                    $item.trigger('click.eshop-filter-item-slider', [true]);
                });

                that.settings.deleteAllClick.apply(that);
            });
        },

        _unselectCheckbox: function(checkbox) {
            checkbox.prop('checked', false);
        },

        _removeFilter: function(o) {
            o.off('.click.eshop-filter-item');
            o.remove();
            this._showOrHideDeleteAllFiltersBtn();
        },

        _removeFilterSlider: function(o) {
            o.off('.click.eshop-filter-item-slider');
            o.remove();
            this._showOrHideDeleteAllFiltersBtn();
        },

        _resetSliderToDefault: function($slider) {
            $slider.data("ionRangeSlider").reset();
        },

        _showOrHideDeleteAllFiltersBtn: function() {
            var hasSomeFilterInside = this._getSelectedFilterItems();

            if (hasSomeFilterInside.length === 0)
                this.deleteAllFiltersBtn.addClass('-nod');
            else  
                this.deleteAllFiltersBtn.removeClass('-nod');  

               
        },

        _updateFilterSetState: function() {

            var hasSomeFilterInside = this._getSelectedFilterItems();
            if (hasSomeFilterInside.length === 0) {
                this.selectedFilterWrapper.addClass('nod');
                //this.selectedFilterSet.html('<p class="eshop-menu-filters__text-nothing-selected">' + this.selectedFilterSet.data('empty-text') + '</p>');
            } else {
                //this.selectedFilterSet.find('p.eshop-menu-filters__text-nothing-selected').remove();
                this.selectedFilterWrapper.removeClass('nod');
            }
        },

        _getSelectedFilterItems: function() {
            return this.selectedFilterSet.find('a[data-itemid]');
        },
  
        /* PUBLIC METHODS */
        update: function(data, cntKey) {
            for (let k in data) {
                var $input = this.filterGroups.find('[data-itemid="'+k+'"]');
                if ($input.length) {
                    this.filterGroups.find('[data-count-itemid="'+k+'"]').text(data[k][cntKey]);
                    this.selectedFilterSet.find('[data-itemid="'+k+'"]').text($input.parent().next('label').text());
                }
            }
        }
    };


    (function ($) {
        $.fn.awEshopFilters = function(options) {
            var
            args   = Array.prototype.slice.call(arguments, 1),
            method = awEshopFilters.prototype[options];

            return this.each(function() {
                var self     = $(this);
                var instance = self.data('awEshopFilters');

                if (!instance) {
                    instance = new awEshopFilters(this, options);
                    instance._create();
                    self.data('awEshopFilters', instance);
                }

                if (method && options.substring(0, 1) == '_') 
                    $.error('Cannot use private method "' + options + '" outside of object');
                
                if (method) {
                    method.apply(instance, args);
                } else if (options && typeof options !== 'object') {
                    $.error('Method "' + options + '" not found.');
                }
            });
        };

        $.fn.awEshopFilters.defaults = {
            animation: false,
            animationSpeed: 0,
            mainButton: '.eshop-menu-filters__main-button', // main toggler button =  reveal below groups, is connected with filterBody
            mainButtonClasses: {
                opened: 'fa fa-angle-down',
                closed: 'fa fa-angle-up',
            },
            filterBody: '.eshop-menu-filters__body',
            filterList: '.eshop-menu-filters__filter-list', // menu with filter links
            filterGroups: '.eshop-menu-filters__filter-groups', // aside filter groups = will be filtered by links in left menu
            filterLinkChildrenClass:  { // link with children  classes for icon 
                opened: 'fa fa-plus-square',
                closed: 'fa fa-minus-square',
            },
            selectedFilterWrapper: '.eshop-menu-filters__selected-filters', // wrapper for selected filters and textual information
            selectedFilterHeading: '.eshop-menu-filters__selected-filter-heading', // title for selected filter name
            selectedFilterSet: '.eshop-menu-filters__selected-filters-set',
            deleteAllFiltersBtn: '.eshop-menu-filters__delete-all-filters',
            selectedFilterItemTemplate: '<a href="#" class="badge badge-secondary mr-2 mb-2 p-1" data-itemid="{{itemid}}">{{name}}</a>',
            selectedFilterItemClick: function(filterItem, checkbox, label) {
            },
            deleteAllClick: function() {
            }
        };
    })(jQuery);
})();