<?php
/**
 * Define a constant if it is not already defined.
 *
 * @since 3.0.0
 *
 * @param string $name Constant name.
 * @param string $value Value.
 */
function ocolus_maybe_define_constant( $name, $value )
{
	if ( !defined( $name ) ) {
		define( $name, $value );
	}
}

/**
 * Wrapper for nocache_headers which also disables page caching.
 *
 * @since 3.2.4
 */
function ocolus_nocache_headers()
{
	Ocolus_Ajax::set_nocache_constants();
	nocache_headers();
}

if ( !class_exists( 'Ocolus_Ajax' ) ) {
	class Ocolus_Ajax
	{
		/**
		 * Hook in ajax handlers.
		 */
		public static function init()
		{
			add_action( 'init', array( __CLASS__, 'define_ajax' ), 0 );
			add_action( 'template_redirect', array( __CLASS__, 'action_ajax' ), 0 );
			add_action( 'after_setup_theme', array( __CLASS__, 'add_ajax_events' ) );
			add_filter( 'wcml_multi_currency_ajax_actions', array( __CLASS__, 'multi_currency_ajax_actions' ), 10, 1 );
		}

		/**
		 * Get Ocolus Ajax Endpoint.
		 *
		 * @param  string $request Optional.
		 *
		 * @return string
		 */
		public static function get_endpoint( $request = '' )
		{
			return esc_url_raw( apply_filters( 'ocolus_ajax_get_endpoint',
					add_query_arg(
						'ocolus-ajax',
						$request,
						remove_query_arg(
							array(),
							home_url( '/', 'relative' )
						)
					),
					$request
				)
			);
		}

		/**
		 * Set constants to prevent caching by some plugins.
		 *
		 * @param  mixed $return Value to return. Previously hooked into a filter.
		 *
		 * @return mixed
		 */
		public static function set_nocache_constants( $return = true )
		{
			ocolus_maybe_define_constant( 'DONOTCACHEPAGE', true );
			ocolus_maybe_define_constant( 'DONOTCACHEOBJECT', true );
			ocolus_maybe_define_constant( 'DONOTCACHEDB', true );

			return $return;
		}

		/**
		 * Set Ocolus AJAX constant and headers.
		 */
		public static function define_ajax()
		{
			if ( !empty( $_GET['ocolus-ajax'] ) ) {
				ocolus_maybe_define_constant( 'DOING_AJAX', true );
				ocolus_maybe_define_constant( 'OCOLUS_DOING_AJAX', true );
				if ( !WP_DEBUG || ( WP_DEBUG && !WP_DEBUG_DISPLAY ) ) {
					@ini_set( 'display_errors', 0 ); // Turn off display_errors during AJAX events to prevent malformed JSON.
				}
				$GLOBALS['wpdb']->hide_errors();
			}
		}

		/**
		 * Send headers for Ocolus Ajax Requests.
		 *
		 * @since 2.5.0
		 */
		private static function ocolus_ajax_headers()
		{
			send_origin_headers();
			@header( 'Content-Type: text/html; charset=' . get_option( 'blog_charset' ) );
			@header( 'X-Robots-Tag: noindex' );
			send_nosniff_header();
			ocolus_nocache_headers();
			status_header( 200 );
		}

		/**
		 * Check for Ocolus Ajax request and fire action.
		 */
		public static function action_ajax()
		{
			global $wp_query;
			if ( !empty( $_GET['ocolus-ajax'] ) ) {
				$wp_query->set( 'ocolus-ajax', sanitize_text_field( wp_unslash( $_GET['ocolus-ajax'] ) ) );
			}
			if ( !empty( $_GET['ocolus_raw_content'] ) ) {
				$wp_query->set( 'ocolus_raw_content', sanitize_text_field( wp_unslash( $_GET['ocolus_raw_content'] ) ) );
			}
			$action  = $wp_query->get( 'ocolus-ajax' );
			$content = $wp_query->get( 'ocolus_raw_content' );
			if ( $action || $content ) {
				self::ocolus_ajax_headers();
				if ( $action ) {
					$action = sanitize_text_field( $action );
					do_action( 'ocolus_ajax_' . $action );
					wp_die();
				} else {
					remove_all_actions( 'wp_head' );
					remove_all_actions( 'wp_footer' );
					remove_all_actions( 'ocolus_footer_content' );
					remove_all_actions( 'ocolus_header_content' );
				}
			}
		}

		/**
		 * Hook in methods - uses WordPress ajax handlers (admin-ajax).
		 */
		public static function add_ajax_events()
		{
			// EVENT => nopriv.
			$ajax_events = array(
				'content_ajax_tabs'     => true,
				'add_to_cart_single'    => true,
				'loadmore_ajax_handler' => true,
				'product_load_more'     => true,
				'update_wishlist_count' => true,
			);
			$ajax_events = apply_filters( 'ocolus_ajax_event_register', $ajax_events );
			foreach ( $ajax_events as $ajax_event => $nopriv ) {
				add_action( 'wp_ajax_ocolus_' . $ajax_event, array( __CLASS__, $ajax_event ) );
				if ( $nopriv ) {
					add_action( 'wp_ajax_nopriv_ocolus_' . $ajax_event, array( __CLASS__, $ajax_event ) );
					// AJAX can be used for frontend ajax requests.
					add_action( 'ocolus_ajax_' . $ajax_event, array( __CLASS__, $ajax_event ) );
				}
			}
		}

		public static function add_to_cart_single()
		{
			$product_id = isset( $_POST['product_id'] ) ? apply_filters( 'woocommerce_add_to_cart_product_id', absint( $_POST['product_id'] ) ) : 0;
			if ( isset( $_POST['add-to-cart'] ) ) {
				$product_id = $_POST['add-to-cart'];
			}
			$product           = wc_get_product( $product_id );
			$quantity          = empty( $_POST['quantity'] ) ? 1 : wc_stock_amount( $_POST['quantity'] );
			$passed_validation = apply_filters( 'woocommerce_add_to_cart_validation', true, $product_id, $quantity );
			$product_status    = get_post_status( $product_id );
			$variation_id      = isset( $_POST['variation_id'] ) ? $_POST['variation_id'] : 0;
			$variation         = array();
			if ( $product && 'variation' === $product->get_type() ) {
				$variation_id = $product_id;
				$product_id   = $product->get_parent_id();
				$variation    = $product->get_variation_attributes();
			}
			if ( $product && $passed_validation && 'publish' === $product_status ) {
				if ( 'variation' === $product->get_type() && $variation_id > 0 && $product_id > 0 ) {
					WC()->cart->add_to_cart( $product_id, $quantity, $variation_id, $variation );
				} elseif ( is_array( $quantity ) && !empty( $quantity ) && 'group' === $product->get_type() ) {
					foreach ( $quantity as $product_id => $qty ) {
						if ( $qty > 0 )
							WC()->cart->add_to_cart( $product_id, $qty );
					}
				} elseif ( !is_array( $quantity ) && is_numeric( $quantity ) && 'simple' === $product->get_type() ) {
					WC()->cart->add_to_cart( $product_id, $quantity );
				}
				do_action( 'woocommerce_ajax_added_to_cart', $product_id );
				if ( 'yes' === get_option( 'woocommerce_cart_redirect_after_add' ) ) {
					wc_add_to_cart_message( array( $product_id => $quantity ), true );
				}
				// Return fragments
				WC_AJAX::get_refreshed_fragments();
			} else {
				// If there was an error adding to the cart, redirect to the product page to show any errors
				$data = array(
					'error'       => true,
					'product_url' => apply_filters( 'woocommerce_cart_redirect_after_error', get_permalink( $product_id ), $product_id ),
				);
				wp_send_json( $data );
			}
			wp_die();
		}

		public function multi_currency_ajax_actions( $ajax_actions )
		{
			$ajax_actions[] = 'content_ajax_tabs'; // Add a AJAX action to the array

			return $ajax_actions;
		}

		public static function update_wishlist_count()
		{
			if ( function_exists( 'YITH_WCWL' ) ) {
				wp_send_json( YITH_WCWL()->count_products() );
			}
			wp_die();
		}

		public static function content_ajax_tabs()
		{
			//check_ajax_referer( 'ocolus_ajax_security', 'security' );
			if ( isset( $_POST['section'] ) ) {
				WPBMap::addAllMappedShortcodes();
				echo wpb_js_remove_wpautop( urldecode( $_POST['section'] ) );
			}
			wp_die();
		}

		public static function loadmore_ajax_handler()
		{
			//check_ajax_referer( 'ocolus_ajax_security', 'security' );
			// prepare our arguments for the query
			$args                = (array)$_POST['query'];
			$args['paged']       = $_POST['paged'] + 1; // we need next page to be loaded
			$args['post_status'] = 'publish';
			// it is always better to use WP_Query but not here
			$posts = new WP_Query( $args );
			if ( $posts->have_posts() ) :
				// run the loop
				while ( $posts->have_posts() ): $posts->the_post();
					?>
                    <article <?php post_class( 'post-item style-01' ); ?>>
						<?php get_template_part( 'templates/blog/blog-style/content-blog', 'style-01' ); ?>
                    </article>
				<?php
				endwhile;
			endif;
			wp_die();
		}

		public static function product_load_more()
		{
			//check_ajax_referer( 'ocolus_ajax_security', 'security' );
			$data   = isset( $_POST['data'] ) ? $_POST['data'] : array();
			$class  = isset( $data['class'] ) ? $data['class'] : array();
			$args   = isset( $data['args'] ) ? $data['args'] : array();
			$target = isset( $data['target'] ) ? $data['target'] : '';
			list( $thumb_width, $thumb_height ) = isset( $data['size_thumb'] ) ? (array)$data['size_thumb'] : array( 300, 300 );
			add_filter( 'ocolus_filter_product_item',
				function () use ( $class ) {
					return $class;
				}
			);
			add_filter( 'ocolus_shop_product_thumb_width',
				function () use ( $thumb_width ) {
					return $thumb_width;
				}
			);
			add_filter( 'ocolus_shop_product_thumb_height',
				function () use ( $thumb_height ) {
					return $thumb_height;
				}
			);
			add_filter( 'woocommerce_product_loop_start',
				function () {
					return '<ul class="products">';
				}
			);
			add_filter( 'woocommerce_product_loop_end',
				function () {
					return '</ul>';
				}
			);
			if ( $target != '' )
				echo ocolus_do_shortcode(
					$target,
					ocolus_shortcode_products_query( $args )
				);
			wp_die();
		}
	}

	Ocolus_Ajax::init();
}