<?php // phpcs:ignore WordPress.Files.FileName

if ( ! defined( 'YITH_COG_VERSION' ) ) {
	exit( 'Direct access forbidden.' );
}

if ( ! class_exists( 'YITH_COG_Ajax' ) ) {
	/**
	 * YITH_COG_Ajax
	 *
	 * @since 1.0.0
	 */
	class YITH_COG_Ajax {

		/**
		 * Single instance of the class
		 *
		 * @var YITH_COG_Ajax
		 * @since 1.0.0
		 */
		protected static $instance;

		/**
		 * Limit variable
		 *
		 * @var int
		 */
		public $limit;

		/**
		 * Offset variable
		 *
		 * @var int
		 */
		public $offset;

		/**
		 * Returns single instance of the class
		 *
		 * @since 1.0.0
		 */
		public static function get_instance() {
			if ( is_null( self::$instance ) ) {
				self::$instance = new self();
			}

			return self::$instance;
		}

		/**
		 * Constructor
		 */
		public function __construct() {

			// Ajax methods for Apply buttons.
			add_action( 'wp_ajax_yith_apply_cost_button', array( $this, 'apply_cost' ) );
			add_action( 'wp_ajax_nopriv_yith_apply_cost_button', array( $this, 'apply_cost' ) );
			add_action( 'wp_ajax_yith_apply_cost_overriding_button', array( $this, 'apply_cost_overriding' ) );
			add_action( 'wp_ajax_nopriv_yith_apply_cost_overriding_button', array( $this, 'apply_cost_overriding' ) );

			add_action( 'wp_ajax_yith_apply_cost_selected_order_button', array( $this, 'apply_cost_selected_order' ) );
			add_action( 'wp_ajax_nopriv_yith_apply_cost_selected_order_button', array( $this, 'apply_cost_selected_order' ) );

			// Ajax methods for Apply buttons.
			add_action( 'wp_ajax_yith_import_cost_button', array( $this, 'yith_import_cost' ) );
			add_action( 'wp_ajax_nopriv_yith_import_cost_button', array( $this, 'yith_import_cost' ) );

			// Ajax call to manage the currency screen option.
			add_action( 'wp_ajax_yith_cog_show_currency', array( $this, 'yith_cog_show_currency' ) );
			add_action( 'wp_ajax_nopriv_yith_cog_show_currency', array( $this, 'yith_cog_show_currency' ) );

		}

		/**
		 * Apply costs to orders that do not have costs set.
		 */
		public function apply_cost() {

			$this->offset = isset( $_POST['offset'] ) ? intval( $_POST['offset'] ) : 0; // phpcs:ignore
			$this->limit  = isset( $_POST['limit'] ) ? intval( $_POST['limit'] ) : 0; // phpcs:ignore

			if ( 0 === $this->limit ) {
				/**
				 * APPLY_FILTERS: yith_cog_limit_generate_apply_cost
				 *
				 * Filter the limit to apply the cost in bulk to the products, to avoid overloads.
				 *
				 * @param int the limit. Default: 50
				 *
				 * @return int
				 */
				$this->limit = apply_filters( 'yith_cog_limit_generate_apply_cost', 50 );
			}

			$orders = wc_get_orders(
				array(
					'post_type'      => 'shop_order',
					'status'         => apply_filters( 'yith_cog_apply_cost_order_statuses', array( 'wc-processing', 'wc-completed', 'wc-on-hold' ) ),
					'limit' => $this->limit,
					'offset' => $this->offset,
				)
			);

			if ( $orders ) {
				foreach ( $orders as $order ) {
					YITH_COG_Orders::get_instance()->set_order_cost_meta( $order->get_id() );
				}
			}

			$number_of_orders = count( $orders );

			$new_offset = $this->offset + $this->limit;

			if ( $number_of_orders < $this->limit ) {
				$data = array(
					'limit'  => "$this->limit",
					'offset' => "$new_offset",
					'loop'   => '0',
				);
				wp_send_json( $data );
			} else {
				$data = array(
					'limit'  => "$this->limit",
					'offset' => "$new_offset",
					'loop'   => '1',
				);

				wp_send_json( $data );
			}
		}


		/**
		 * Apply costs to all orders, overriding previous costs.
		 */
		public function apply_cost_overriding() {

			$this->offset = isset( $_POST['offset'] ) ? intval( $_POST['offset'] ) : 0; // phpcs:ignore
			$this->limit  = isset( $_POST['limit'] ) ? intval( $_POST['limit'] ) : 0; // phpcs:ignore

			if ( 0 === $this->limit ) {
				/**
				 * APPLY_FILTERS: yith_cog_limit_generate_apply_cost
				 *
				 * Filter the limit to apply the cost in bulk to the products, to avoid overloads.
				 *
				 * @param int the limit. Default: 50
				 *
				 * @return int
				 */
				$this->limit = apply_filters( 'yith_cog_limit_generate_apply_cost', 50 );
			}

			$orders = wc_get_orders(
				array(
					'post_type'      => 'shop_order',
					'status'         => apply_filters( 'yith_cog_apply_cost_order_statuses', array( 'wc-processing', 'wc-completed', 'wc-on-hold' ) ),
					'posts_per_page' => '-1',
				)
			);

			$number_of_orders = count( $orders );

			if ( $this->limit > $number_of_orders ) {
				$counter = $number_of_orders;
			} else {
				$counter = $this->offset + $this->limit;
			}

			for ( $i = $this->offset; $i < $counter; $i++ ) {

				$order    = $orders[ $i ];
				$order_id = $order->get_id();

				YITH_COG_Orders::get_instance()->set_order_cost_meta_overriding( $order_id );
			}

			$new_offset = $this->offset + $this->limit;

			if ( ( $number_of_orders - $new_offset ) < $this->limit ) {
				$this->limit = $number_of_orders - $new_offset;
			}

			if ( $new_offset < $number_of_orders ) {

				$data = array(
					'limit'  => "$this->limit",
					'offset' => "$new_offset",
					'loop'   => '1',
				);

				wp_send_json( $data );
			} else {
				$data = array(
					'limit'  => "$this->limit",
					'offset' => "$new_offset",
					'loop'   => '0',
				);
				wp_send_json( $data );
			}
		}

		/**
		 * Apply cost on selected order
		 */
		public function apply_cost_selected_order() {

			$order_id = sanitize_text_field( wp_unslash( $_POST['order_id'] ) ); // phpcs:ignore

			if ( isset( $order_id ) ) {
				YITH_COG_Orders::get_instance()->set_order_cost_meta_overriding( $order_id );
			}
			$data = array(
				'limit'  => "$this->limit",
				'offset' => "$new_offset",
				'loop'   => '0',
			);
			wp_send_json( $data );
		}

		/**
		 * Apply costs to orders that do not have costs set.
		 */
		public function yith_import_cost() {

			global $wpdb;

			$this->offset = isset( $_POST['offset'] ) ? intval( $_POST['offset'] ) : 0; // phpcs:ignore
			$this->limit  = isset( $_POST['limit'] ) ? intval( $_POST['limit'] ) : 0; // phpcs:ignore

			if ( 0 === $this->limit ) {
				/**
				 * APPLY_FILTERS: yith_cog_limit_generate_import_cost
				 *
				 * Filter the limit to import the cost of goods from the WC plugin, to avoid overloads.
				 *
				 * @param int the limit. Default: 100
				 *
				 * @return int
				 */
				$this->limit = apply_filters( 'yith_cog_limit_generate_import_cost', 100 );
			}

			$query_from = "FROM {$wpdb->posts} as posts
			INNER JOIN {$wpdb->postmeta} AS postmeta ON posts.ID = postmeta.post_id
			WHERE 1=1
			AND posts.post_type IN ( 'product' )
			AND posts.post_status = 'publish' ";

			$products_array = $wpdb->get_results( "SELECT DISTINCT posts.ID as id {$query_from} " ); // phpcs:ignore

			$total_products_number = $wpdb->get_var( "SELECT COUNT( DISTINCT posts.ID ) {$query_from};" ); // phpcs:ignore

			if ( $this->limit > $total_products_number ) {
				$counter = $total_products_number;
			} else {
				$counter = $this->offset + $this->limit;
			}

			foreach ( $products_array as $products ) {

				$product    = wc_get_product( $products->id );
				$product_id = $product->get_id();

				for ( $i = $this->offset; $i < $counter; $i++ ) {

					if ( $product->is_type( 'variable' ) ) {

						foreach ( $product->get_children() as $child_id ) {

							$variation_cost     = get_post_meta( $child_id, 'yith_cog_cost', true );
							$woo_variation_cost = get_post_meta( $child_id, '_wc_cog_cost', true );

							if ( empty( $variation_cost ) && ! empty( $woo_variation_cost ) ) {
								update_post_meta( $child_id, 'yith_cog_cost', $woo_variation_cost );
							}
						}
						$cost               = get_post_meta( $product_id, 'yith_cog_cost', true );
						$cost_variable      = get_post_meta( $product_id, 'yith_cog_cost_variable', true );
						$min_variation_cost = get_post_meta( $product_id, 'yith_cog_min_variation_cost', true );
						$max_variation_cost = get_post_meta( $product_id, 'yith_cog_max_variation_cost', true );
					} else {
						$cost = get_post_meta( $product_id, 'yith_cog_cost', true );
					}

					$woo_cost               = get_post_meta( $product_id, '_wc_cog_cost', true );
					$woo_cost_variable      = get_post_meta( $product_id, '_wc_cog_cost_variable', true );
					$woo_min_variation_cost = get_post_meta( $product_id, '_wc_cog_min_variation_cost', true );
					$woo_max_variation_cost = get_post_meta( $product_id, '_wc_cog_max_variation_cost', true );

					if ( empty( $cost ) && ! empty( $woo_cost ) ) {
						update_post_meta( $product_id, 'yith_cog_cost', $woo_cost );
					}
					if ( empty( $cost_variable ) && ! empty( $woo_cost_variable ) ) {
						update_post_meta( $product_id, 'yith_cog_cost_variable', $woo_cost_variable );
					}
					if ( empty( $min_variation_cost ) && ! empty( $woo_min_variation_cost ) ) {
						update_post_meta( $product_id, 'yith_cog_min_variation_cost', $woo_min_variation_cost );
					}
					if ( empty( $max_variation_cost ) && ! empty( $woo_max_variation_cost ) ) {
						update_post_meta( $product_id, 'yith_cog_max_variation_cost', $woo_max_variation_cost );
					}
				}
			}

			$new_offset = $this->offset + $this->limit;

			if ( ( $total_products_number - $new_offset ) < $this->limit ) {
				$this->limit = $total_products_number - $new_offset;
			}

			if ( $new_offset < $total_products_number ) {
				$data = array(
					'limit'  => "$this->limit",
					'offset' => "$new_offset",
					'loop'   => '1',
				);

				wp_send_json( $data );
			} else {
				$data = array(
					'limit'  => "$this->limit",
					'offset' => "$new_offset",
					'loop'   => '0',
				);
				wp_send_json( $data );
			}
		}

		/**
		 * Apply cost on selected order
		 */
		public function yith_cog_show_currency() {

			$input_value = 'true' === $_POST['input_value'] ? true : false; //phpcs:ignore
			$sucess      = false;

			if ( $input_value ) {

				update_option( 'yith_cog_currency_report', 'yes' );
				$sucess = true;
			} else {

				update_option( 'yith_cog_currency_report', 'no' );
			}
			wp_send_json( $sucess );
		}

	}
}
