class PcSponsorships {

    init() {
        
        this.selectors = {
            filterSelect: '.pcsponsor-filters select',
            submit: '.submit',
            loader: '.lds-roller',
            resetFilters: '#pc-reset-filters',
            pagination: '.pc_page-numbers:not(.js-pc-set)',
            form: 'form',
            singleSponsorship: '.pcsponsor-item a',
            backButton: '.pcs-navigation .back',
            sponsorhipForm: '.pcsponsor-fund-form',
        };

        this.initEventHandlers();
    }

    initEventHandlers() {
        jQuery(document).on('change', this.selectors.filterSelect, function(){
            window.PcSponsorships.filterSponsorships(jQuery(this));
        })
    
        jQuery(document).on('click', this.selectors.submit, function(event) {

            const form = jQuery(this).parents('form');
		
            if (!form.hasClass('comment-form')) {
                event.preventDefault();              
                form.submit();
                return false;
            }
        });
    
        window.loadingSign = jQuery(this.selectors.loader).length > 0 ? jQuery(this.selectors.loader)[0].outerHTML : '';
    
        // Sponsorships lazy loading
        window.PcSponsorships.sponsorshipsLazyLoading();
    
        // Reset Filters
        jQuery(document).on('click', this.selectors.resetFilters, function(event){
            event.preventDefault();
    
            const pureUrl = window.location.origin + window.location.pathname;
            window.location = pureUrl;
        });
    
        // Pagination Filter Carry
        jQuery(document).on('click', this.selectors.pagination, window.PcSponsorships.paginationFilterCarry);

        // Single Sponsorship Filter Carry
	    jQuery(document).on('click', this.selectors.singleSponsorship, window.PcSponsorships.singleSponsorshipFilterCarry);

        // Back Button Filter Carry
	    jQuery(document).on('click', this.selectors.backButton, window.PcSponsorships.backButtonFilterCarry);
    
        // Query Form Submit Filter Carry
        jQuery(document).on('submit', this.selectors.form, window.PcSponsorships.paginationFilterCarry);

        // Sponsorhip form submit
        jQuery(document).on('submit', this.selectors.sponsorhipForm, window.PcSponsorships.sponsorhipFormSubmit);
    }

    filterSponsorships(filter) {
        // Get the values
        var query_string = [];
        if(jQuery('select[name=age]').val() != "0"){ query_string.push("age="+jQuery('select[name=age]').val()) }
        if(jQuery('select[name=gender]').val() != "0"){ query_string.push("gender="+jQuery('select[name=gender]').val()) }
        if(jQuery('select[name=location]').val() != "0"){ query_string.push("location="+jQuery('select[name=location]').val()) }

        // Trigger Filter Update only in case the value is not empty
        if (filter.val() !== '0') {

            // Get Filter Name
            const filterName = filter.attr('name');

            // Get the container
            const container = filter.closest('.js-sponshorships-lazy-loaded');

            // Filter URLs
            const urlArr = container.attr('data-url').split('?');
            const url = new URLSearchParams(urlArr[1]);
            const urlFullArr = container.attr('data-full-url').split('?');
            const urlFull = new URLSearchParams(urlFullArr[1]);

            // Age Filter
            if (filterName === 'age') {
                const minAge = filter.val().split('-')[0];
                const maxAge = filter.val().split('-')[1];
                
                url.set('min_age', minAge);
                url.set('max_age', maxAge);

                urlFull.set('min_age', minAge);
                urlFull.set('max_age', maxAge);
            } else {

                // Set the new Filters
                url.set(filterName, filter.val());
                urlFull.set(filterName, filter.val());
            }

            // In case the URL contains "page" parameter it should be purged for correct filtering
            if (url.has('page')) {
                url.delete('page');
            }

            if (urlFull.has('page')) {
                urlFull.delete('page');
            }

            // In case the current Browser URL contains "_page" parameter it should be purged for correct filtering
            const currentUrl = new URL(window.location.href);
            if (currentUrl.searchParams.has('_page')) {
                
                currentUrl.searchParams.delete('_page');

                window.history.pushState(
                    {},
                    '',
                    currentUrl
                );
            }

            // Reset Filter URLs
            container
                .attr('data-url', urlArr[0] +'?'+ url.toString())
                .attr('data-full-url', urlFullArr[0] +'?'+ urlFull.toString())
                .removeClass('inited');

            // Trigger Sponsorships Section Reload
            window.PcSponsorships.sponsorshipsLazyLoading();
        }
    }

    sponsorshipsLazyLoading(bypassCache = false) {
        const sponsorships = document.querySelectorAll('.js-sponshorships-lazy-loaded:not(.inited)');
    
        if (
            typeof sponsorships === 'undefined' ||
            sponsorships === null ||
            sponsorships.length === 0 ||
            !sponsorships
        ) { return false; }
    
        const filters = [
            'select[name=age]',
            'select[name=gender]',
            'select[name=location]',
            'input[name=query]',
        ];
    
        sponsorships.forEach((container) => {
    
            const dataObject = {
                action: 'sponsorshipsLazyLoading',
                url: container.dataset.url,
                fullUrl: container.dataset.fullUrl,
            };
    
            if (bypassCache === true) {
                dataObject.bypassCache = true;
            }
    
            if (
                !container.querySelector('.lds-roller') &&
                !bypassCache
            ) {
                jQuery(container).children().css({'display': 'none'});
                jQuery(container).prepend(window.loadingSign);
            }
    
            jQuery.ajax({
                url: container.dataset.ajaxUrl,
                type: 'POST',
                data: dataObject,
                success: (response) => {
                    container.classList.add('inited');
    
                    if (
                        typeof response === 'undefined' ||
                        response === null ||
                        response.length === 0
                    ) { return false; }
    
                    response = JSON.parse(response);
    
                    if (!response.success) { return false; }

                    // Inspect Filters
                    const filtersQuery = window.PcSponsorships.getFiltersFromQuery(window.location.search);
    
                    const filterValues = {};
                    filters.forEach((name) => {
                        const filter = (
                            typeof container.querySelector(name) !== 'undefined' &&
                            container.querySelector(name) !== null ?
                            container.querySelector(name) : 
                            false
                        );
                        
                        const filterFieldValue = jQuery(filter).val();
    
                        const filterValue = (
                            typeof filterFieldValue !== 'undefined' &&
                            filterFieldValue !== null ?
                            filterFieldValue : 
                            (
                                typeof filtersQuery[name] !== 'undefined' &&
                                filtersQuery[name] !== null ?
                                filtersQuery[name] :
                                null
                            )
                        );
                        
                        if (
                            typeof filterValue !== 'undefined' &&
                            filterValue !== null
                        ) {
                            filterValues[name] = filterValue;
                        }
                    });
                    
                    // Update the container
                    jQuery(container).empty();
                    container.insertAdjacentHTML('beforeend', response.data);
    
                    // Reset Filter Values
                    window.PcSponsorships.sponsorshipsSetFilters(filterValues, container);
    
                    // Check if recache is needed
                    const sponsorshipRecacheTrigger = jQuery(container).find('#sponsorshipRecacheTrigger');
                    if (
                        typeof sponsorshipRecacheTrigger !== 'undefined' &&
                        sponsorshipRecacheTrigger &&
                        sponsorshipRecacheTrigger.length > 0
                    ) {
                        window.PcSponsorships.sponsorshipsRecache();
                    }
                },
                error: (xhr) => {
                    console.error(xhr);
                }
            });
        });
    }

    sponsorshipsSetFilters(filterValues, container) {

        Object.keys(filterValues).forEach((key) => {
            const filterValue = decodeURI(filterValues[key]).replace(/\+/g, ' ');
            jQuery(container)
                .find(key)
                .val(filterValue);
        });
    }    

    sponsorshipsRecache() {
        const sponsorships = document.querySelectorAll('.js-sponshorships-lazy-loaded.inited');
    
        if (
            typeof sponsorships === 'undefined' ||
            sponsorships === null ||
            sponsorships.length === 0 ||
            !sponsorships
        ) { return false; }
    
        sponsorships.forEach((container) => {
            container.classList.remove('inited');
        });
    
        window.PcSponsorships.sponsorshipsLazyLoading(true);
    }

    getFiltersFromQuery(query) {

        const queryArr = query.replace('?', '').split('&');
        const filtersInQuery = {};
    
        const nameToTypeMap = {
            age: 'select',
            gender: 'select',
            location: 'select',
            query: 'input',
        }
    
        if (queryArr.length > 0) {
    
            queryArr.forEach((element) => {
    
                const filterArr = element.split('=');
    
                const filterType = nameToTypeMap[filterArr[0]];
    
                const filterName = (
                    filterType +
                    '[name='+
                    filterArr[0] +
                    ']'
                );
                const filterValue = (
                    typeof filterArr[1] !== 'undefined' ?
                    filterArr[1] :
                    ''
                );
    
                if (typeof filtersInQuery[filterName] === 'undefined') {
                    filtersInQuery[filterName] = filterValue;
                }
            });
        }
    
        return filtersInQuery;
    }

    paginationFilterCarry(event) {
        event.preventDefault();
    
        const form = event.target;
        const queryExtension = window.PcSponsorships.constructFiltersQuery(form);
    
        if (event.type === 'submit') {
            jQuery(document).off('submit', 'form');
            jQuery(form).trigger('submit');
            return undefined;
        }
    
        const target = (
            jQuery(event.target).hasClass('pc_page-numbers') ?
            jQuery(event.target) : 
            jQuery(event.target).closest('.pc_page-numbers')
        );
        
        const href = (
            target.attr('href') +
            (
                typeof queryExtension !== 'undefined' &&
                queryExtension.length > 0 ?
                '&'+ queryExtension.join('&') :
                ''
            )
        );
        
        const newUrl = (
            window.location.origin +
            window.location.pathname +
            href
        );
    
        window.location = newUrl;
    
        return undefined;
    }

    singleSponsorshipFilterCarry(event) {
        event.preventDefault();
    
        // Collect Filters
        const queryExtension = window.PcSponsorships.constructFiltersQuery();
    
        // In case the Page filter is on collect
        if (window.location.href.indexOf('_page') > -1) {
    
            const url = new URL(window.location.href);
            const page = url.searchParams.get('_page');
    
            queryExtension.push('_page='+ page);
        }

        // Current URL
        const currentUrl = (
            window.location.href.indexOf('?') > -1 ?
            (window.location.href.split('?'))[0] :
            window.location.href
        );

        const queryExtensionString = (
            queryExtension &&
            queryExtension.length > 0 ?
            queryExtension.join('&') :
            ''
        );

        const currentPageNewUrl = (
            currentUrl +
            (
                queryExtensionString.length > 0 ?
                '?'+ queryExtensionString :
                ''	
            )
        );

        window.history.pushState(
            {},
            '',
            currentPageNewUrl
        );
    
        // Get the Target - Trigger
        const target = jQuery(event.target).closest('a');
    
        const href = (
            target.attr('href') +
            (
                queryExtensionString.length > 0 ?
                '&'+ queryExtensionString :
                ''
            )
        );
        
        const newUrl = (
            window.location.origin +
            window.location.pathname +
            href
        );
    
        // Redirect
        window.location = newUrl;
        return undefined;
    }

    backButtonFilterCarry(event) {
        event.preventDefault();
    
        const restrictedKeys = ['sponsorship'];
        const currentUrl = new URL(window.location.href);
        const queryExtension = [];
    
        currentUrl.searchParams.forEach((paramValue, paramKey) => {
    
            if (restrictedKeys.indexOf(paramKey) < 0) {
    
                const param = paramKey +'='+ paramValue;
                queryExtension.push(param);
            }
        });
    
        // Get the Target - Trigger
        const target = jQuery(event.target).closest('a');

        const hrefClean = (
            target.attr('href').indexOf('?') > -1 ?
            target.attr('href').split('?')[0] :
            target.attr('href')
        );

        const href = (
            hrefClean +
            (
                typeof queryExtension !== 'undefined' &&
                queryExtension.length > 0 ?
                '?'+ queryExtension.join('&') :
                ''
            )
        );
    
        // Redirect
        window.location = href;
        return undefined;
    }

    constructFiltersQuery(form = null) {
        const filtersInContainer = jQuery('.pcsponsor-filters select, .sp-filtering input[name="query"]');
    
        const filters = {};
    
        filtersInContainer.each((index, element) => {
    
            const filter = jQuery(element);
            const filterValue = filter.val();
            const filterName = filter.attr('name');
    
            if (
                typeof filterValue !== 'undefined' &&
                filterValue !== null &&
                filterValue !== '0' &&
			    (filterValue.trim()).length > 0 &&
                typeof filters[filterName] === 'undefined'
            ) {
    
                filters[filterName] = filterValue;
            }
        });
    
        const queryExtension = [];
        if (Object.keys(filters).length > 0) {
    
            Object.keys(filters).forEach((filterName) => {
                
                const filterValue = filters[filterName];
                
                if (
                    event.type === 'submit' &&
                    form &&
				    !form.querySelector('[name="'+ filterName +'"]')
                ) {
    
                    const field = document.createElement('input');
                    field.type = 'hidden';
                    field.name = filterName;
                    field.value = filterValue;
    
                    form.append(field);
                }
    
                const extension = (
                    filterName +
                    '=' +
                    filterValue
                );
    
                queryExtension.push(extension);
            });
        }
    
        return queryExtension;
    }

    sponsorhipFormSubmit(event) {
        const target = event.target;
        const amount = parseInt(target.querySelector('[name="amount"]').value);

        if (isNaN(amount)) {
            event.preventDefault();

            const firstValue = target.querySelector('[name="amount"] option:nth-of-type(2)');
            firstValue.setAttribute('selected', 'selected');

            target.submit();
            return false;
        }
    }
}

window.PcSponsorships = new PcSponsorships;