<?php
/**
 * This class manage all ajax features
 *
 * @package YITH\DynamicPricingAndDiscounts\Classes
 */

if ( ! defined( 'ABSPATH' ) ) {
	exit;
}
use Automattic\WooCommerce\StoreApi\SchemaController;
use Automattic\WooCommerce\StoreApi\StoreApi;
/**
 * Class YWDPD_Ajax
 */
class YWDPD_Ajax {
	/**
	 * Add ajax events
	 *
	 * @author YITH <plugins@yithemes.com>
	 * @since  3.0.0
	 */
	public static function init() {

		$frontend_actions = YWDPD_Assets::get_actions( 'popup_action', 'frontend' );
		$product_actions  = YWDPD_Assets::get_actions( 'product_action', 'frontend' );

		foreach ( $frontend_actions as $function => $ajax_event ) {   
			add_action( 'wp_ajax_' . $ajax_event, array( __CLASS__, $function ) );
			add_action( 'wp_ajax_nopriv_' . $ajax_event, array( __CLASS__, $function ) );
		}

		foreach ( $product_actions as $function => $ajax_event ) {
			add_action( 'wp_ajax_' . $ajax_event, array( __CLASS__, $function ) );
			add_action( 'wp_ajax_nopriv_' . $ajax_event, array( __CLASS__, $function ) );
		}

		$admin_action = YWDPD_Assets::get_actions( 'table_rule' );
		foreach ( $admin_action as $function => $ajax_event ) {
			add_action( 'wp_ajax_' . $ajax_event, array( __CLASS__, $function ) );
		}

		add_action( 'wp_ajax_update_cart_after_payment_method', array(
			__CLASS__,
			'update_cart_after_payment_method'
		) );
		add_action( 'wp_ajax_nopriv_update_cart_after_payment_method', array(
			__CLASS__,
			'update_cart_after_payment_method'
		) );
	}

	/**
	 * Show the second step of the popup
	 *
	 * @since  3.0.0
	 */
	public static function show_second_step() {
		check_ajax_referer( 'show-second-step', 'security' );
		$posted = $_REQUEST;
		if ( isset( $posted['product_id'] ) ) {

			$rule_type = isset( $posted['rule_type'] ) ? $posted['rule_type'] : 'gift_products';
			$args      = array(
				'product_id' => $posted['product_id'],
				'rule_id'    => $posted['rule_id'],
				'rule_type'  => $rule_type,
				'discount'   => array(
					'type'   => 'percentage',
					'amount' => 1,
				),
			);

			if ( 'special_offer' === $rule_type ) {
				$rule = ywdpd_get_rule( $posted['rule_id'] );
				$rule = $rule instanceof YWDPD_Special_Offer && $rule->is_valid() ? $rule : false;
				if ( $rule ) {

					$discount_mode              = $rule->get_so_rule();
					$args['discount']['type']   = $discount_mode['type_discount'];
					$args['discount']['amount'] = $discount_mode['discount_amount'];
				}
			}
			ob_start();
			wc_get_template( 'yith_ywdpd_popup_single_product.php', $args, YITH_YWDPD_TEMPLATE_PATH, YITH_YWDPD_TEMPLATE_PATH );
			$template = ob_get_contents();
			ob_end_clean();

			wp_send_json( array( 'template' => $template ) );
		}
	}

	/**
	 * Add the gift product in the cart
	 *
	 * @throws Exception The Exception.
	 * @since  3.0.0
	 */
	public static function add_gift_to_cart() {

		check_ajax_referer( 'add-gift-to-cart', 'security' );

		if ( isset( $_REQUEST['rules_to_apply'] ) ) {
			$gift_class = ywdpd_dynamic_pricing_discounts()->get_gift_rules_manager();
			$gift_class->load_gift_rules();
			$gift_class->check_if_apply_rules();
			$rules = wp_unslash( $_REQUEST['rules_to_apply'] ); // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized

			foreach ( $rules as $rule_id => $products_to_add ) {
				$rule_id   = str_replace( 'ywdpd_single_rule_', '', $rule_id );
				$gift_rule = ywdpd_get_rule( $rule_id );
				if ( $gift_rule instanceof YWDPD_Gift_Products ) {

					$total_items_in_cart = $gift_rule->get_total_gift_product_in_cart();
					$allowed_items       = $gift_rule->get_amount_gift_product_allowed();

					foreach ( $products_to_add as $product_to_add ) {

						$qty          = ! empty( $product_to_add['quantity'] ) ? $product_to_add['quantity'] : 1;
						$product_id   = isset( $product_to_add['product_id'] ) ? $product_to_add['product_id'] : false;
						$variation_id = ! empty( $product_to_add['variation_id'] ) && $product_to_add['variation_id'] > 0 ? $product_to_add['variation_id'] : 0;
						$variations   = ! empty( $product_to_add['variations'] ) ? $product_to_add['variations'] : array();
						$product      = wc_get_product( $product_id );
						if ( 'variation' === $product->get_type() && 0 === $variation_id ) {
							$product_id   = $product->get_parent_id();
							$variation_id = $product->get_id();
							$variations   = $product->get_attributes();
						}
						if ( $product_id && $total_items_in_cart + $qty <= $allowed_items ) {

							$product = wc_get_product( $product_id );

							if ( $variation_id > 0 && count( $variations ) > 0 ) {

								$product = wc_get_product( $variation_id );
							}
							$total_items_in_cart += $qty;

							$cart_key = WC()->cart->add_to_cart(
								$product_id,
								$qty,
								$variation_id,
								$variations,
								array(
									'ywdpd_is_gift_product' => true,
									'ywdpd_rule_id'         => $rule_id,
									'ywdpd_time'            => time(),
								)
							);
							/* translators: name of product */
							wc_add_notice( sprintf( __( 'Gift %s added properly', 'ywdpd' ), $product->get_formatted_name() ) );
						}
					}
				}
			}
			wc_print_notices();
			wp_die();
		}

	}

	/**
	 * Add the product in the cart and will be applied the special offer
	 *
	 * @auhtor YITH
	 * @throws Exception The exception.
	 * @since  3.0
	 */
	public static function add_special_to_cart() {
		check_ajax_referer( 'add-special-to-cart', 'security' );
		$posted = $_REQUEST;
		if ( isset( $posted['rules_to_apply'] ) ) {
			$rules = $posted['rules_to_apply'];
			foreach ( $rules as $rule_id => $products_to_add ) {
				foreach ( $products_to_add as $product_to_add ) {

					$qty          = ! empty( $product_to_add['quantity'] ) ? $product_to_add['quantity'] : 1;
					$product_id   = $product_to_add['product_id'] ?? false;
					$variation_id = ! empty( $product_to_add['variation_id'] ) && $product_to_add['variation_id'] > 0 ? $product_to_add['variation_id'] : 0;
					$variations   = ! empty( $product_to_add['variations'] ) ? $product_to_add['variations'] : array();

					if ( $product_id ) {

						$product = wc_get_product( $product_id );
						if ( 'variation' === $product->get_type() && 0 === $variation_id ) {
							$product_id   = $product->get_parent_id();
							$variation_id = $product->get_id();
							$variations   = $product->get_attributes();
						}

						if ( $variation_id > 0 && count( $variations ) > 0 ) {

							$product = wc_get_product( $variation_id );
						}

						$cart_item_key = WC()->cart->add_to_cart(
							$product_id,
							$qty,
							$variation_id,
							$variations
						);

						wc_add_to_cart_message( array( $product->get_id() => $qty ) );

					}
				}
			}

			WC_AJAX::get_refreshed_fragments();
		}
	}

	/**
	 * Add the last deal products
	 *
	 * @return void
	 * @throws Exception The exception.
	 * @since 4.0.0
	 */
	public static function add_last_deals() {
		check_ajax_referer( 'add-last-deals', 'security' );
		if ( isset( $_REQUEST['rules_to_apply'] ) ) {
			$rules = wp_unslash( $_REQUEST['rules_to_apply'] ); // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
			foreach ( $rules as $rule_id => $products_to_add ) {
				$rule_id   = str_replace( 'ywdpd_single_rule_', '', $rule_id );
				$deal_rule = ywdpd_get_rule( $rule_id );

				if ( $deal_rule instanceof YWDPD_Last_Deals && $deal_rule->is_valid() && ! $deal_rule->has_last_deals_in_cart() ) {
					$has_limit  = $deal_rule->has_limits();
					$max_qty    = $deal_rule->get_deal_max_unit_product_to_add();
					$total_prod = $deal_rule->get_deal_total_product_to_add();
					$total      = 0;
					foreach ( $products_to_add as $product_to_add ) {

						$qty          = ! empty( $product_to_add['quantity'] ) ? $product_to_add['quantity'] : 1;
						$product_id   = isset( $product_to_add['product_id'] ) ? $product_to_add['product_id'] : false;
						$variation_id = ! empty( $product_to_add['variation_id'] ) && $product_to_add['variation_id'] > 0 ? $product_to_add['variation_id'] : 0;
						$variations   = ! empty( $product_to_add['variations'] ) ? $product_to_add['variations'] : array();
						$product      = wc_get_product( $product_id );
						if ( - 1 !== $product->get_max_purchase_quantity() ) {
							$qty = min( $qty, $product->get_max_purchase_quantity() );
						}
						if ( $has_limit && $total_prod < $total ) {
							continue;
						}
						if ( $has_limit ) {
							$qty = min( $qty, $max_qty );
						}
						if ( 'variation' === $product->get_type() && 0 === $variation_id ) {
							$product_id   = $product->get_parent_id();
							$variation_id = $product->get_id();
							$variations   = $product->get_attributes();
						}

						if ( $product_id ) {

							$product = wc_get_product( $product_id );

							if ( $variation_id > 0 && count( $variations ) > 0 ) {

								$product = wc_get_product( $variation_id );
							}
							$cart_data           = array(
								'ywdpd_is_deals_product' => true,
								'ywdpd_rule_id'          => $rule_id,
							);
							$product_in_cart_key = WC()->cart->generate_cart_id( $product_id, $variation_id, $variations, $cart_data );
							// The product is in the cart , avoid to add it again.
							if ( isset( WC()->cart->cart_contents[ $product_in_cart_key ] ) ) {
								continue;
							}
							$total ++;

							WC()->cart->add_to_cart(
								$product_id,
								$qty,
								$variation_id,
								$variations,
								$cart_data
							);
							/* translators: name of product */
							wc_add_notice( sprintf( __( 'Deal %s added properly', 'ywdpd' ), $product->get_formatted_name() ) );
						}
					}
				}
			}
			wc_print_notices();
			wp_die();
		}
	}

	/**
	 * Check if a variation is already added as gift or special offer
	 *
	 * @since  3.0.0
	 */
	public static function check_variable() {
		check_ajax_referer( 'check-variable', 'security' );
		$posted = $_REQUEST;
		if ( isset( $posted['ywdp_check_rule_id'] ) && isset( $posted['product_id'] ) ) {

			$rule_id    = $posted['ywdp_check_rule_id'];
			$product_id = $posted['product_id'];
			$find       = false;
			$product    = wc_get_product( $product_id );
			$old_price  = $product->get_price();
			if ( 'special_offer' === $posted['rule_type'] ) {
				$discount_type   = $posted['type_discount'];
				$discount_amount = $posted['amount_discount'];
				$total_to_add    = $posted['tot_to_add'];

				if ( 'percentage' === $discount_type ) {
					if ( 1 === intval( $discount_amount ) ) {
						$new_price = 0;
					} else {
						$new_price = $old_price - ( $old_price * $discount_amount );
						$new_price = wc_get_price_to_display( $product, array( 'price' => $old_price * $new_price ) );
					}
				} elseif ( 'price' === $discount_type ) {
					$new_price = $old_price - $discount_amount;
					$new_price = $new_price > 0 ? wc_get_price_to_display( $product, array( 'price' => $new_price ) ) : 0;
				} else {
					$new_price = wc_get_price_to_display( $product, array( 'price' => $discount_amount ) );
				}
				$validated_rule = ywdpd_get_rule( $rule_id );
				$rule           = $validated_rule instanceof YWDPD_Gift_Products ?? $validated_rule;
				if ( $rule ) {
					$total_added = YWDPD_Counter::get_product_with_dynamic_rule_counter( 'special_offer', $rule_id );

					if ( $total_added < $total_to_add ) {
						$find = false;
					} else {
						$find = true;
					}
				}
			} else {
				$new_price = 0;
				if ( ! is_null( WC()->cart ) ) {

					foreach ( WC()->cart->get_cart_contents() as $cart_item_key => $cart_item ) {

						$cart_rule_id = isset( $cart_item['ywdpd_rule_id'] ) ? $cart_item['ywdpd_rule_id'] : false;

						if ( $cart_rule_id && $rule_id == $cart_rule_id && $product_id == $cart_item['variation_id'] ) { // phpcs:ignore
							$find = true;
							break;
						}
					}
				}
			}

			$price_html = wc_format_sale_price( wc_get_price_to_display( $product, array( 'price' => $old_price ) ), $new_price );
			wp_send_json(
				array(
					'variation_found' => $find,
					'price'           => $price_html,
				)
			);
		}
	}

	/**
	 * Show again th gift popup is necessary
	 *
	 * @since  3.0.0
	 */
	public static function update_gift_popup() {
		check_ajax_referer( 'update-gift-popup', 'security' );
		$template   = '';
		$gift_class = ywdpd_dynamic_pricing_discounts()->get_gift_rules_manager();
		ob_start();
		$gift_class->print_popup_for_gift_rules();
		$template = ob_get_clean();
		wp_send_json( array( 'popup' => $template ) );
	}

	/**
	 * Update the product price in product page
	 *
	 * @since  3.0.0
	 */
	public static function update_product_price() {

		check_ajax_referer( 'update-product-price', 'security' );

		$rule_id       = isset( $_REQUEST['rule_id'] ) ? sanitize_text_field( wp_unslash( $_REQUEST['rule_id'] ) ) : false;
		$product_id    = isset( $_REQUEST['product_id'] ) ? sanitize_text_field( wp_unslash( $_REQUEST['product_id'] ) ) : false;
		$qty           = isset( $_REQUEST['qty'] ) ? sanitize_text_field( wp_unslash( $_REQUEST['qty'] ) ) : false;
		$price_updated = '';

		if ( $rule_id && $product_id && $qty ) {

			$rule    = ywdpd_get_rule( $rule_id );
			$product = wc_get_product( $product_id );
			/**
			 * APPLY_FILTERS: ywdpd_change_base_price
			 *
			 * Change the base product price.
			 *
			 * @param float $price The price.
			 * @param WC_Product $product The product.
			 *
			 * @return float
			 */
			$price = apply_filters( 'ywdpd_change_base_price', $product->get_price( 'edit' ), $product );

			if ( $rule instanceof YWDPD_Quantity_Table ) {

				$new_price     = $rule->get_discounted_price( $price, $qty, $product );
				$price_updated = YWDPD_Utils::get_product_new_price_html( $price, $new_price, $product );

			}
		}
		wp_send_json( $price_updated );

	}

	/**
	 * Sort the rules by priority
	 *
	 * @since  3.0.0
	 */
	public static function sort_discount_rules() {

		check_ajax_referer( 'sort-discount-rules', 'security' );

		$rule_ids = isset( $_POST['rule_ids'] ) ? sanitize_text_field( wp_unslash( $_POST['rule_ids'] ) ) : array();
		$rule_ids = explode( ',', $rule_ids );
		$priority = 1;
		foreach ( $rule_ids as $rule_id ) {
			update_post_meta( $rule_id, '_priority', $priority ++ );
		}

		ywdpd_delete_plugin_transient();
		die();

	}

	/**
	 * Enable or disable a rule
	 *
	 * @throws Exception The exception.
	 * @since  3.0.0
	 */
	public static function enable_or_disable_rule() {

		check_ajax_referer( 'enable-or-disable-rule', 'security' );
		$id      = isset( $_REQUEST['id'] ) ? sanitize_text_field( wp_unslash( $_REQUEST['id'] ) ) : false;
		$enabled = isset( $_REQUEST['enabled'] ) ? sanitize_text_field( wp_unslash( $_REQUEST['enabled'] ) ) : false;
		if ( $id && $enabled ) {
			$discount_id = absint( $id );
			$post        = ywdpd_get_rule( $discount_id );
			$post->set_active( $enabled );
			if ( $post ) {
				update_post_meta( $discount_id, '_active', $enabled );
				ywdpd_delete_plugin_transient();
				ywdpd_clear_modal_rule_cookie();
				/**
				 * The data store
				 *
				 * @var YWDPD_Dynamic_Rules_Data_Store $data_store ;
				 */
				$data_store = WC_Data_Store::load( 'ywdpd_dynamic_rules' );
				if ( $data_store->rule_exists( $id ) ) {
					$data_store->update( $id );
				} else {
					$data_store->create( $id );
				}
				do_action( 'ywdpd_dynamic_rules_after_toggle', $id );
				wp_send_json(
					array(
						'success'          => true,
						'new_status'       => $enabled,
						'formatted_status' => $post->get_formatted_status(),
					)
				);
			} else {
				wp_send_json(
					array(
						'error' => sprintf(
						/* translators: %s is the rule id */
							__( 'Error: Discount #%s not found', 'ywpdp' ),
							$discount_id
						),
					)
				);
			}
		}

	}

	/**
	 * Check if show the popup for special offer also in the shop pages
	 *
	 * @since  3.0.0
	 */
	public static function show_popup_on_shop() {
		check_ajax_referer( 'show-popup-on-shop', 'security' );
		$template         = '';
		$price_rule_class = ywdpd_dynamic_pricing_discounts()->get_price_rules_manager();
		ob_start();
		$price_rule_class->print_special_offer_popup_on_shop();
		$template = ob_get_clean();
		wp_send_json( array( 'popup' => $template ) );
	}

	/**
	 * Reload the checkout page
	 *
	 * @return void
	 */
	public static function valid_rule_in_checkout() {
		check_ajax_referer( 'valid-rule-in-checkout', 'security' );
		WC_Cache_Helper::get_transient_version( 'shipping', true );

		WC()->cart->calculate_totals();

	}

	public static function update_cart_after_payment_method() {
		check_ajax_referer( 'update_cart_after_payment_method', 'security' );
		WC_Cache_Helper::get_transient_version( 'shipping', true );
		$payment_method = isset( $_REQUEST['paymentMethod'] ) ? sanitize_text_field( wp_unslash( $_REQUEST['paymentMethod'] ) ) : '';
		WC()->session->set( 'chosen_payment_method', $payment_method );
		WC()->cart->calculate_totals();
		$response = StoreApi::container()->get( SchemaController::class )->get( 'cart' );

		wp_send_json( $response->get_item_response(WC()->cart));
	}
}

YWDPD_Ajax::init();
