<?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_Frontend_Premium' ) ) {
	/**
	 * Class YITH_Pre_Order_Frontend_Premium
	 */
	class YITH_Pre_Order_Frontend_Premium extends YITH_Pre_Order_Frontend {

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

			return self::$instance;
		}

		/**
		 * Construct
		 *
		 * @since  1.0
		 */
		public function __construct() {
			parent::__construct();

			if ( 'no' === get_option( 'yith_wcpo_enable_pre_order', 'yes' ) ) {
				return;
			}

			add_filter( 'woocommerce_get_stock_html', array( $this, 'print_pre_order_info_on_single_product_page' ), 99, 3 );
			add_filter( 'woocommerce_checkout_cart_item_quantity', array( $this, 'print_pre_order_info_on_checkout' ), 10, 2 );

			add_action( 'woocommerce_before_variations_form', array( $this, 'variable_product_label' ) );
			add_filter( 'woocommerce_loop_add_to_cart_link', array( $this, 'variable_product_label_on_loop' ) );

			add_filter( 'woocommerce_package_rates', array( $this, 'add_pre_order_free_shipping' ), 10, 2 );
			add_filter( 'woocommerce_product_is_in_stock', array( $this, 'avoid_selling_until_start_date' ), 10, 2 );
			add_filter( 'woocommerce_is_purchasable', array( $this, 'can_pre_order_current_user' ), 100, 2 );
			add_filter( 'woocommerce_cart_total', array( $this, 'format_cart_total' ) );
			add_filter( 'woocommerce_available_payment_gateways', array( $this, 'remove_unsupported_gateways_for_upon_release_payment' ), 100 );

			// Flatsome fix for showing availability date on Quick View.
			add_action( 'wc_quick_view_before_single_product', array( $this, 'flatsome_fix' ), 5 );

			$this->customize_buttons();
		}

		/**
		 * Enqueue frontend scripts
		 */
		public function enqueue_scripts() {
			parent::enqueue_scripts();

			if ( is_product() || is_shop() || is_cart() || is_checkout() || is_account_page() ) {
				wp_enqueue_style( 'ywpo-frontend', YITH_WCPO_ASSETS_URL . 'css/ywpo-frontend.css', array(), YITH_WCPO_VERSION );
			}

			if ( is_shop() || is_product_category() || is_product_tag() || is_product_taxonomy() || apply_filters( 'yith_ywpo_enqueue_script', false ) ) {
				wp_register_script( 'yith-wcpo-frontend-shop-loop', YITH_WCPO_ASSETS_JS_URL . yit_load_js_file( 'frontend-shop-loop.js' ), array( 'jquery' ), YITH_WCPO_VERSION, 'true' );
				wp_localize_script(
					'yith-wcpo-frontend-shop-loop',
					'infinite_scrolling',
					array(
						'events' => apply_filters( 'yith_ywpo_infinite_scrolling_events', 'yith_infs_added_elem scroll' ),
					)
				);
				wp_enqueue_script( 'yith-wcpo-frontend-shop-loop' );
			}
			if ( apply_filters( 'yith_wcpo_allow_other_page', is_cart() || is_checkout() ) ) {
				wp_register_script( 'yith-wcpo-frontend-cart', YITH_WCPO_ASSETS_JS_URL . yit_load_js_file( 'frontend-cart.js' ), array( 'jquery' ), YITH_WCPO_VERSION, 'true' );
				wp_enqueue_script( 'yith-wcpo-frontend-cart' );
			}
			if ( is_account_page() || is_checkout() ) {
				wp_register_script( 'yith-wcpo-frontend-my-account', YITH_WCPO_ASSETS_JS_URL . yit_load_js_file( 'frontend-my-account.js' ), array( 'jquery' ), YITH_WCPO_VERSION, 'true' );
				wp_enqueue_script( 'yith-wcpo-frontend-my-account' );
			}
		}

		/**
		 * Replaces the Add to cart button text.
		 *
		 * @param string     $text The original Add to cart text.
		 * @param WC_Product $product The WC_Product object.
		 *
		 * @return string
		 */
		public function pre_order_label( $text, $product ) {
			if ( YITH_Pre_Order_Utils::is_pre_order_active( $product ) ) {
				$label                = YITH_Pre_Order_Utils::get_pre_order_label( $product );
				$plugin_options_label = get_option( 'yith_wcpo_default_add_to_cart_label' );
				if (
					! empty( $label ) &&
					(
						metadata_exists( 'post', $product->get_id(), '_ywpo_override_labels' ) && 'yes' === YITH_Pre_Order_Utils::get_override_labels( $product ) ||
						! metadata_exists( 'post', $product->get_id(), '_ywpo_override_labels' )
					)
				) {
					return $label;
				} elseif ( ! empty( $plugin_options_label ) ) {
					return $plugin_options_label;
				} else {
					return __( 'Pre-order now', 'yith-pre-order-for-woocommerce' );
				}
			}
			return $text;
		}

		/**
		 * Print the pre-order info (start date or availability date) in the cart page.
		 *
		 * @param array $cart_item The cart item for showing the pre-order info.
		 */
		public function pre_order_product_cart_label( $cart_item ) {
			if ( apply_filters( 'ywpo_availability_in_cart', 'yes' !== get_option( 'ywpo_availability_in_cart', 'yes' ) ) ) {
				return;
			}

			$product = isset( $cart_item['data'] ) && $cart_item['data'] instanceof WC_Product ? $cart_item['data'] : false;

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

				if ( 'upfront' === $charge_type ) {
					$message = __( 'This pre-order will be charged upfront', 'yith-pre-order-for-woocommerce' );
				} else {
					$message = __( 'This pre-order will be charged upon release', 'yith-pre-order-for-woocommerce' );
				}
				$message          = apply_filters( 'yith_ywpo_pre_order_product_label', $message, null, $product->get_id(), $cart_item );
				$cart_label_class = apply_filters( 'ywpo_cart_label_class', 'ywpo-charge-type-info ywpo-' . $charge_type, $charge_type, $product->get_id(), $cart_item );
				$cart_info_class  = apply_filters( 'ywpo_cart_info_class', 'ywpo-cart-info', $charge_type, $product->get_id(), $cart_item );

				$charge_type_label = '<div class="' . $cart_label_class . '">' . $message . '</div>';
				$pre_order_info    = YITH_Pre_Order_Frontend()::print_pre_order_info( $product, 'pre_order_on_cart' );

				$cart_info = '<div class="' . $cart_info_class . '">' . $charge_type_label . $pre_order_info . '</div>';
				$cart_info = apply_filters( 'ywpo_pre_order_info_on_cart', $cart_info, $product->get_id(), $cart_item, $charge_type_label, $pre_order_info, $charge_type );

				echo wp_kses_post( $cart_info );
			}
		}

		/**
		 * Add the pre-order data that will be used for replacing the Add to cart text in the pre-order variations.
		 *
		 * @param array                $array            The variable product data array.
		 * @param WC_Product_Variable  $variable_product The WC_Product_Variable object.
		 * @param WC_Product_Variation $variation        The WC_Product_Variation object.
		 *
		 * @return array
		 */
		public function add_variable_pre_order_data( $array, $variable_product, $variation ) {
			if ( YITH_Pre_Order_Utils::is_pre_order_active( $variation->get_id() ) ) {
				$edit_product_page_label = YITH_Pre_Order_Utils::get_pre_order_label( $variation );
				$default_pre_order_label = get_option( 'yith_wcpo_default_add_to_cart_label', __( 'Pre-order now', 'yith-pre-order-for-woocommerce' ) );
				if ( ! empty( $edit_product_page_label ) && 'yes' === YITH_Pre_Order_Utils::get_override_labels( $variation ) ) {
					$pre_order_label = $edit_product_page_label;
				} elseif ( ! empty( $default_pre_order_label ) ) {
					$pre_order_label = $default_pre_order_label;
				} else {
					$pre_order_label = apply_filters( 'ywpo_pre_order_variation_default_label', __( 'Pre-order now!', 'yith-pre-order-for-woocommerce' ), $variation->get_id() );
				}

				$array['is_pre_order']    = 'yes';
				$array['pre_order_label'] = apply_filters( 'ywpo_variation_pre_order_label', $pre_order_label, $variation->get_id() );
			}

			return $array;
		}

		/**
		 * Print the pre-order info (start date or availability date) in the checkout page.
		 *
		 * @param string $qty_html  The original HTML part where the quantity info is printed (next to the product's name).
		 * @param array  $cart_item The cart item.
		 *
		 * @return string
		 */
		public function print_pre_order_info_on_checkout( $qty_html, $cart_item ) {
			if ( apply_filters( 'ywpo_availability_in_cart', 'yes' !== get_option( 'ywpo_availability_in_cart', 'yes' ) ) ) {
				return $qty_html;
			}
			$product = isset( $cart_item['data'] ) && $cart_item['data'] instanceof WC_Product ? $cart_item['data'] : false;
			if ( $product && YITH_Pre_Order_Utils::is_pre_order_active( $product ) ) {
				$pre_order_info = apply_filters( 'ywpo_pre_order_info_on_checkout', YITH_Pre_Order_Frontend()::print_pre_order_info( $product, 'pre_order_on_checkout' ), $product->get_id(), $cart_item );
				$qty_html      .= $pre_order_info;
			}
			return $qty_html;
		}


		/**
		 * Display custom label in single product pages when all variations from a variable product are pre-order.
		 */
		public function variable_product_label() {
			global $product;

			if (
				( 'yes' !== get_option( 'yith_wcpo_variable_product_label_enabled', 'no' ) ) ||
				( ! $product instanceof WC_Product ) ||
				( 'variable' !== $product->get_type() )
			) {
				return;
			}

			$children                   = $product->get_children();
			$all_children_are_pre_order = true;

			foreach ( $children as $child ) {
				if ( ! YITH_Pre_Order_Utils::is_pre_order_active( $child ) ) {
					$all_children_are_pre_order = false;
					break;
				}
			}

			if ( $all_children_are_pre_order ) {
				$label = apply_filters( 'yith_wcpo_variable_product_label_content_value', get_option( 'yith_wcpo_variable_product_label_content' ), $product );
				$color = apply_filters( 'yith_wcpo_variable_product_label_color_value', get_option( 'yith_wcpo_variable_product_label_color' ), $product );
				$style = apply_filters( 'yith_wcpo_variable_product_label_style', ! empty( $color ) ? 'color: ' . $color . ';' : '', $color, $product );

				$message = '<div class="ywpo_variable_product_label" style="' . $style . '">' . $label . '</div>';
				$message = apply_filters( 'yith_ywpo_variable_product_label', $message );
				echo wp_kses_post( $message );
			}
		}

		/**
		 * Display custom label in loop pages when all variations from a variable product are pre-order.
		 *
		 * @param string $text Original Add to cart link.
		 *
		 * @return string
		 */
		public function variable_product_label_on_loop( $text ) {
			$this->variable_product_label();

			return $text;
		}

		/**
		 * Add a Free Shipping method if the option 'ywpo_free_shipping_condition' is enabled and if there is at least
		 * one pre-order item in the cart.
		 *
		 * @param WC_Shipping_Rate[] $rates   Array of WC_Shipping_Rate objects.
		 * @param array              $package Package array.
		 *
		 * @return array
		 */
		public function add_pre_order_free_shipping( $rates, $package ) {
			if (
				apply_filters(
					'ywpo_free_shipping_condition',
					'yes' === get_option( 'ywpo_offer_free_shipping', 'no' ) && ywpo_count_pre_order_items_on_cart() > 0,
					$rates,
					$package
				)
			) {
				$shipping_method = new WC_Shipping_Free_Shipping();

				$args = apply_filters(
					'ywpo_free_shipping_rate_args',
					array(
						'id'      => 'ywpo-free_shipping',
						'label'   => __( 'Pre-order free shipping', 'yith-pre-order-for-woocommerce' ),
						'cost'    => 0,
						'taxes'   => false,
						'package' => $package,
					),
					$package
				);
				$shipping_method->add_rate( $args );
				$rates[ $args['id'] ] = $shipping_method->rates[ $args['id'] ];

				// Remove other shipping methods and leave only the pre-order free shipping method.
				if ( apply_filters( 'ywpo_remove_other_shipping_methods', true, $rates, $package, $shipping_method ) ) {
					foreach ( $rates as $rate_id => $rate ) {
						if ( 'ywpo-' !== substr( $rate->get_id(), 0, 5 ) ) {
							unset( $rates[ $rate_id ] );
						}
					}
				}
				$rates = apply_filters( 'ywpo_shipping_rates_after_adding_free_shipping', $rates, $package, $shipping_method );
			}

			return $rates;
		}

		/**
		 * Mark the product out of stock if the start date hasn't been reached yet.
		 *
		 * @param bool       $stock_status False for 'out of stock' stock status.
		 * @param WC_Product $product      The WC_Product object.
		 *
		 * @return bool
		 */
		public function avoid_selling_until_start_date( $stock_status, $product ) {
			if ( YITH_Pre_Order_Utils::is_pre_order_active( $product ) && ywpo_availability_date_not_ready( $product ) ) {
				return false;
			}

			return $stock_status;
		}

		/**
		 * Determine if the current user can add to the cart a pre-order product according to the settings.
		 *
		 * @param bool       $return  Whether the product is purchasable or not.
		 * @param WC_Product $product The WC_Product object.
		 *
		 * @return false
		 */
		public function can_pre_order_current_user( $return, $product ) {
			$pre_order_users = get_option( 'ywpo_pre_order_users', 'all' );
			if ( 'all' === $pre_order_users ) {
				return $return;
			}

			if (
				YITH_Pre_Order_Utils::is_pre_order_active( $product ) &&
				( 'registered' === $pre_order_users || 'roles' === $pre_order_users )
			) {
				if ( ! get_current_user_id() ) {
					return false;
				}
				if ( 'roles' === $pre_order_users ) {
					$user          = wp_get_current_user();
					$allowed_roles = get_option( 'ywpo_allowed_roles', array( 'customer' ) );

					if ( empty( $allowed_roles ) || ! is_array( $allowed_roles ) ) {
						return $return;
					}

					$intersect = array_intersect( $user->roles, $allowed_roles );

					if ( empty( $intersect ) ) {
						return false;
					}
				}
			}

			return $return;
		}

		/**
		 * Format the cart total for upon release pre-orders to add release date info next to the total price.
		 *
		 * @param string $total The text that includes the total.
		 *
		 * @return string
		 */
		public function format_cart_total( $total ) {
			if ( ywpo_check_pre_order_cart_errors() ) {
				return $total;
			}

			$cart_charge_type = ywpo_get_cart_charge_type();
			if ( 'upon_release' !== $cart_charge_type ) {
				return $total;
			}

			$cart_item = current( WC()->cart->get_cart_contents() );
			$product   = isset( $cart_item['data'] ) && $cart_item['data'] instanceof WC_Product ? $cart_item['data'] : false;
			if ( $product instanceof WC_Product && YITH_Pre_Order_Utils::is_pre_order_active( $product ) ) {
				$release_date = YITH_Pre_Order_Utils::calculate_availability_date_timestamp( $product );
				$total       .= '&nbsp;';
				if ( $release_date ) {
					$release_date_label = ywpo_print_date( $release_date );
					// translators: %s: date.
					$total .= sprintf( __( 'charged on: %s', 'yith-pre-order-for-woocommerce' ), $release_date_label );
				} else {
					$total .= __( 'charged at a future date', 'yith-pre-order-for-woocommerce' );
				}
			}

			return $total;
		}

		/**
		 * Remove the unsupported gateways when the current cart is for an upon release pre-order.
		 * In case the cart is for Pay Later, remove all gateways except Pay Later.
		 *
		 * @param array $available_gateways Available gateways.
		 *
		 * @return array
		 */
		public function remove_unsupported_gateways_for_upon_release_payment( $available_gateways ) {
			if ( defined( 'WOOCOMMERCE_CHECKOUT' ) && WOOCOMMERCE_CHECKOUT && ywpo_cart_contains_pre_order_product() ) {
				if ( ywpo_is_upon_release_cart() ) {
					// Remove any non-supported payment gateways.
					foreach ( $available_gateways as $gateway_id => $gateway ) {
						if ( ! method_exists( $gateway, 'supports' ) || false === $gateway->supports( 'yith_pre_orders' ) || 'no' === $gateway->enabled ) {
							unset( $available_gateways[ $gateway_id ] );
						}
					}
				} elseif ( ywpo_is_pay_later_cart() ) {
					// Remove all gateways except Pay Later.
					foreach ( $available_gateways as $gateway_id => $gateway ) {
						if ( 'ywpo_pay_later' !== $gateway_id ) {
							unset( $available_gateways[ $gateway_id ] );
						}
					}
				}
			}

			return apply_filters( 'ywpo_remove_unsupported_gateways', $available_gateways );
		}

		/**
		 * Flatsome fix for showing availability date in Quick View
		 *
		 * @since 1.3.2
		 */
		public function flatsome_fix() {
			?>
			<script type="text/javascript">
				jQuery('div.pre_order_single').each(function () {
					var unix_time = parseInt(jQuery(this).data('time'));
					var date = new Date(0);
					date.setUTCSeconds(unix_time);
					var time = date.toLocaleTimeString();
					time = time.slice(0, -3);
					jQuery(this).find('.availability_date').text(date.toLocaleDateString());
					jQuery(this).find('.availability_time').text(time);
				});
			</script>
			<?php
		}

		/**
		 * Hooks for customizing functions for the pre-order button (add to cart) and the place order button.
		 */
		public function customize_buttons() {
			if ( 'yes' === get_option( 'ywpo_customize_pre_order_button', 'no' ) ) {
				add_action( 'wp_footer', array( $this, 'customize_pre_order_button' ) );
			}
			if ( 'yes' === get_option( 'ywpo_custom_place_order_button_enabled', 'no' ) ) {
				if ( ! empty( get_option( 'ywpo_custom_place_order_button_label' ) ) ) {
					add_filter( 'woocommerce_order_button_text', array( $this, 'customize_place_order_button_text' ) );
				}
				if ( 'custom' === get_option( 'ywpo_custom_place_order_button_colors', 'default' ) ) {
					add_action( 'wp_footer', array( $this, 'customize_place_order_button_colors' ) );
				}
			}
		}

		/**
		 * Customize colors for the pre-order button (add to cart).
		 */
		public function customize_pre_order_button() {
			if ( is_checkout() ) {
				return;
			}
			$colors = get_option( 'ywpo_pre_order_button_colors' );
			if ( ! empty( $colors ) && is_array( $colors ) ) {
				?>
				<style>
					.products .product.yith-pre-order-product a.button.product_type_simple, .single-product .product.yith-pre-order-product .single_add_to_cart_button {
						background: <?php echo esc_html( apply_filters( 'ywpo_background_color', $colors['ywpo_background_color'] ) ); ?>;
						color: <?php echo esc_html( apply_filters( 'ywpo_text_color', $colors['ywpo_text_color'] ) ); ?>;
					<?php do_action( 'ywpo_add_to_cart_button_style', $colors ); ?>
					}

					.products .product.yith-pre-order-product a.button.product_type_simple:hover, .single-product .product.yith-pre-order-product .single_add_to_cart_button:hover {
						background: <?php echo esc_html( apply_filters( 'ywpo_background_hover_color', $colors['ywpo_background_hover_color'] ) ); ?>;
						color: <?php echo esc_html( apply_filters( 'ywpo_text_hover_color', $colors['ywpo_text_hover_color'] ) ); ?>;
					<?php do_action( 'ywpo_add_to_cart_button_hover_style', $colors ); ?>
					}
				</style>
				<?php
			}
		}

		/**
		 * Set the custom text for the place order button.
		 *
		 * @param string $text Custom text.
		 *
		 * @return string
		 */
		public function customize_place_order_button_text( $text ) {
			if ( ywpo_cart_contains_pre_order_product() ) {
				return get_option( 'ywpo_custom_place_order_button_label', __( 'Place pre-order now', 'yith-pre-order-for-woocommerce' ) );
			} else {
				return $text;
			}
		}

		/**
		 * Set the custom colors for the place order button.
		 */
		public function customize_place_order_button_colors() {
			if ( is_checkout() && ywpo_cart_contains_pre_order_product() ) {
				$colors = get_option( 'ywpo_place_order_colors' );
				if ( ! empty( $colors ) && is_array( $colors ) ) {
					?>
					<style>
						.woocommerce-checkout #place_order {
							background: <?php echo esc_html( apply_filters( 'ywpo_place_order_background_color', $colors['ywpo_place_order_background_color'] ) ); ?>;
							color: <?php echo esc_html( apply_filters( 'ywpo_place_order_text_color', $colors['ywpo_place_order_text_color'] ) ); ?>;
						<?php do_action( 'ywpo_place_order_button_style', $colors ); ?>
						}

						.woocommerce-checkout #place_order:hover {
							background: <?php echo esc_html( apply_filters( 'ywpo_place_order_background_hover_color', $colors['ywpo_place_order_background_hover_color'] ) ); ?>;
							color: <?php echo esc_html( apply_filters( 'ywpo_place_order_text_hover_color', $colors['ywpo_place_order_text_hover_color'] ) ); ?>;
						<?php do_action( 'ywpo_place_order_button_hover_style', $colors ); ?>
						}
					</style>
					<?php
				}
			}
		}

		/**
		 * Print the pre-order relative info. It could display the info about the starting date or the release date, depending on
		 * the product's settings.
		 *
		 * @param WC_Product $product The WC_Product object.
		 * @param string     $context The context the info will be displayed.
		 *
		 * @return string
		 */
		public static function print_pre_order_info( $product, $context ) {
			$start_date      = '';
			$start_date_mode = YITH_Pre_Order_Utils::get_start_mode( $product );

			if ( 'date' === $start_date_mode ) {
				$start_date = YITH_Pre_Order_Frontend()::print_start_date( $product, $context );
			}

			$availability_date = YITH_Pre_Order_Frontend()::print_availability_date( $product, $context );

			$pre_order_info = $availability_date;

			if ( $start_date && YITH_Pre_Order_Utils::get_start_date_timestamp( $product ) > time() ) {
				if ( apply_filters( 'ywpo_display_availability_date_along_with_start_date', false, $availability_date, $product->get_id(), $context ) ) {
					$pre_order_info = $start_date . $availability_date;
				} else {
					$pre_order_info = $start_date;
				}
			}

			return apply_filters( 'ywpo_pre_order_info', $pre_order_info, $product->get_id(), $context, $availability_date, $start_date );
		}

		/**
		 * Print the pre-order availability date.
		 *
		 * @param WC_Product $product The WC_Product object.
		 * @param string     $context The context the info will be displayed.
		 *
		 * @return string
		 */
		public static function print_availability_date( $product, $context ) {
			if ( ! metadata_exists( 'post', $product->get_id(), '_ywpo_availability_date_mode' ) && metadata_exists( 'post', $product->get_id(), '_ywpo_for_sale_date' ) ) {
				$availability_date_mode = get_post_meta( $product->get_id(), '_ywpo_for_sale_date', true ) > 0 ? 'date' : 'no_date';
			} else {
				$availability_date_mode = metadata_exists( 'post', $product->get_id(), '_ywpo_availability_date_mode' ) ? YITH_Pre_Order_Utils::get_availability_date_mode( $product ) : 'no_date';
			}

			$timestamp = YITH_Pre_Order_Utils::calculate_availability_date_timestamp( $product );

			$global_no_date_msg = get_option( 'yith_wcpo_no_date_label' );
			$no_date_msg        = '';
			if (
				metadata_exists( 'post', $product->get_id(), '_ywpo_override_labels' ) && 'yes' === YITH_Pre_Order_Utils::get_override_labels( $product ) ||
				! metadata_exists( 'post', $product->get_id(), '_ywpo_override_labels' )
			) {
				$no_date_msg = YITH_Pre_Order_Utils::get_pre_order_no_date_label( $product );
			}

			// Checks if there is a date set for the product.
			if ( ! empty( $timestamp ) && 'no_date' !== $availability_date_mode ) {
				$availability_label         = get_option( 'yith_wcpo_default_availability_date_label' );
				$availability_label_product = YITH_Pre_Order_Utils::get_pre_order_availability_date_label( $product );
				if (
					! empty( $availability_label_product ) &&
					(
						metadata_exists( 'post', $product->get_id(), '_ywpo_override_labels' ) && 'yes' === YITH_Pre_Order_Utils::get_override_labels( $product ) ||
						! metadata_exists( 'post', $product->get_id(), '_ywpo_override_labels' )
					)
				) {
					$availability_label = $availability_label_product;
				}
				$availability_label = apply_filters( 'yith_ywpo_date_time', $availability_label );

				if ( empty( $availability_label ) ) {
					$availability_label = apply_filters(
						'yith_ywpo_default_availability_date_label',
						// translators: %1$s: date, %2$s: time.
						sprintf( __( 'Available on: %1$s at %2$s', 'yith-pre-order-for-woocommerce' ), '{availability_date}', '{availability_time}' )
					);
				}

				if ( 'yes' === get_option( 'yith_wcpo_enable_automatic_date_formatting', 'yes' ) ) {
					$availability_label = str_replace( '{availability_date}', '<span class="availability_date"></span>', $availability_label );
					$availability_label = str_replace( '{availability_time}', '<span class="availability_time"></span>', $availability_label );
					$availability_label = apply_filters( 'yith_ywpo_availability_date_auto_label', nl2br( $availability_label ) );

					// Show the custom label set in the plugin options.
					return '<div class="ywpo_availability_date ' . $context . '" data-time="' . $timestamp . '">' . $availability_label . '</div>';
				} else {
					$date = apply_filters( 'yith_ywpo_availability_date_no_auto_date', ywpo_print_date( $timestamp ), $timestamp );
					$time = apply_filters( 'yith_ywpo_availability_date_no_auto_time', ywpo_print_time( $timestamp ), $timestamp );

					if ( apply_filters( 'ywpo_availability_date_show_offset_label', false, $timestamp, $date, $time ) ) {
						$time = apply_filters( 'yith_ywpo_no_auto_time', $time . ' (' . ywpo_get_timezone_offset_label() . ')', $time );
					}

					$availability_label = str_replace( '{availability_date}', '<span class="availability_date">' . $date . '</span>', $availability_label );
					$availability_label = str_replace( '{availability_time}', '<span class="availability_time">' . $time . '</span>', $availability_label );
					$availability_label = apply_filters( 'yith_ywpo_availability_date_no_auto_label', nl2br( $availability_label ), $product->get_id(), $timestamp, $date, $time );

					return '<div class="ywpo_availability_date ' . $context . '-no-auto-format">' . $availability_label . '</div>';
				}
			} elseif ( $no_date_msg ) {
				$no_date_msg_label = '<div class="ywpo_availability_date ' . $context . '">' . nl2br( $no_date_msg ) . '</div>';
				return apply_filters( 'yith_ywpo_no_date_label', $no_date_msg_label, $product->get_id() );
			} elseif ( ! empty( $global_no_date_msg ) ) {
				// If no date is set, it shows the No date label.
				$default_no_date_label = '<div class="ywpo_availability_date ' . $context . '">' . nl2br( $global_no_date_msg ) . '</div>';
				return apply_filters( 'yith_ywpo_no_date_label', $default_no_date_label, $product->get_id(), $context );
			}

			return '';
		}

		/**
		 * Print the pre-order start date (if any).
		 *
		 * @param WC_product $product The WC_Product object.
		 * @param string     $context The context the info will be displayed.
		 *
		 * @return string
		 */
		public static function print_start_date( $product, $context ) {
			$timestamp = YITH_Pre_Order_Utils::get_start_date_timestamp( $product );

			if ( ! $timestamp || $timestamp < time() ) {
				return '';
			}

			$text = YITH_Pre_Order_Utils::get_start_date_label( $product );

			if ( 'yes' === get_option( 'yith_wcpo_enable_automatic_date_formatting', 'yes' ) ) {
				$text = str_replace( '{availability_date}', '<span class="availability_date"></span>', $text );
				$text = str_replace( '{availability_time}', '<span class="availability_time"></span>', $text );
				$text = apply_filters( 'ywpo_start_date_auto_label', nl2br( $text ), $product->get_id() );

				return '<div class="ywpo_start_date ' . $context . '" data-time="' . $timestamp . '">' . $text . '</div>';
			} else {
				$date = apply_filters( 'yith_ywpo_start_date_no_auto_date', ywpo_print_date( $timestamp ), $timestamp );
				$time = apply_filters( 'yith_ywpo_start_date_no_auto_time', ywpo_print_time( $timestamp ), $timestamp );

				if ( apply_filters( 'ywpo_start_date_show_offset_label', false, $timestamp, $date, $time ) ) {
					$time = apply_filters( 'yith_ywpo_no_auto_time', $time . ' (' . ywpo_get_timezone_offset_label() . ')', $time );
				}

				$text = str_replace( '{availability_date}', '<span class="availability_date">' . $date . '</span>', $text );
				$text = str_replace( '{availability_time}', '<span class="availability_time">' . $time . '</span>', $text );
				$text = apply_filters( 'yith_ywpo_start_date_no_auto_label', nl2br( $text ), $timestamp, $date, $time );

				return '<div class="ywpo_start_date ' . $context . '-no-auto-format">' . $text . '</div>';
			}
		}
	}
}

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