<?php
namespace TotalTheme\Pagination;

use WP_Query;

defined( 'ABSPATH' ) || exit;

/**
 * Load more pagination.
 *
 * @package TotalTheme
 * @subpackage Author
 * @version 5.5
 */
class Load_More {

	/**
	 * Query var used to store loadmore POST data.
	 */
	const QUERY_VAR = 'wpex_loadmore_data';

	/**
	 * Checks if we are currently fetching posts.
	 */
	public static function is_doing_ajax() {
		if ( wp_doing_ajax() && isset( $_REQUEST['action'] ) && 'wpex_ajax_load_more' === $_REQUEST['action'] ) {
			return true;
		}
		return false;
	}

	/**
	 * Returns load more data.
	 *
	 * @todo prefix loadmore.
	 */
	public static function get_data( $key = '' ) {
		if ( empty( $_POST['loadmore'] ) || ! self::is_doing_ajax() ) {
			return;
		}
		$data = get_query_var( self::QUERY_VAR );
		if ( $key ) {
			return $data[$key] ?? '';
		}
		return $data;
	}

	/**
	 * Enqueues load more scripts.
	 */
	public static function enqueue_scripts() {
		// Make sure possibly needed scripts are loaded.
		// Is it possible to optimize this somehow? (maybe have a multi-select in the customizer where you can select which scripts get added (Slider, Lightbox, WPMedia)).
		wpex_enqueue_slider_pro_scripts();
		wpex_enqueue_lightbox_scripts();

		// WP Media.
		if ( get_theme_mod( 'blog_entry_audio_output', false ) || apply_filters( 'wpex_loadmore_enqueue_mediaelement', false ) ) {
			wp_enqueue_style( 'wp-mediaelement' );
			wp_enqueue_script( 'wp-mediaelement' );
		}

		// Theme loadmore script.
		if ( WPEX_MINIFY_JS ) {
			$file = 'wpex-loadmore.min.js';
		} else {
			$file = 'wpex-loadmore.js';
		}

		wp_enqueue_script(
			'wpex-loadmore',
			wpex_asset_url( 'js/dynamic/' . $file ),
			array( 'jquery', 'imagesloaded', WPEX_THEME_JS_HANDLE ),
			WPEX_THEME_VERSION,
			true
		);

		wp_localize_script(
			'wpex-loadmore',
			'wpex_loadmore_params',
			array(
				'ajax_url' => set_url_scheme( admin_url( 'admin-ajax.php' ) ),
				'i18n'     => array(
					'text'        => sanitize_text_field( self::get_more_text() ),
					'loadingText' => sanitize_text_field( self::get_loading_text() ),
					'failedText'  => sanitize_text_field( self::get_failed_text() ),
				),
			)
		);
	}

	/**
	 * Returns an array of loader options.
	 */
	public static function get_loader_svg_options() {
		return array(
			''                 => esc_html__( 'Default', 'total' ),
			'ball-triangle'    => esc_html__( 'Ball Triangle', 'total' ),
			'bars'             => esc_html__( 'Bars', 'total' ),
			'circles'          => esc_html__( 'Circles', 'total' ),
			'grid'             => esc_html__( 'Grid', 'total' ),
			'oval'             => esc_html__( 'Oval', 'total' ),
			'puff'             => esc_html__( 'Puff', 'total' ),
			'rings'            => esc_html__( 'Rings', 'total' ),
			'spinning-circles' => esc_html__( 'Spinning Circles', 'total' ),
			'tail-spin'        => esc_html__( 'Tail Spin', 'total' ),
			'three-dots'       => esc_html__( 'Three Dots', 'total' ),
			'wordpress'        => 'WordPress',
		);
	}

	/**
	 * Returns loader gif.
	 */
	public static function get_loader_gif() {
		return (string) apply_filters( 'wpex_loadmore_gif', null );
	}

	/**
	 * Returns loader svg.
	 */
	public static function get_loader_svg() {
		$svg = get_theme_mod( 'loadmore_svg' ) ?: 'wordpress';
		if ( ! $svg || ! array_key_exists( $svg, self::get_loader_svg_options() ) ) {
			$svg = self::get_default_svg();
		}
		return $svg;
	}

	/**
	 * Returns loader svg html.
	 */
	public static function get_loader_svg_html( $svg = '', $size = '' ) {
		if ( ! $svg ) {
			$svg = self::get_loader_svg();
		}
		if ( ! $size ) {
			$size = absint( get_theme_mod( 'loadmore_svg_size' ) ) ?: 20;
		}
		if ( $svg ) {
			return wpex_get_svg( 'loaders/' . $svg, $size );
		}
	}

	/**
	 * Returns the more text.
	 */
	public static function get_more_text() {
		$text = wpex_get_translated_theme_mod( 'loadmore_text' ) ?: esc_html__( 'Load More', 'total' );

		/**
		 * Filters the load more button text.
		 *
		 * @param string $text
		 */
		$text = (string) apply_filters( 'wpex_loadmore_text', $text );

		return $text;
	}

	/**
	 * Returns the loading text.
	 */
	public static function get_loading_text() {
		$text = wpex_get_translated_theme_mod( 'loadmore_loading_text' ) ?: esc_html__( 'Loading...', 'total' );

		/**
		 * Filters the load more loading button text.
		 *
		 * @param string $text
		 */
		$text = (string) apply_filters( 'wpex_loadmore_loading_text', $text );

		return $text;
	}

	/**
	 * Returns the failed text.
	 */
	public static function get_failed_text() {
		$text = wpex_get_translated_theme_mod( 'loadmore_failed_text' ) ?: esc_html__( 'Failed to load posts.', 'total' );

		/**
		 * Filters the load more failed text.
		 *
		 * @param string $text
		 */
		$text = (string) apply_filters( 'wpex_loadmore_failed_text', $text );

		return $text;
	}

	/**
	 * Render button.
	 */
	public static function render_button( $args = array() ) {
		$page = get_query_var( 'paged' ) ?: 1;

		global $wp_query;

		// define load more default args.
		$defaults = [
			'grid'            => '#blog-entries',
			'loop_type'       => 'blog',
			'nonce'           => wp_create_nonce( 'wpex-load-more-nonce' ),
			'page'            => $page,
			'maxPages'        => $wp_query->max_num_pages,
			'infinite_scroll' => false,
			'count'           => wpex_get_loop_counter(),
			'query_vars'      => wp_json_encode( $wp_query->query_vars ),

			// @todo deprecate?
			'is_home'         => is_home(),
			'category'        => is_category() ? get_query_var( 'cat' ) : false, // is this being used anywhere?
		];

		/**
		 * Add current term_id to args.
		 * Required for meta field checks (custom term settings).
		 */
		if ( is_category() || is_tag() || is_tax() ) {
			$defaults['term_id'] = get_queried_object_id();
		}

		$args                = wp_parse_args( $args, $defaults );
		$max_pages           = absint( $args['maxPages'] ?? 1 );
		$has_infinite_scroll = wp_validate_boolean( $args['infinite_scroll'] ?? false );

		if ( ! wp_doing_ajax() && ( ! $max_pages || $max_pages === 1 || ( $max_pages == $page ) ) ) {
			return; // there isn't any pagination.
		}

		self::enqueue_scripts();

		$output = '';

		$output .= '<div class="wpex-load-more-wrap wpex-pt-10 wpex-text-center">';

			$button_class = 'wpex-load-more';

			if ( $has_infinite_scroll ) {
				$button_class .= ' wpex-load-more--infinite-scroll wpex-h-1px';
			}

			$button_class .= ' theme-button';

			if ( get_theme_mod( 'loadmore_btn_expanded', true ) ) {
				$button_class .= ' expanded';
			}

			if ( ! $has_infinite_scroll && $max_pages && $max_pages > 1 ) {
				$button_class .= ' wpex-visible';
			}

			$output .= '<a href="#" class="' . esc_attr( $button_class ) . '" data-loadmore="' . htmlentities( wp_json_encode( $args ) ) . '">';

				$output .= '<span class="theme-button-inner">' . esc_html( self::get_more_text() ) . '</span>';

			$output .= '</a>';

			$gif = self::get_loader_gif();

			if ( $gif ) {
				$output .= '<img src="' . esc_url( $gif ) . '" class="wpex-spinner" alt="' . esc_attr( self::get_loading_text() ) . '">';
			} else {
				$svg = self::get_loader_svg_html();
				if ( $svg ) {
					$output .= '<div class="wpex-spinner">' . $svg . '</div>';
				}
			}

			$output .= '</div>';

		echo $output; // @codingStandardsIgnoreLine
	}

	/**
	 * Get posts via AJAX.
	 */
	public static function get_posts() {
		check_ajax_referer( 'wpex-load-more-nonce', 'nonce' );

		if ( empty( $_POST['loadmore'] ) || ! is_array( $_POST['loadmore'] ) ) {
			wp_die();
		}

		$loadmore = $_POST['loadmore'];
		//$loadmore = json_decode( html_entity_decode( stripslashes( $_POST['loadmore'] ) ), true );

		$query_args = $loadmore['query_vars'] ?? $loadmore['query'] ?? [];
		if ( is_string( $query_args ) ) {
			$query_args = json_decode( stripslashes_deep( $query_args ), true );
			$loadmore['query_vars'] = $query_args; // update array.
		}

		if ( ! is_array( $query_args ) ) {
			return;
		}

		// Make sure we are only querying published posts since WP doesn't know we are on the front-end.
		$query_args['post_status'] = 'publish';

		// Updated query paged argument.
		$query_args['paged'] = absint( $_POST['page'] ?? 2 );

		wpex_set_loop_counter( $loadmore['count'] ?? 0 );

		// Update load more data.
		set_query_var( self::QUERY_VAR, $loadmore );

		$loop_type = $loadmore['loop_type'] ?? 'blog';

		$posts = new WP_Query( $query_args );

		ob_start();

			if ( $posts->have_posts() ) :
				while ( $posts->have_posts() ): $posts->the_post();
					get_template_part( 'partials/loop/loop', $loop_type );
				endwhile;
			endif;

			// used to update wpex_set_loop_counter()
			echo '<div class="wpex-hidden" data-count="' . esc_attr( wpex_get_loop_counter() ) . '"></div>';

			wp_reset_postdata();

			set_query_var( self::QUERY_VAR, null );

		$data = ob_get_clean();

		wp_send_json_success( $data );

		wp_die();
	}

}