<?php
/**
 * Static class that will handle all ajax calls for the list
 *
 * @author Your Inspiration Themes
 * @package YITH WooCommerce Wishlist
 * @version 3.0.0
 */

if ( ! defined( 'YITH_WCWL' ) ) {
	exit;
} // Exit if accessed directly

if ( ! class_exists( 'YITH_WCWL_Ajax_Handler' ) ) {
	/**
	 * WooCommerce Wishlist Ajax Handler
	 *
	 * @since 3.0.0
	 */
	class YITH_WCWL_Ajax_Handler {
		/**
		 * Performs all required add_actions to handle forms
		 *
		 * @return void
		 */
		public static function init() {
			// add to wishlist
			add_action( 'wp_ajax_add_to_wishlist', array( 'YITH_WCWL_Ajax_Handler', 'add_to_wishlist' ) );
			add_action( 'wp_ajax_nopriv_add_to_wishlist', array( 'YITH_WCWL_Ajax_Handler', 'add_to_wishlist' ) );

			// remove from wishlist
			add_action( 'wp_ajax_remove_from_wishlist', array( 'YITH_WCWL_Ajax_Handler', 'remove_from_wishlist' ) );
			add_action( 'wp_ajax_nopriv_remove_from_wishlist', array( 'YITH_WCWL_Ajax_Handler', 'remove_from_wishlist' ) );

			// remove from wishlist (button)
			add_action( 'wp_ajax_delete_item', array( 'YITH_WCWL_Ajax_Handler', 'delete_item' ) );
			add_action( 'wp_ajax_nopriv_delete_item', array( 'YITH_WCWL_Ajax_Handler', 'delete_item' ) );

			// load mobile templates
			add_action( 'wp_ajax_load_mobile', array( 'YITH_WCWL_Ajax_Handler', 'load_mobile' ) );
			add_action( 'wp_ajax_nopriv_load_mobile', array( 'YITH_WCWL_Ajax_Handler', 'load_mobile' ) );

			// add to wishlist and reload
			add_action( 'wp_ajax_reload_wishlist_and_adding_elem', array( 'YITH_WCWL_Ajax_Handler', 'reload_wishlist_and_adding_elem' ) );
			add_action( 'wp_ajax_nopriv_reload_wishlist_and_adding_elem', array( 'YITH_WCWL_Ajax_Handler', 'reload_wishlist_and_adding_elem' ) );

			// load fragments
			add_action( 'wp_ajax_load_fragments', array( 'YITH_WCWL_Ajax_Handler', 'load_fragments' ) );
			add_action( 'wp_ajax_nopriv_load_fragments', array( 'YITH_WCWL_Ajax_Handler', 'load_fragments' ) );
		}

		/**
		 * Add to wishlist from ajax call
		 *
		 * @return void
		 */
		public static function add_to_wishlist() {
			try {
				YITH_WCWL()->add();

				$return = 'true';
				$message = apply_filters( 'yith_wcwl_product_added_to_wishlist_message', get_option( 'yith_wcwl_product_added_text' ) );
			}
			catch( YITH_WCWL_Exception $e ){
				$return = $e->getTextualCode();
				$message = apply_filters( 'yith_wcwl_error_adding_to_wishlist_message', $e->getMessage() );
			}
			catch( Exception $e ){
				$return = 'error';
				$message = apply_filters( 'yith_wcwl_error_adding_to_wishlist_message', $e->getMessage() );
			}

			$product_id = isset( $_REQUEST['add_to_wishlist'] ) ? intval( $_REQUEST['add_to_wishlist'] ) : false;
			$fragments = isset( $_REQUEST['fragments'] ) ? $_REQUEST['fragments'] : false;
			$wishlist_url = YITH_WCWL()->get_last_operation_url();

			$wishlists = YITH_WCWL_Wishlist_Factory::get_wishlists();
			$wishlists_to_prompt = array();

			foreach(  $wishlists as $wishlist ){
				$wishlists_to_prompt[] = array(
					'id' => $wishlist->get_id(),
					'wishlist_name' => $wishlist->get_formatted_name(),
					'add_to_this_wishlist_url' => $product_id ? add_query_arg( array(
						'add_to_wishlist' => $product_id,
						'wishlist_id' => $wishlist->get_id()
					) ) : ''
				);
			}

			if( in_array( $return, array( 'exists', 'true' ) ) ){
				// search for related fragments
				if( ! empty( $fragments ) && ! empty( $product_id ) ){
					foreach( $fragments as $id => $options ){
						if( strpos( $id, 'add-to-wishlist-' . $product_id ) ){
							$fragments[ $id ]['wishlist_url'] = $wishlist_url;
							$fragments[ $id ]['added_to_wishlist'] = $return == 'true';
						}
					}
				}
			}

			wp_send_json(
				apply_filters( 'yith_wcwl_ajax_add_return_params', array(
					'prod_id' => $product_id,
					'result' => $return,
					'message' => $message,
					'fragments' => self::refresh_fragments( $fragments ),
					'user_wishlists' => $wishlists_to_prompt,
					'wishlist_url' => $wishlist_url
				) )
			);
		}

		/**
		 * Remove from wishlist from ajax call
		 *
		 * @return void
		 */
		public static function remove_from_wishlist() {
			try{
				YITH_WCWL()->remove();
				$message = apply_filters( 'yith_wcwl_product_removed_text', __( 'Product successfully removed.', 'yith-woocommerce-wishlist' ) );
			}
			catch( Exception $e ){
				$message = $e->getMessage();
			}

			wc_add_notice( $message );

			wp_send_json( array(
				'fragments' => self::refresh_fragments( isset( $_REQUEST['fragments'] ) ? $_REQUEST['fragments'] : false )
			) );
		}

		/**
		 * Remove item from a wishlist
		 * Differs from remove from wishlist, since this accepts item id instead of product id
		 *
		 * @return void
		 * @since 3.0.0
		 */
		public static function delete_item() {
			$item_id = isset( $_POST['item_id'] ) ? intval( $_POST['item_id'] ) : false;
			$return = array(
				'result' => false
			);

			if( $item_id ){
				$item = YITH_WCWL_Wishlist_Factory::get_wishlist_item( $item_id );

				if( $item ){
					$item->delete();

					$return = array(
						'result' => true,
						'message' => apply_filters( 'yith_wcwl_product_removed_text', __( 'Product successfully removed.', 'yith-woocommerce-wishlist' ) ),
						'fragments' => YITH_WCWL_Ajax_Handler::refresh_fragments( isset( $_REQUEST['fragments'] ) ? $_REQUEST['fragments'] : false )
					);
				}
			}

			wp_send_json( $return );
		}

		/**
		 * Generated fragments to replace in the the page
		 *
		 * @return void
		 * @since 3.0.0
		 */
		public static function load_fragments() {
			wp_send_json( array(
				'fragments' => self::refresh_fragments( isset( $_POST['fragments'] ) ? $_POST['fragments'] : false )
			) );
		}

		/**
		 * Reload wishlist and adding elem action
		 *
		 * @return void
		 * @since 1.0.0
		 */
		public static function reload_wishlist_and_adding_elem() {
			$type_msg   = 'success';

			try {
				YITH_WCWL()->add();
				$message = apply_filters( 'yith_wcwl_product_added_to_wishlist_message', get_option( 'yith_wcwl_product_added_text' ) );
			}
			catch( YITH_WCWL_Exception $e ){
				$message = $e->getMessage();
				$type_msg = $e->getTextualCode();
			}
			catch( Exception $e ){
				$message = $e->getMessage();
				$type_msg = 'error';
			}

			$wishlist_token = isset( $_REQUEST['wishlist_token'] ) ? $_REQUEST['wishlist_token'] : false;

			$atts = array( 'wishlist_id' => $wishlist_token );
			if( isset( $_REQUEST['pagination'] ) ){
				$atts['pagination'] = $_REQUEST['pagination'];
			}

			if( isset( $_REQUEST['per_page'] ) ){
				$atts['per_page'] = $_REQUEST['per_page'];
			}

			ob_start();

			wc_add_notice( $message, $type_msg );

			echo '<div>'. YITH_WCWL_Shortcode::wishlist( $atts ) . '</div>';

			echo ob_get_clean();
			die();

		}

		/**
		 * Reloads fragments, returning mobile version when available
		 *
		 * @return void
		 * @since 3.0.0
		 */
		public static function load_mobile() {
			global $yith_wcwl_is_mobile;

			$fragments = isset( $_POST['fragments'] ) ? $_POST['fragments'] : false;
			$result = array();

			if( ! empty( $fragments ) ){
				foreach( $fragments as $id => $options ){
					$yith_wcwl_is_mobile = isset( $options['is_mobile'] ) ? 'yes' == $options['is_mobile'] : false;

					$result = array_merge( $result, self::refresh_fragments( array( $id => $options ) ) );
				}
			}

			wp_send_json( array(
				'fragments' => $result
			) );
		}

		/**
		 * Generate fragments for the templates that needs to be refreshed after ajax
		 *
		 * @param $fragments array Array of fragments to refresh
		 * @return array Array of templates to be replaced on the page
		 */
		public static function refresh_fragments( $fragments ) {
			$result = array();

			if( ! empty( $fragments ) ){
				foreach( $fragments as $id => $options ){
					$options = YITH_WCWL_Frontend()->decode_fragment_options( $options );
					$item = isset( $options['item'] ) ? $options['item'] : false;

					if( ! $item ){
						continue;
					}

					switch( $item ){
						case 'add_to_wishlist':
						case 'wishlist':
							$result[ $id ] = YITH_WCWL_Shortcode::$item( $options );
							break;
						case 'YITH_WCWL_Widget':
						case 'YITH_WCWL_Items_Widget':
							ob_start();
							the_widget( $item, $options );
							$result[ $id ] = ob_get_clean();
							break;
						default:
							$result[ $id ] = apply_filters( 'yith_wcwl_fragment_output', '', $id, $options );
							break;
					}
				}
			}

			return $result;
		}
	}
}
YITH_WCWL_Ajax_Handler::init();