class PcTrips {

    init() {

		this.loaderMarkup = `
		<div class="lds-roller"><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div></div>
		`;

        this.selectorPureClass = {
            filterButton: 'js-filter-button',
            submitFilters: 'js-submit-filters',
			resetFilters: 'js-reset-filters',
        };
        this.selectorClass = this.prepareSelectorClass(this.selectorPureClass);

        this.pcPureClass = {
            pcFilter: 'pc-filter',
            pcFilterOptions: 'pc-filter-options',
            pcFilters: 'pc-filters',
            pcFiltersMobile: 'pc-filters-mobile',
            pcFilterOption: 'pc-filter-option',
			pcTripsFormContainer: 'pc-trips-form-container',
			pcTripsFormSelf: 'pc-trips-form-self',
			pcTripsFormInput: 'pc-trips-form-input',
			pcTripsFormButton: 'pc-trips-form-button',
			pcPageButton: 'pc_page-numbers',
			pcTripsPageNumberInput: 'pc-trips-page-number-input',
        };
        this.pcClass = this.prepareSelectorClass(this.pcPureClass);

        this.helperPureClass = {
            open: 'open',
            forMobile: 'for-mobile',
        };
        this.helperClass = this.prepareSelectorClass(this.helperPureClass);

        this.containerPureClass = {
            jsTrips: 'js-trips',
        };
        this.containerClass = this.prepareSelectorClass(this.containerPureClass);
        
        this.restAction = 'purecharityTripsFiltering';

		this.defaultFilterSelectors = [
			`${this.pcClass.pcFilterOption}:checked`,
			this.pcClass.pcTripsFormInput,
			this.pcClass.pcTripsPageNumberInput,
		];

		this.keyFromInitialQueryTrimMap = [
			'_page',
			'page',
		];
		
		this.setFilterOptionChangeState(false);

		this.shortcodeInitialQuery = this.fetchShortcodeInitialQuery();

        this.initEventHandlers();
    }

    prepareSelectorClass(selectorPureClass) {

        const result = {};

        if (Object.keys(selectorPureClass).length === 0) { return result; }

        Object.keys(selectorPureClass).forEach((key, index) => {

            if (typeof result[key] === 'undefined') {

                const pureClass = selectorPureClass[key];
                result[key] = `.${pureClass}`;
            }
        });

        return result;
    }

    initEventHandlers() {

        jQuery(document).on('click', this.selectorClass.filterButton, this.handleFilterButtonClick);

        jQuery(document).on('click', this.selectorClass.submitFilters, this.handleSubmitFilters);

		jQuery(document).on('submit', this.pcClass.pcTripsFormSelf, this.handleSubmitLiveSearchFilters);

		jQuery(document).on('click', this.selectorClass.resetFilters, this.handleResetFilters);

		jQuery(document).on('click', this.pcClass.pcPageButton, this.handlePageButton);

		jQuery(document).on('change', this.pcClass.pcFilterOption, this.handleFilterOptionChanged);
    }

	setFilterOptionChangeState(state = false) {
		this.filterOptionWasChanged = state;
	}

	getFilterOptionChangeState() {
		return this.filterOptionWasChanged;
	}

	handleFilterOptionChanged(event) {
		window.PcTrips.setFilterOptionChangeState(true);
	}

	handlePageButton(event) {
		event.preventDefault();

		const target = jQuery(event.target).closest('a');

		if (target.length === 0) { return false; }

		const href = target.attr('href');
		const pageNumber = (
			href.indexOf('_page') > -1 ?
			href.split('_page=')[1].trim() :
			'1'
		);

		const fullUrl = window.location.href;
		const fullUrlUsable = new URL(fullUrl);
		
		fullUrlUsable.searchParams.set('_page', pageNumber);

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

		jQuery(window.PcTrips.pcClass.pcTripsPageNumberInput).val(pageNumber);

		jQuery(window.PcTrips.selectorClass.submitFilters).trigger('click');

		return false;
	}

	handleResetFilters(event) {
		event.preventDefault();
    
		const pureUrl = window.location.origin + window.location.pathname;
		window.location = pureUrl;
	}

	handleSubmitLiveSearchFilters(event) {
		event.preventDefault();

		window.PcTrips.setFilterOptionChangeState(true);
		jQuery(window.PcTrips.selectorClass.submitFilters).trigger('click');

		return undefined;
	}

    handleFilterButtonClick(event) {

        const target = (
			jQuery(event.target).hasClass(window.PcTrips.selectorPureClass.filterButton) ?
			jQuery(event.target) : 
			jQuery(event.target).closest(window.PcTrips.selectorClass.filterButton)
		);

		if (!target.hasClass(window.PcTrips.helperPureClass.open)) {
			target.addClass(window.PcTrips.helperPureClass.open);

			if (!target.hasClass(window.PcTrips.helperPureClass.forMobile)) {
				target.closest(window.PcTrips.pcClass.pcFilter).find(window.PcTrips.pcClass.pcFilterOptions).slideDown('fast');
			} else {
				target.parent().find(window.PcTrips.pcClass.pcFiltersMobile).slideDown('fast');
			}
		} else {
			target.removeClass(window.PcTrips.helperPureClass.open);

			if (!target.hasClass(window.PcTrips.helperPureClass.forMobile)) {
				target.closest(window.PcTrips.pcClass.pcFilter).find(window.PcTrips.pcClass.pcFilterOptions).slideUp('fast');
			} else {
				target.parent().find(window.PcTrips.pcClass.pcFiltersMobile).slideUp('fast');
			}
		}
    }

    handleSubmitFilters(event) {

        const target = (
			jQuery(event.target).hasClass(window.PcTrips.selectorPureClass.submitFilters) ?
			jQuery(event.target) : 
			jQuery(event.target).closest(window.PcTrips.selectorClass.submitFilters)
		);

		if (target.is('disabled')) { return false; }

		event.preventDefault();

		window.PcTrips.handleSubmitState(target, true);

		jQuery(window.PcTrips.containerClass.jsTrips).html(window.PcTrips.loaderMarkup);

		if (window.PcTrips.getFilterOptionChangeState()) {
			jQuery(window.PcTrips.pcClass.pcTripsPageNumberInput).val('1');

			const fullUrl = window.location.href;
			const fullUrlUsable = new URL(fullUrl);
			
			fullUrlUsable.searchParams.delete('_page');

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

			window.PcTrips.setFilterOptionChangeState(false);
		}

		if (jQuery(`${window.PcTrips.pcClass.pcFilterOption}:checked`).length > 0) {
			
			const vw = Math.max(document.documentElement.clientWidth || 0, window.innerWidth || 0)
			const scrollTarget = vw >= 768 ? 'body' : window.PcTrips.containerClass.jsTrips;
			document.querySelector(scrollTarget).scrollIntoView({
				behavior: "smooth", 
				block: "start", 
				inline: "start"
			});

			const filters = window.PcTrips.prepareFilters();

			jQuery.ajax({
				url: window.pcPublicConfig.scripts.ajaxUrl,
				type: 'POST',
				data: {
					action: window.PcTrips.restAction,
					filters: filters,
					initialQuery: window.PcTrips.shortcodeInitialQuery,
				},
				success: (response) => {
					window.PcTrips.handleSubmitState(target, false);

					if (typeof response === 'undefined') { return false; }

					const result = JSON.parse(response);

					if (
						typeof result.success === 'undefined' ||
						result.success === null ||
						!result.success 
					) { return false; }

                    const listing = result.data.listing.split('<pc-listing>')[1].split('</pc-listing>')[0];

					jQuery(window.PcTrips.containerClass.jsTrips).html(listing);
				},
				error: (response) => {
					window.PcTrips.handleSubmitState(target, false);
					console.error(response);
				}
			});
		} else {
			window.PcTrips.handleSubmitState(target, false);
		}
    }

	prepareFilters(selectors = []) {

		if (
			typeof selectors.length === 'undefined' ||
			!selectors.length ||
			selectors.length === 0
		) {

			selectors = window.PcTrips.defaultFilterSelectors;
		}

		const jquerySelector = selectors.join(', ');

		const filterFields = jQuery(jquerySelector);

		const filters = {};
		
		if (filterFields.length === 0) { return filters; }

		filterFields.each(function() {
			const filter = jQuery(this);
			const filterKey = (
				typeof filter.attr('name') !== 'undefined' &&
				filter.attr('name').length > 0 ?
				filter.attr('name') :
				(
					typeof filter.attr('id') !== 'undefined' &&
					filter.attr('id').length > 0 ?
					filter.attr('id') :
					null
				)
			);


			if (
				filterKey &&
				typeof filters[filterKey] === 'undefined'
			) {
			
				filters[filterKey] = filter.val();
			}
		});

		return filters;
	}

	fetchShortcodeInitialQuery() {

		let initialQuery = jQuery(window.PcTrips.containerClass.jsTrips).data('shortcode-initial-query');
		
		if (
			typeof initialQuery !== 'undefined' &&
			initialQuery &&
			initialQuery.length > 0
		) {

			const initialQueryArr = initialQuery.split('&');
			const initialQueryFixedArr = [];

			initialQueryArr.forEach(function(argumentString, index) {

				const argumentArr = argumentString.split('=');
				const argumentObject = {
					key: argumentArr[0].trim(),
					value: argumentArr[1].trim(),
				};

				if (window.PcTrips.keyFromInitialQueryTrimMap.indexOf(argumentObject.key) < 0) {

					const argumentStringFixed = `${argumentObject.key}=${argumentObject.value}`;
					initialQueryFixedArr.push(argumentStringFixed);
				}
			});

			initialQuery = initialQueryFixedArr.join('&');
		}

		return (
			typeof initialQuery !== 'undefined' &&
			initialQuery &&
			initialQuery.length > 0 ?
			initialQuery :
			''
		);
	}

	handleSubmitState(target, lock = true) {

		if (lock) {

			target.attr('disabled', 'disabled');
		} else {

			target.removeAttr('disabled');
		}
	}
}

window.PcTrips = new PcTrips;