<?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\Integrations
 * @author YITH <plugins@yithemes.com>
 */

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

if ( ! class_exists( 'YITH_Deposits_And_Down_Payments_Integration' ) ) {
	/**
	 * Class YITH_Deposits_And_Down_Payments_Integration
	 * This class manages the operations concerning the pre-order fees.
	 */
	class YITH_Deposits_And_Down_Payments_Integration {

		/**
		 * Main Instance
		 *
		 * @var YITH_Deposits_And_Down_Payments_Integration
		 */
		protected static $instance;

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

			return self::$instance;
		}

		/**
		 * Construct
		 */
		public function __construct() {
			add_action( 'yith_wcdp_before_suborders_create', array( $this, 'remove_pre_order_meta_from_parent_order' ) );
			add_filter( 'yith_wcdp_add_single_deposit_button', array( $this, 'remove_deposit_button_for_upon_release_products' ), 10, 2 );
			add_filter( 'yith_wcdp_show_add_to_cart_in_loop', array( $this, 'remove_deposit_button_in_loop_for_upon_release_products' ) );
			add_filter( 'ywpo_order_is_paid', array( $this, 'mark_balance_as_paid_for_completing_a_pre_order' ), 10, 2 );
			add_filter( 'woocommerce_payment_complete_order_status', array( $this, 'suborder_to_pending_after_pre_order_complete' ), 10, 3 );

			// Set "Pre-ordered" status to balance order.
			add_filter( 'yith_wcdp_suborder_status', array( YITH_Pre_Order_Orders_Manager(), 'update_payment_complete_order_status' ), 10, 2 );
		}

		/**
		 * Remove the pre-order order meta and order item meta from the parent order.
		 * Only the balance order will have the pre-order meta.
		 *
		 * @param int $order_id Parent order id.
		 */
		public function remove_pre_order_meta_from_parent_order( $order_id ) {
			$parent_order = wc_get_order( $order_id );
			if ( ! YITH_WCDP_Suborders()->has_deposits( $parent_order ) ) {
				return false;
			}

			if ( $parent_order->meta_exists( '_order_has_preorder' ) ) {
				$items = $parent_order->get_meta( '_ywpo_pre_order_items' );
				if ( ! empty( $items ) && is_array( $items ) ) {
					foreach ( $items as $item_id => $item_status ) {
						$item = $parent_order->get_item( $item_id );
						$item->delete_meta_data( '_ywpo_item_preorder' );
						$item->delete_meta_data( '_ywpo_item_status' );
						$item->delete_meta_data( '_ywpo_item_for_sale_date' );
						$item->save();
					}
				}
				$parent_order->delete_meta_data( '_order_has_preorder' );
				$parent_order->delete_meta_data( '_ywpo_status' );
				$parent_order->delete_meta_data( '_ywpo_pre_order_items' );
				$parent_order->delete_meta_data( '_ywpo_order_charge_type' );
				$parent_order->delete_meta_data( '_ywpo_pending_payment' );
				$parent_order->save();
			}
		}

		/**
		 * Remove the deposit button on the single product page for upon release products.
		 *
		 * @param bool       $bool    Whether to display or hide the deposit button.
		 * @param WC_Product $product The WC_Product object.
		 */
		public function remove_deposit_button_for_upon_release_products( $bool, $product ) {
			if ( ! $product instanceof WC_Product ) {
				return $bool;
			}

			if ( ! YITH_Pre_Order_Utils::is_pre_order_active( $product ) ) {
				return $bool;
			}

			$charge_type = get_option( 'ywpo_charge_type', 'upfront' );
			if ( 'yes' === YITH_Pre_Order_Utils::get_override_charge_type( $product ) ) {
				$charge_type = ! empty( YITH_Pre_Order_Utils::get_charge_type( $product ) ) ? YITH_Pre_Order_Utils::get_charge_type( $product ) : $charge_type;
			}

			if ( 'upon_release' === $charge_type || 'pay_later' === $charge_type ) {
				$bool = false;
			}

			return $bool;
		}

		/**
		 * Remove the deposit button on loop pages for upon release products.
		 *
		 * @param bool $bool Whether to display or hide the deposit button.
		 */
		public function remove_deposit_button_in_loop_for_upon_release_products( $bool ) {
			global $product;

			return $this->remove_deposit_button_for_upon_release_products( $bool, $product );
		}

		/**
		 * When completing a pre-order for a balance order, mark the order as paid just to complete the pre-order process.
		 *
		 * @param bool     $bool  Whether the pre-order is paid or not. If it's a balance order for completing a pre-order, the value returned will be true.
		 * @param WC_Order $order The WC_Order object.
		 */
		public function mark_balance_as_paid_for_completing_a_pre_order( $bool, $order ) {
			if ( self::is_a_pre_order_completed_non_paid_balance( $order ) ) {
				$bool = true;
			}
			return $bool;
		}

		/**
		 * When a balance pre-order is completed, modify the valid payment complete order status ('processing' by default),
		 * so it cannot match the current status ('pending').
		 * This avoids setting a paid date, so the Pay for the Item button is displayed on the pre-order completed email.
		 *
		 * @param string   $status   List of valid payment complete order statuses.
		 * @param int      $order_id The order ID.
		 * @param WC_Order $order    The WC_Order object.
		 */
		public function suborder_to_pending_after_pre_order_complete( $status, $order_id, $order ) {
			if ( self::is_a_pre_order_completed_non_paid_balance( $order ) ) {
				// The status cannot match the current order status to avoid giving a paid date to the order.
				$status = '-';
			}
			return $status;
		}

		/**
		 * Return true if the order is a non paid yet suborder but the pre-order status is completed.
		 *
		 * @param WC_Order $order The WC_Order object.
		 *
		 * @return bool
		 */
		public static function is_a_pre_order_completed_non_paid_balance( $order ) {
			$bool = false;
			if (
				YITH_WCDP_Suborders()->is_suborder( $order ) &&
				ywpo_order_has_pre_order( $order ) &&
				ywpo_is_completed_pre_order( $order ) &&
				( 'processing' !== $order->get_status() && 'completed' !== $order->get_status() ) &&
				empty( $order->get_date_paid() )
			) {
				$bool = true;
			}
			return $bool;
		}
	}
}

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