<?php
/**
 * This file belongs to the YIT Framework.
 *
 * This source file is subject to the GNU GENERAL PUBLIC LICENSE (GPL 3.0)
 * that is bundled with this package in the file LICENSE.txt.
 * It is also available through the world-wide-web at this URL:
 * http://www.gnu.org/licenses/gpl-3.0.txt
 *
 * @package YITH\PreOrder\Includes
 * @author YITH <plugins@yithemes.com>
 */

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

if ( ! class_exists( 'YITH_Pre_Order_Premium' ) ) {
	/**
	 * Class YITH_Pre_Order_Premium
	 */
	class YITH_Pre_Order_Premium  extends YITH_Pre_Order {
		/**
		 * Main Stock manager Instance. This is kept for code snippets compatibility.
		 *
		 * @var YITH_Pre_Order_Stock_Manager
		 * @since 1.3.0
		 */
		public $stock_manager = null;

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

			return self::$instance;
		}

		/**
		 * Calls get_instance() for backward compatibility.
		 *
		 * @since 1.0.0
		 */
		public static function instance() {
			return self::get_instance();
		}

		/**
		 * Constructor
		 */
		protected function __construct() {
			parent::__construct();
			$this->manage_gateways();
			add_action( 'wp_loaded', array( $this, 'register_plugin_for_activation' ), 99 );
			add_action( 'wp_loaded', array( $this, 'register_plugin_for_updates' ), 99 );

			// Add custom meta query.
			add_filter( 'woocommerce_product_data_store_cpt_get_products_query', array( $this, 'products_custom_query_var' ), 10, 2 );
		}


		/**
		 * Register the email classes included in the plugin.
		 *
		 * @param array $email_classes Array of available email classes.
		 *
		 * @return array
		 */
		public function register_email_classes( $email_classes ) {
			require_once YITH_WCPO_PATH . 'includes/emails/class-yith-pre-order-email.php';

			$email_classes['YITH_Pre_Order_Cancelled_Email']             = include YITH_WCPO_PATH . 'includes/emails/class-yith-pre-order-cancelled-email.php';
			$email_classes['YITH_Pre_Order_Completed_Email']             = include YITH_WCPO_PATH . 'includes/emails/class-yith-pre-order-completed-email.php';
			$email_classes['YITH_Pre_Order_Confirmed_Email']             = include YITH_WCPO_PATH . 'includes/emails/class-yith-pre-order-confirmed-email.php';
			$email_classes['YITH_Pre_Order_New_Pre_Order_Email']         = include YITH_WCPO_PATH . 'includes/emails/class-yith-pre-order-new-pre-order-email.php';
			$email_classes['YITH_Pre_Order_Out_Of_Stock_Email']          = include YITH_WCPO_PATH . 'includes/emails/class-yith-pre-order-out-of-stock-email.php';
			$email_classes['YITH_Pre_Order_Payment_Reminder_Email']      = include YITH_WCPO_PATH . 'includes/emails/class-yith-pre-order-payment-reminder-email.php';
			$email_classes['YITH_Pre_Order_Release_Date_Changed_Email']  = include YITH_WCPO_PATH . 'includes/emails/class-yith-pre-order-release-date-changed-email.php';
			$email_classes['YITH_Pre_Order_Release_Date_Reminder_Email'] = include YITH_WCPO_PATH . 'includes/emails/class-yith-pre-order-release-date-reminder-email.php';

			return $email_classes;
		}

		/**
		 * Helper function to initialize gateways management at 'init' hook.
		 */
		public function manage_gateways() {
			$priority = apply_filters( 'ywpo_add_gateway_priority', 11 );
			add_filter( 'woocommerce_payment_gateways', array( $this, 'add_gateway' ), $priority );
		}

        /**
         * Is admin rest providers endpoint?
         * Check if is request /wp-json/wc-admin/settings/payments/providers
         *
         * @return boolean
         */
        protected function is_rest_providers_request() {
            global $wp;

            return wp_is_rest_endpoint() && $wp instanceof WP && 'wp-json/wc-admin/settings/payments/providers' === $wp->request;
        }

		/**
		 * Add the Pay Later gateway.
		 *
		 * @since 2.0.0
		 * @param array $gateways Gateways array.
		 * @return array
		 */
		public function add_gateway( $gateways ) {
            // Avoid override methods on admin sections as it is not required
            if ( $this->is_rest_providers_request() ) {
                return $gateways;
            }

			require_once YITH_WCPO_PATH . 'includes/gateways/class-yith-pre-order-pay-later.php';
			$gateways[] = 'YITH_Pre_Order_Pay_Later';
			if ( class_exists( 'WC_Stripe_Payment_Gateway' ) ) {
				include_once YITH_WCPO_PATH . 'includes/gateways/woocommerce-gateway-stripe/class-yith-pre-order-wc-stripe.php';
				include_once YITH_WCPO_PATH . 'includes/gateways/woocommerce-gateway-stripe/class-yith-pre-order-wc-stripe-upe.php';

				foreach ( $gateways as $key => $gateway ) {
					if ( class_exists( 'WC_Stripe_Feature_Flags' ) && WC_Stripe_Feature_Flags::is_upe_preview_enabled() && WC_Stripe_Feature_Flags::is_upe_checkout_enabled() ) {
						if ( 'WC_Stripe_UPE_Payment_Gateway' === $gateway || $gateway instanceof WC_Stripe_UPE_Payment_Gateway ) {
							$gateways[ $key ] = 'YITH_Pre_Order_WC_Stripe_UPE';
						}
					} else {
						if ( 'WC_Gateway_Stripe' === $gateway || $gateway instanceof WC_Gateway_Stripe ) {
							$gateways[ $key ] = 'YITH_Pre_Order_WC_Stripe';
						}
					}
				}
			}

			return $gateways;
		}

		/**
		 * Include files.
		 */
		public function init_includes() {
			parent::init_includes();
			require_once YITH_WCPO_PATH . 'includes/functions-pre-order-premium.php';

			if ( ywpo_is_admin() || defined( 'YITH_WCFM_PREMIUM' ) ) {
				require_once YITH_WCPO_PATH . 'includes/class-yith-pre-order-admin-premium.php';
				require_once YITH_WCPO_PATH . 'includes/class-yith-pre-order-edit-product-page-premium.php';
			}

			if ( ! is_admin() || ( defined( 'DOING_AJAX' ) && DOING_AJAX ) ) {
				require_once YITH_WCPO_PATH . 'includes/class-yith-pre-order-frontend-premium.php';
				require_once YITH_WCPO_PATH . 'includes/class-yith-pre-order-fee.php';
				require_once YITH_WCPO_PATH . 'includes/class-yith-pre-order-cart-messages.php';
			}

			if ( defined( 'ELEMENTOR_VERSION' ) ) {
				require_once YITH_WCPO_PATH . 'includes/elementor/class-yith-pre-order-elementor.php';
			}

			require_once YITH_WCPO_PATH . 'includes/class-yith-pre-order-cron.php';
			require_once YITH_WCPO_PATH . 'includes/class-yith-pre-order-stock-manager.php';
			require_once YITH_WCPO_PATH . 'includes/class-yith-pre-order-shortcodes.php';
			require_once YITH_WCPO_PATH . 'includes/class-yith-pre-order-orders-manager.php';
			require_once YITH_WCPO_PATH . 'includes/class-yith-pre-order-download-links-premium.php';

			// Compatibility classes.
			require_once YITH_WCPO_PATH . 'includes/compatibility/class-yith-pre-order-yith-stripe-compat.php';

			// Integrations.
			if ( defined( 'YWPC_PREMIUM' ) ) {
				require_once YITH_WCPO_PATH . 'includes/integrations/class-yith-product-countdown-integration.php';
			}

			if ( defined( 'YITH_WCDP_PREMIUM_INIT' ) ) {
				require_once YITH_WCPO_PATH . 'includes/integrations/class-yith-deposits-and-down-payments-integration.php';
			}
		}


		/**
		 * Instance the plugin classes.
		 */
		public function init() {
			if ( ywpo_is_admin() || defined( 'YITH_WCFM_PREMIUM' ) ) {
				$this->admin = YITH_Pre_Order_Admin_Premium();
				YITH_Pre_Order_Edit_Product_Page_Premium();
			}

			if ( ! is_admin() || ( defined( 'DOING_AJAX' ) && DOING_AJAX ) ) {
				$this->frontend  = YITH_Pre_Order_Frontend_Premium();
				$this->myaccount = YITH_Pre_Order_My_Account();
				YITH_Pre_Order_Fee();
				YITH_Pre_Order_Cart_Messages();
			}

			if ( defined( 'ELEMENTOR_VERSION' ) ) {
				YITH_Pre_Order_Elementor();
			}

			YITH_Pre_Order_Orders_Manager();
			YITH_Pre_Order_Cron();
			$this->download_links = YITH_Pre_Order_Download_Links_Premium();
			$this->stock_manager  = YITH_Pre_Order_Stock_Manager();
			YITH_Pre_Order_Shortcodes();
			YITH_Pre_Order_Orders_Manager();

			// Compatibility classes.
			YITH_Pre_Order_YITH_Stripe_Compat();

			// Integrations.
			if ( defined( 'YWPC_PREMIUM' ) ) {
				YITH_Product_Countdown_Integration();
			}

			if ( defined( 'YITH_WCDP_PREMIUM_INIT' ) ) {
				YITH_Deposits_And_Down_Payments_Integration();
			}
		}

		/**
		 * Register plugins for activation tab
		 */
		public function register_plugin_for_activation() {

			if ( ! class_exists( 'YIT_Plugin_Licence' ) ) {
				require_once YITH_WCPO_PATH . '/plugin-fw/licence/lib/yit-licence.php';
				require_once YITH_WCPO_PATH . '/plugin-fw/lib/yit-plugin-licence.php';
			}

			YIT_Plugin_Licence()->register( YITH_WCPO_INIT, YITH_WCPO_SECRETKEY, YITH_WCPO_SLUG );
		}

		/**
		 * Register plugin for update tab.
		 */
		public function register_plugin_for_updates() {
			if ( ! class_exists( 'YIT_Upgrade' ) ) {
				require_once YITH_WCPO_PATH . '/plugin-fw/lib/yit-upgrade.php';
			}
			YIT_Upgrade()->register( YITH_WCPO_SLUG, YITH_WCPO_INIT );
		}

		/**
		 * Add custom product meta query.
		 *
		 * @param array           $query      WP_Query args.
		 * @param WC_Object_Query $query_vars The WC_Object_Query object.
		 *
		 * @return array
		 */
		public function products_custom_query_var( $query, $query_vars ) {
			if ( ! empty( $query_vars['_ywpo_preorder'] ) ) {
				$query['meta_query'][] = array(
					'key'   => '_ywpo_preorder',
					'value' => esc_attr( $query_vars['_ywpo_preorder'] ),
				);
			}

			return $query;
		}

		/**
		 * Add custom order meta query.
		 *
		 * @param array           $query      WP_Query args.
		 * @param WC_Object_Query $query_vars The WC_Object_Query object.
		 *
		 * @return array
		 */
		public function orders_custom_query_var( $query, $query_vars ) {
			if ( ! empty( $query_vars['order_has_preorder'] ) ) {
				$query['meta_query'][] = array(
					'key'   => '_order_has_preorder',
					'value' => esc_attr( $query_vars['order_has_preorder'] ),
				);
			}

			if ( ! empty( $query_vars['_ywpo_status'] ) ) {
				$query['meta_query'][] = array(
					'key'   => '_ywpo_status',
					'value' => esc_attr( $query_vars['_ywpo_status'] ),
				);
			}

			if ( ! empty( $query_vars['_ywpo_pending_payment'] ) ) {
				$query['meta_query'][] = array(
					'key'   => '_ywpo_pending_payment',
					'value' => esc_attr( $query_vars['_ywpo_pending_payment'] ),
				);
			}

			return $query;
		}

		/**
		 * Check if a product can be displayed as pre-order in the shop.
		 *
		 * @since  2.0.0
		 *
		 * @param WC_Product|int $product The WC_Product object or product ID.
		 * @return bool
		 */
		public static function is_pre_order_active( $product ) {
			$return = false;

			// Use the WC product factory function to ensure that $product is a WC_Product object.
			$product = wc_get_product( $product );

			if ( $product instanceof WC_Product && ( 'simple' === $product->get_type() || 'variation' === $product->get_type() ) ) {
				// Backward compatibility.
				if ( apply_filters( 'ywpo_enable_backward_compatibility_mode', false, $product ) ) {
					return self::is_pre_order_product( $product );
				}

				if ( ywpo_automatic_pre_order_check( $product ) ) {
					$return = true;
				} elseif ( self::is_pre_order_product( $product ) && 'outofstock' !== $product->get_stock_status( 'edit' ) ) {
					$auto_pre_order_condition = ywpo_product_is_eligible_for_auto_pre_order( $product );
					$pre_order                = ywpo_get_pre_order( $product );

					if ( $auto_pre_order_condition && 'manual' === $pre_order->get_override_pre_order_mode() ) {
						$return = true;
					} elseif ( ! $auto_pre_order_condition && 'manual' === $pre_order->get_pre_order_mode() ) {
						$return = true;
					}
					if (
						'yes' === get_option( 'yith_wcpo_enable_pre_order_purchasable', 'yes' ) &&
						'date' === $pre_order->get_availability_date_mode() &&
						time() > $pre_order->get_for_sale_date_timestamp()
					) {
						ywpo_reset_pre_order( $product );
						$return = false;
					}
				}
			}

			return apply_filters( 'ywpo_is_pre_order_active', $return, $product );
		}
	}
}

/**
 * Unique access to instance of YITH_Pre_Order_Premium class
 *
 * @return YITH_Pre_Order_Premium
 */
function YITH_Pre_Order_Premium() { // phpcs:ignore WordPress.NamingConventions.ValidFunctionName.FunctionNameInvalid
	return YITH_Pre_Order_Premium::get_instance();
}
