<?php
/**
 * WooCommerce hooks helper.
 *
 * @package HBFWC
 */
namespace HBFWC\WC;

defined( 'ABSPATH' ) || exit;

use function HBFWC\HBF_WC;
use HBFWC\Utils\Constants;
use Automattic\WooCommerce\StoreApi\Exceptions\RouteException;
use Automattic\WooCommerce\Utilities\FeaturesUtil;
use HBFWC_WC_Product_Accommodation;
use WP_REST_Request;

/**
 * Class HBFWC\WC\WC_Hooks.
 */
class WC_Hooks {
	/**
	 * Hooks in.
	 */
	public static function run() {
		add_filter( 'woocommerce_product_class', array( __CLASS__, 'accommodation_product_class' ), 9999, 2 );
		add_action( 'woocommerce_check_cart_items', array( __CLASS__, 'validate_cart' ), 1 );
		add_filter( 'wc_get_template', array( __CLASS__, 'get_template_file' ), 10, 2 );
		add_action( 'woocommerce_accommodation_add_to_cart', array( __CLASS__, 'accommodation_add_to_cart' ), 30 );
		add_action( 'woocommerce_after_add_to_cart_accommodation_button', array( __CLASS__, 'append_js_templates' ), 10 );
		add_filter( 'woocommerce_get_price_html', array( __CLASS__, 'get_price_html' ), 10, 2 );
		add_filter( 'woocommerce_cart_item_price', array( __CLASS__, 'register_cart_price' ), 1, 2 );
		add_filter( 'woocommerce_get_item_data', array( __CLASS__, 'display_custom_cart_item_data' ), 10, 2 );
		add_filter( 'woocommerce_order_item_display_meta_key', array( __CLASS__, 'meta_key_order_display' ), 10 );
		add_filter( 'woocommerce_order_item_display_meta_value', array( __CLASS__, 'meta_value_order_display' ), 10, 2 );
		add_action( 'woocommerce_product_query', array( __CLASS__, 'maybe_hide_accommodations' ) );
		add_action( 'template_redirect', [ __CLASS__, 'pro_info' ], 5 );
		add_action( 'woocommerce_cancel_unpaid_orders', array( __CLASS__, 'cancel_onhold_orders' ) );
		add_action( 'hbfwc_template_after_accommodation_loop', array( __CLASS__, 'make_global' ), 1 );
		add_action( 'hbfwc_template_after_availability_search_form', array( __CLASS__, 'make_global' ), 1 );
		// Stocks.
		add_action( 'woocommerce_reduce_order_stock', array( __CLASS__, 'reduce_room_availability' ) );
		add_action( 'woocommerce_restore_order_stock', array( __CLASS__, 'restore_room_availability' ) );

		// Rest.
		add_filter( 'woocommerce_store_api_add_to_cart_data', array( __CLASS__, 'rest_add_to_cart_data' ), 9999, 2 );
		add_filter( 'woocommerce_store_api_product_quantity_minimum', array( __CLASS__, 'rest_get_minimum_quantity' ), 9999, 3 );
		add_filter( 'woocommerce_store_api_product_quantity_maximum', array( __CLASS__, 'rest_get_maximum_quantity' ), 9999, 3 );
		add_filter( 'woocommerce_store_api_product_quantity_editable', array( __CLASS__, 'rest_is_quantity_editable' ), 9999, 3 );

		// Content.
		add_filter( 'woocommerce_product_tabs', array( __CLASS__, 'add_accommodation_tab' ) );
		add_filter( 'woocommerce_related_products', array( __CLASS__, 'woocommerce_related_products' ), 20, 3 );
		add_filter( 'wp_kses_allowed_html', 'hbfwc_kses_register_args', 10, 2 );

		/**
		 * @since 1.0.20
		 * Make sure manage stock settings is correct.
		 */
		add_action( 'woocommerce_admin_process_product_object', array( __CLASS__, 'setup_stock_management' ), 20 );

		/**
		 * @since 1.0.33
		 * Fix the meta display in new WC email template.
		 */
		add_action( 'woocommerce_order_item_meta_start', [ __CLASS__, 'obStartHelper'], 999, 4 );
		add_action( 'woocommerce_order_item_meta_end',   [ __CLASS__, 'redoItemMetaDisplay'], 5, 4 );
		add_filter( 'woocommerce_display_item_meta',     [ __CLASS__, 'beautify_hbfwc_email'], 10, 3 );

		add_filter( 'woocommerce_cart_item_quantity',    [ __CLASS__, 'disable_cart_quantity_change' ], 10, 3 );
		add_action( 'woocommerce_after_cart_item_quantity_update', [ __CLASS__, 'after_cart_item_quantity_update' ], 1, 4 );
	}

	/**
	 * Run after quantity of the cart item gets updated.
	 *
	 * @param string  $cart_item_key The cart item key.
	 * @param int     $quantity      New quantity.
	 * @param int     $old_quantity  Old quantity.
	 * @param WC_Cart $cart          The WooCommerce cart object
	 *
	 * @return void
	 * @throw  RouteException
	 */
	public static function after_cart_item_quantity_update( $cart_item_key, $quantity, $old_quantity, $cart ) {
		$cart_item  = $cart->get_cart_item( $cart_item_key );
		$added_more = absint( $old_quantity ) < absint( $quantity );
		
		if ( ! $added_more ) {
			return;
		}
		
		$product = $cart_item['data'] ?? false;
		
		// Oh dear other GREATEST WP/WC Addon developers,
		// Could you please add similar line like below?
		// So your awesome code doesn't breaks the whole WC flows.
		if ( ! $product instanceof \HBFWC_WC_Product_Accommodation ) return;
		
		$max_room = $product->get_allotment();
		
		if ( empty( $max_room ) ) return;

		$qty_in_cart   = hbfwc_get_quantity_data_from_cart_order( $product->get_id(), $cart_item['check_in'], $cart_item['check_out'] );
		$diff_quantity = absint( $quantity ) - absint( $old_quantity );
		
		$unpassed = [];
		foreach( $qty_in_cart as $bk_date => $date_quantity_left ) {
			if ( 0 > intval($date_quantity_left) ) {
				$unpassed[] = wp_date( hbfwc_get_date_format(), strtotime( $bk_date ) );
				continue;
			}
		}
				
		if ( ! empty( $unpassed ) ) {
			$cart->cart_contents[ $cart_item_key ]['quantity'] = $old_quantity;
			
			$print_dates = \hbfwc_natural_language_join( $unpassed, __( 'and', 'hotel-booking-for-woocommerce' ) );

			throw new RouteException(
				'woocommerce_quantity_error',
				sprintf(
				/* translators: Booking date */
					esc_html__( 'The room is not available on %s The last room is already in your cart.', 'hotel-booking-for-woocommerce' ),
					esc_html("**{$print_dates}**")
				),
				400
			);
		}
		
		return;
	}

	/**
	 * Ob start.
	 */
	public static function obStartHelper( $item_id, $item, $order, $plain_text ) {
		if ( did_action( 'woocommerce_email_header' ) > 0 && FeaturesUtil::feature_is_enabled( 'email_improvements' ) ) {
			$GLOBALS['wc_email_item_meta_buffer'] = ob_get_level();
			ob_start();
		}
	}

	/**
	 * Fix custom meta display in email.
	 */
	public static function redoItemMetaDisplay( $item_id, $item, $order, $plain_text ) {
		if ( 
			did_action( 'woocommerce_email_header' ) > 0 
			&& FeaturesUtil::feature_is_enabled( 'email_improvements' ) 
			) {
			if (
				isset( $GLOBALS['wc_email_item_meta_buffer'] ) &&
				ob_get_level() > $GLOBALS['wc_email_item_meta_buffer']
			) {
				ob_end_clean();
				$item_meta = wc_display_item_meta(
					$item,
					array(
						'before'       => '',
						'after'        => '',
						'separator'    => '<br>',
						'echo'         => false,
						'label_before' => '<span>',
						'label_after'  => ':</span> ',
					)
				);

				echo '<div class="email-order-item-meta">';
				// Using wp_kses instead of wp_kses_post to remove all block elements.
				echo wp_kses(
					$item_meta,
					array(
						'br'     => array(),
						'hr'     => array(),
						'strong' => array(),
						'span'   => array(
							'style' => true,
						),
						'a'      => array(
							'href'   => true,
							'target' => true,
							'rel'    => true,
							'title'  => true,
						),
					)
				);
				echo '</div>';

				unset( $GLOBALS['wc_email_item_meta_buffer'] );
			}
		}
	}

	public static function beautify_hbfwc_email( $html, $item, $args ) {
		if ( did_action( 'woocommerce_email_header' ) > 0 && FeaturesUtil::feature_is_enabled( 'email_improvements' ) ) {
			$strings = array();
			foreach ( $item->get_formatted_meta_data() as $meta_id => $meta ) {
				$value = $args['autop'] ? wp_kses_post( $meta->display_value ) : wp_kses_post( make_clickable( trim( $meta->display_value ) ) );
				if ( $meta->key === 'booking_line_addons' ) {
					$strings[] = '<span style="clear:both;display:block;margin-top:4px;margin-bottom:4px;height:2px;border-bottom:1px solid #e3e3e3">&nbsp;</span>' . $args['label_before'] . '<strong>' . wp_kses_post( $meta->display_key ) . '</strong>' . $args['label_after'] . '<br>' . $value;
				} else {
					$strings[] = $args['label_before'] . wp_kses_post( $meta->display_key ) . $args['label_after'] . $value;
				}
			}

			if ( $strings ) {
				$html = $args['before'] . implode( $args['separator'], $strings ) . $args['after'];
			}
		}
		return $html;
	}

	/**
	 * Send the right class name for our product type.
	 *
	 * @param string $class_name The class name.
	 * @param string $product_type The product type.
	 *
	 * @return string
	 */
	public static function accommodation_product_class( $class_name, $product_type ) {
		if ( 'accommodation' === $product_type ) {
			$class_name = 'HBFWC_WC_Product_Accommodation';
		}

		return $class_name;
	}

	/**
	 * @since 1.0.20
	 * Make sure the manage stock settings is correct.
	 */
	public static function setup_stock_management( $product ) {
		if ( $product->get_type() === 'accommodation' ) {
			$product->set_props([
				'manage_stock' => false,
				'stock_status' => 'instock',
			]);
		}
	}

	/**
	 * Get the template using the default WC method.
	 */
	public static function accommodation_add_to_cart() {
		global $product;

		if ( ! $product instanceof HBFWC_WC_Product_Accommodation ) {
			return;
		}

		// phpcs:disable WordPress.Security.NonceVerification.Recommended.
		$min_stay = (int) apply_filters( 'hbfwc_single_room_minimum_stay', $product->get_minimum_stay(), $product );
		$checkin  = isset( $_GET['checkin'] ) ? sanitize_text_field( wp_unslash( $_GET['checkin'] ) ) : self::get_default_checkin_date( $product, $min_stay );
		$checkout = isset( $_GET['checkout'] ) ? sanitize_text_field( wp_unslash( $_GET['checkout'] ) ) : self::get_default_checkout_date( $checkin, $min_stay );
		$qty      = isset( $_GET['qty'] ) ? absint( wp_unslash( $_GET['qty'] ) ) : 1;
		$ci_date  = new \DateTime( $checkin );
		$co_date  = new \DateTime( $checkout );
		$stay     = intval( $co_date->diff( $ci_date )->format( '%a' ) );
		// phpcs:enable

		wc_get_template(
			'single-product/add-to-cart/accommodation.php',
			array(
				'checkin'       => $checkin,
				'checkout'      => $checkout,
				'qty'           => $qty,
				'checkin_date'  => $ci_date,
				'checkout_date' => $co_date,
				'stay'          => $stay,
			)
		);
	}

	/**
	 * Resolve fallback check-in date when request does not include one.
	 *
	 * @param HBFWC_WC_Product_Accommodation $product Product object.
	 * @param int                            $min_stay Minimum stay.
	 *
	 * @return string
	 */
	private static function get_default_checkin_date( $product, $min_stay ) {
		$default_checkin = new \DateTime( wp_date( 'Y-m-d', hbfwc_default_checkin_date() ) );
		$checkin         = $product->first_valid_checkin_date( $default_checkin, $min_stay );

		if ( ! $checkin ) {
			$checkin = $default_checkin;
		}

		return $checkin->format( 'm/d/Y' );
	}

	/**
	 * Build fallback checkout date from check-in and minimum stay.
	 *
	 * @param string $checkin Check-in date.
	 * @param int    $min_stay Minimum stay.
	 *
	 * @return string
	 */
	private static function get_default_checkout_date( $checkin, $min_stay ) {
		$checkout_date = new \DateTime( $checkin );
		$checkout_date->modify( "+{$min_stay} days" );

		return $checkout_date->format( 'm/d/Y' );
	}

	/**
	 * Filter the template if only user not yet provide custom template.
	 *
	 * @param string $template The template file path.
	 * @param string $template_name The template name.
	 *
	 * @return string the template file
	 */
	public static function get_template_file( $template, $template_name ) {
		if ( false !== strpos( $template_name, 'accommodation.php' ) && ! file_exists( $template ) ) {
			$template = HBF_WC()->plugin_path() . '/templates/add-to-cart/accommodation.php';
		} elseif ( false !== strpos( $template_name, 'hbfwc' ) && ! file_exists( $template ) ) {
			$new_template_name = '/' . str_replace( 'hbfwc', 'templates', $template_name );
			$template          = HBF_WC()->plugin_path() . $new_template_name;
		}

		return apply_filters( 'hbfwc_get_template_file', $template, $template_name );
	}

	/**
	 * Modify price html output.
	 *
	 * @param string     $price The item price.
	 * @param WC_Product $product The product object.
	 *
	 * @return string
	 */
	public static function get_price_html( $price, $product ) {
		if ( $product instanceof HBFWC_WC_Product_Accommodation ) {
			$after = '<span class="hbfwc_per_night">' . __( '/night', 'hotel-booking-for-woocommerce' ) . '</span>';
			$price = $price . $after;
		}

		return $price;
	}

	/**
	 * Get the actual cart price.
	 *
	 * @param string $product_price The default item price.
	 * @param array  $values The cart values.
	 *
	 * @return string
	 */
	public static function register_cart_price( $product_price, $values ) {
		if ( empty( $values['check_in'] ) || empty( $values['check_out'] ) || empty( $values['rate_id'] ) ) {
			return $product_price;
		}

		$start_date = $values['check_in'];
		$end_date   = $values['check_out'];
		$rate_id    = $values['rate_id'];
		$product_id = $values['product_id'];

		$product = \wc_get_product( absint( $product_id ) );

		if ( ! $product instanceof HBFWC_WC_Product_Accommodation ) {
			return $product_price;
		}

		$total_cost = $product->get_cart_price( $start_date, $end_date, $rate_id );

		if ( isset( $values['addons'] ) ) {
			$addon_costs = 0;
			foreach( $values['addons'] as $addon ) {
				$addon_id  = (int) $addon['id'];
				$raw_price = $addon['price'];

				$addon_costs = bcadd( 
					$addon_costs, 
					bcmul( 
						wc_format_decimal($raw_price, Constants::MATH_SCALE), 
						$addon['qty'], 
						Constants::MATH_SCALE 
					),
					Constants::MATH_SCALE
				);
			}

			$addon_total_costs = apply_filters( 'hbfwc_register_addon_cart_price', $addon_costs, $values, $values['addons'] );
			$total_cost = bcadd( wc_format_decimal($total_cost, Constants::MATH_SCALE), wc_format_decimal($addon_total_costs, Constants::MATH_SCALE), Constants::MATH_SCALE );
		}

		return wc_price( $total_cost );
	}

	/**
	 * Display the meta on cart table.
	 *
	 * @param array $cart_data The cart data.
	 * @param array $cart_item The cart item.
	 *
	 * @return array
	 */
	public static function display_custom_cart_item_data( $cart_data, $cart_item ) {
		$product = $cart_item['data'] ?? false;
		
		if ( ! $product instanceof HBFWC_WC_Product_Accommodation ) {
			$cart_data;
		}
	
		if ( isset( $cart_item['rate_id'] ) ) {
			$rate = get_term_by( 'term_id', absint( $cart_item['rate_id'] ), 'rate_plan' );
			if ( $rate ) {
				$cart_data[] = array(
					'key'   => __( 'Rate', 'hotel-booking-for-woocommerce' ),
					'value' => $rate->name,
				);
			}
		}

		if ( isset( $cart_item['check_in'] ) && isset( $cart_item['check_out'] ) ) {
			$ci_date     = new \DateTime( wp_date( 'Y-m-d', $cart_item['check_in'] ) );
			$co_date     = new \DateTime( wp_date( 'Y-m-d', $cart_item['check_out'] ) );
			$stay        = absint( $co_date->diff( $ci_date )->format( '%a' ) );
			$stay_string = sprintf(
				/* translators: Number of nights */
				_n( '%d night', '%d nights', $stay, 'hotel-booking-for-woocommerce' ),
				$stay
			);

			$cart_data[] = array(
				'key'   => __( 'Date', 'hotel-booking-for-woocommerce' ),
				'value' => "{$stay_string} (" . wp_date( hbfwc_get_date_format(), $cart_item['check_in'] ) . ' &ndash; ' . wp_date( hbfwc_get_date_format(), $cart_item['check_out'] ) . ')',
			);
		}

		if ( isset( $cart_item['adults'] ) ) {
			$guest_val = [];
			$guest_val[] = sprintf(
					/* translators: Number of adults */
					__( 'Adults: %s', 'hotel-booking-for-woocommerce' ),
					$cart_item['adults']
				);

			if ( isset( $cart_item['children'] ) ) {
				$guest_val[] = sprintf(
					/* translators: Number of children */
					__( 'Children: %s', 'hotel-booking-for-woocommerce' ),
					$cart_item['children']
				);
			}

			$cart_data[] = array(
				'key'   => __( 'Guests', 'hotel-booking-for-woocommerce' ),
				'value' => implode( ', ', $guest_val ),
			);
		}

		if ( isset( $cart_item['children_ages'] ) ) {
			$ca_val = array();
			foreach ( $cart_item['children_ages'] as $i => $age ) {
				$ca_val[] = sprintf(
					/* translators: 1. Count of children 2. Age of children */
					__( 'Children #%1$d age: %2$s', 'hotel-booking-for-woocommerce' ),
					$i + 1,
					$age
				);
			}
			$cart_data[] = array(
				'key'   => __( 'Children ages', 'hotel-booking-for-woocommerce' ),
				'value' => implode( ' | ', $ca_val ),
			);
		}

		if ( isset( $cart_item['addons'] ) ) {
			$addon_lines = [];
			foreach( $cart_item['addons'] as $addon ) {
				$addon_id  = (int) $addon['id'];
				$raw_price = $addon['price'];
				$qty = intval( $addon['qty'] ) > 1 ? ' &times; ' . $addon['qty'] : '';

				$price_val = bcmul( wc_format_decimal( $raw_price, Constants::MATH_SCALE ), $addon['qty'], Constants::MATH_SCALE );
				$unit      = get_post_meta( $addon_id, 'unit', true );

				$addon['qty_and_unit'] = ! empty( $unit ) 
					? sprintf( '%d %s', intval( $addon['qty'] ), $unit ) 
					: $addon['qty'];
				
				$addon_qty = intval( $addon['qty'] ) > 1 ? wc_price( wc_format_decimal($raw_price, wc_get_price_decimals()) ) . ' &times; ' . $addon['qty_and_unit'] : wc_price( wc_format_decimal($raw_price, wc_get_price_decimals()) );

				$single_addon_line_data = array(
					'key'   => get_the_title( $addon_id ),
					'value' => $addon_qty . ' ' . wc_price( $price_val ),
				);

				$cart_data[] = apply_filters( 'hbfwc_single_addon_line_cart_item_data', $single_addon_line_data, $cart_item, $addon );
			}
		}

		return $cart_data;
	}

	/**
	 * Append js template helper.
	 */
	public static function append_js_templates() {
		global $product;

		if ( ! $product || ! $product instanceof HBFWC_WC_Product_Accommodation ) {
			return;
		}

		$minimum_stay = apply_filters( 'hbfwc_single_room_minimum_stay', $product->get_minimum_stay(), $product );
		print '<script type="text/template" id="hbfwc-alert-min-stay-template"><div id="hbfwc-alert-min-stay">' . sprintf(
			/* translators: Minimum of stay */
			esc_html__( '%d-night minimum', 'hotel-booking-for-woocommerce' ),
			absint( $minimum_stay )
		) . '</div></script>' . "\n";

		print '<script type="text/template" id="hbfwc-alert-only-checkout-template"><div id="hbfwc-alert-only-checkout">' . __( 'Check-out only', 'hotel-booking-for-woocommerce' ) . '</div></script>' . "\n";

		print '<script type="text/template" id="hbfwc-children-age-slider-template">
		<div class="hhbfwc-children-age-slider" id="hhbfwc-children-age-slider__{{number}}">
			<span class="hhbfwc-children-age-slider__label">' . sprintf(
				/* translators: Number of children */
			esc_html__( 'Children #%s age', 'hotel-booking-for-woocommerce' ),
			'{{number}}'
		) . '</span>
			<span class="hhbfwc-children-age-slider__input">
				<input type="range" id="children_age_{{number}}" name="children_age[]" value="6" min="0" max="' . esc_attr( hbfwc_get_max_children_age() ) . '" step="1" oninput="this.nextElementSibling.innerHTML = this.value" />
				<label for="children_age_{{number}}">6</label>
			</span>
		</div>
		</script>' . "\n";
	}

	/**
	 * Fix the meta value display.
	 *
	 * @param string $display_value The product meta display value.
	 * @param object $meta Product meta object.
	 *
	 * @return string
	 */
	public static function meta_value_order_display( $display_value, $meta ) {
		switch ( $meta->key ) {
			case 'booking_date':
				$values = json_decode( $display_value, true );

				if ( ! is_array( $values ) || empty( $values['check_in'] ) || empty( $values['check_out'] ) ) {
					return $display_value;
				}

				$ci_date     = new \DateTime( wp_date( 'Y-m-d', $values['check_in'] ) );
				$co_date     = new \DateTime( wp_date( 'Y-m-d', $values['check_out'] ) );
				$stays       = absint( $co_date->diff( $ci_date )->format( '%a' ) );
				$stay_string = sprintf(
					/* translators: Number of nights */
					_n( '%d night', '%d nights', $stays, 'hotel-booking-for-woocommerce' ),
					$stays
				);

				return "<strong>{$stay_string}</strong> (" . wp_date( hbfwc_get_date_format(), $values['check_in'] ) . ' &ndash; ' . wp_date( hbfwc_get_date_format(), $values['check_out'] ) . ')';
			
			case 'booking_guests':
				$values = json_decode( $display_value, true );

				if ( ! is_array( $values ) || empty( $values['adults'] ) ) {
					return $display_value;
				}

				$guest_val = [];
				$guest_val[] = sprintf(
						/* translators: Number of adults */
						__( 'Adults: %s', 'hotel-booking-for-woocommerce' ),
						$values['adults']
					);

					if ( isset( $values['children'] ) ) {
						$guest_val[] = sprintf(
							/* translators: Number of children */
							__( 'Children: %s', 'hotel-booking-for-woocommerce' ),
							$values['children']
						);
					}

				return implode( ', ', $guest_val );

			case 'booking_children_ages':
				$values = json_decode( $display_value, true );

				if ( ! is_array( $values ) ) {
					return $display_value;
				}

				$ages = array();
				foreach ( $values as $i => $age ) {
					$ages[] = sprintf(
						/* translators: 1. Count of children 2. Age of children */
						__( 'Children #%1$d age: %2$s', 'hotel-booking-for-woocommerce' ),
						$i + 1,
						$age
					);
				}

				return empty( $ages ) ? $display_value : implode( '<br>', $ages );

			case 'rate_id':
				$rate = get_term_by( 'term_id', absint( $display_value ), 'rate_plan' );
				return ( $rate ) ? $rate->name : $display_value;

			case 'booking_line_addons':
				$line_addons = json_decode( $display_value, true );
				
				if ( ! is_array( $line_addons ) || empty( $line_addons ) ) {
					return $display_value;
				}

				$email_improvements_enabled = FeaturesUtil::feature_is_enabled( 'email_improvements' );
				$for_email                  = did_action( 'woocommerce_email_header' ) > 0;
				$addon_order_values         = $display_value;

				if ( $for_email ) {
					$spans = [];
					$sp = 0;

					foreach( $line_addons as $dpv ) {
						$addon_id  = (int) $dpv['id'];
						$raw_price = $dpv['price'];
						$price_val = bcmul( wc_format_decimal( $raw_price, Constants::MATH_SCALE ), ( $dpv['qty'] ?? '1' ), Constants::MATH_SCALE );
						$unit      = get_post_meta( $addon_id, 'unit', true );
						
						$dpv['qty_and_unit'] = ! empty( $unit ) 
							? sprintf( '%d %s', intval( $dpv['qty'] ?? 1 ), $unit ) 
							: wc_price( wc_format_decimal($raw_price, wc_get_price_decimals()) );
						
						$addon_qty = intval( $dpv['qty'] ?? 1 ) > 1 
							? wc_price( wc_format_decimal($raw_price, wc_get_price_decimals()) ) . ' &times; ' . $dpv['qty_and_unit']
							: $dpv['qty_and_unit'];
						
						$add_style = ( $sp > 0 && $email_improvements_enabled ) 
							? 'padding-top:4px;margin-top:4px;border-top:1px solid #e3e3e3'
							: '';
						
						$addon_value  = '<span style="clear:both;display:block;font-weight:500;' . esc_attr( $add_style ) . '">' . esc_html( get_the_title( $addon_id ) ) . '</span>';
						$addon_value .= '<span style="float:left;font-size:12px;color:#999999">' . wp_kses_post( $addon_qty ) . '</span>';
						$addon_value .= '<span style="float:right;font-size:12px;color:#999999">' . wp_kses_post( wc_price( $price_val ) ) . '</span>';
						
						$spans[] = apply_filters( 'hbfwc_order_addon_value_email_html', $addon_value, $addon_id, $dpv, $email_improvements_enabled );
						
						unset( $dpv );
						++$sp;
					}

					if ( ! empty( $spans ) ) {
						if ( $email_improvements_enabled ) {
							$addon_order_values = '<br>' . implode( '<br>', $spans ) . '<span style="clear:both;display:block;margin-top:4px;height:2px;border-bottom:1px solid #e3e3e3">&nbsp;</span>';
						} else {
							$li = '</li><li style="clear:both">';

							$addon_order_values = '<ul style="clear:both">';
							$addon_order_values .= '<li style="clear:both">';
							$addon_order_values .= implode( $li, $spans );
							$addon_order_values .= '</li>';
							$addon_order_values .= '</ul>';
						}
					}

				} else {

					$list = '<ul class="hbfwc-line-item-addons">';
					foreach( $line_addons as $dpv ) {
						$addon_id  = (int) $dpv['id'];
						$raw_price = $dpv['price'];
						$unit      = get_post_meta( $addon_id, 'unit', true );
						
						$dpv['qty_and_unit'] = ! empty( $unit ) 
							? sprintf( '%d %s', intval( $dpv['qty'] ), $unit ) 
							: wc_price( wc_format_decimal($raw_price, wc_get_price_decimals()) );
						
						$addon_qty = intval( $dpv['qty'] ) > 1 ? wc_price( wc_format_decimal($raw_price, wc_get_price_decimals()) ) . ' &times; ' . $dpv['qty_and_unit'] : $dpv['qty_and_unit'];
						$price_val = bcmul( wc_format_decimal( $raw_price, Constants::MATH_SCALE ), $dpv['qty'], Constants::MATH_SCALE );
					
						$addon_value_html = '<li><span class="hbfwc-lia-name">' . get_the_title( $addon_id ) . '</span> <span class="hbfwc-lia-qty">' . $addon_qty . '</span> <span class="hbfwc-lia-price">' . wc_price( $price_val ) . '</span></li>';
						$list .= apply_filters( 'hbfwc_order_addon_value_html', $addon_value_html, $dpv );
					}
					$list .= '</ul>';

					$addon_order_values = $list;
				}

				return $addon_order_values;

			default:
				return apply_filters( 'hbfwc_booking_item_display_meta_value', $display_value, $meta );
		}
	}

	/**
	 * Fix the meta key display.
	 *
	 * @param string $display_key The meta key display name.
	 *
	 * @return string
	 */
	public static function meta_key_order_display( $display_key ) {
		switch ( $display_key ) {
			case 'booking_date':
				return __( 'Date', 'hotel-booking-for-woocommerce' );

			case 'booking_guests':
				return __( 'Guests', 'hotel-booking-for-woocommerce' );

			case 'booking_children_ages':
				return __( 'Children ages', 'hotel-booking-for-woocommerce' );

			case 'rate_id':
				return __( 'Rate', 'hotel-booking-for-woocommerce' );

			case 'booking_line_addons':
				return __( 'Add-ons', 'hotel-booking-for-woocommerce' );

			default:
				return apply_filters( 'hbfwc_booking_item_display_meta_key', $display_key );
		}
	}

	/**
	 * Validate cart items.
	 */
	public static function validate_cart() {
		$return = true;

		$cart = WC()->cart->get_cart();
		foreach ( $cart as $cart_item_key => $values ) {
			$product = $values['data'] ?? false;
			
			// (!) Don't touch any other product types.
			if ( ! $product instanceof HBFWC_WC_Product_Accommodation ) continue;

			if ( 
				isset( $values['check_in'] ) 
				&& wp_date( 'Y-m-d', intval( $values['check_in'] ) ) < wp_date( 'Y-m-d' ) 
			) {

				WC()->cart->remove_cart_item( $cart_item_key );
				wc_add_notice( __( 'An item that has expired has been taken out of your cart.', 'hotel-booking-for-woocommerce' ), 'error' );
				$return = false;
			}

		}

		if ( ! $return ) {
			WC()->cart->calculate_totals();
		}

		return $return;
	}

	/**
	 * Maybe hide accommodation products from archive.
	 *
	 * @param WP_Query $q The query object.
	 */
	public static function maybe_hide_accommodations( $q ) {
		if ( ! hbfwc_accommodation_is_hidden() ) {
			return;
		}

		$tax_query   = (array) $q->get( 'tax_query' );
		$tax_query[] = array(
			'taxonomy' => 'product_type',
			'field'    => 'slug',
			'terms'    => array( 'accommodation' ),
			'operator' => 'NOT IN',
		);

		$q->set( 'tax_query', $tax_query );
	}

	/**
	 * Cancel on-hold orders.
	 */
	public static function cancel_onhold_orders() {
		$held_duration          = get_option( 'woocommerce_hold_stock_minutes' );
		$cancel_unpaid_interval = apply_filters( 'woocommerce_cancel_unpaid_orders_interval_minutes', absint( $held_duration ) );

		$unpaid_orders = (array) \wc_get_orders(
			array(
				'orderby'      => 'date',
				'order'        => 'DESC',
				'limit'        => -1,
				'status'       => 'on-hold',
				'date_created' => '<' . ( time() - ( $cancel_unpaid_interval * 60 ) ),
			)
		);

		if ( count( $unpaid_orders ) > 0 ) {
			foreach ( $unpaid_orders as $order ) {
				$should_cancelled = false;

				foreach ( $order->get_items() as $item ) {
					if ( ! $item->is_type( 'line_item' ) ) {
						continue;
					}

					$product = $item->get_product();

					if ( ! $product ) {
						continue;
					}

					if ( $product->is_type( 'accommodation' ) ) {
						$should_cancelled = true;
						break;
					}
				}

				if ( $should_cancelled ) {
					$order->update_status( 'cancelled', __( 'The order was cancelled due to no payment from customer.', 'hotel-booking-for-woocommerce' ) );
				}
			}
		}
	}

	/**
	 * Reduce room availability on WC reduce stock action.
	 * Our accommodation product type basically not use the WC stock management due to different availability for each date.
	 *
	 * @param WC_Order $order The order object.
	 */
	public static function reduce_room_availability( $order ) {
		$changes = array();
		$blocked_dates = array();
		// Loop over all items.
		foreach ( $order->get_items() as $item ) {
			if ( ! $item->is_type( 'line_item' ) ) {
				continue;
			}

			// Only reduce stock once for each item.
			$product            = $item->get_product();
			$item_stock_reduced = $item->get_meta( '_reduced_stock', true );

			if ( $item_stock_reduced || ! $product || ! $product->is_type( 'accommodation' ) ) {
				continue;
			}

			$qty           = $item->get_quantity();
			$allotment     = $product->get_allotment();
			$booking_dates = $item->get_meta( 'booking_date' );

			// If no booking dates or user not set the value of allotment. Don't bother.
			if ( empty( $booking_dates ) || empty( $allotment ) ) {
				continue;
			}

			$booking_dates = json_decode( $booking_dates, true );
			$check_in      = new \DateTime( wp_date( 'Y-m-d', $booking_dates['check_in'] ) );
			$check_out     = new \DateTime( wp_date( 'Y-m-d', $booking_dates['check_out'] ) );

			$room_changes = array();

			while ( $check_in < $check_out ) {
				$current_day = $check_in->format( 'Y-m-d' );

				$existing_data = HBF_WC()->db->get_single_date_entry( $product->get_id(), $current_day );

				if ( $existing_data ) {
					$existing = $existing_data->qty;
					$roomleft = (int) $existing - (int) $qty;

					HBF_WC()->db->update_custom(
						array(
							'qty' => absint( $roomleft ),
						),
						array(
							'post_id'      => $product->get_id(),
							'booking_date' => $current_day,
						),
						array( '%d' ),
						array( '%d', '%s' )
					);
				} else {
					$existing = $allotment;
					$roomleft = (int) $existing - (int) $qty;

					HBF_WC()->db->add_new(
						array(
							'post_id'      => $product->get_id(),
							'qty'          => absint( $roomleft ),
							'booking_date' => $current_day,
						),
						array( '%d', '%d', '%s' ),
					);
				}

				$change         = array(
					'product' => $product,
					'date'    => $current_day,
					'from'    => $existing,
					'to'      => $roomleft,
				);
				$room_changes[] = $change;

				if ( 1 > intval( $roomleft ) ) {
					$blocked_dates[] = [
						'id'   => $product->get_id(),
						'date' => $current_day
					];
				}

				$check_in->modify( '+1 day' );
			}
			$changes[] = $room_changes;

			$item->add_meta_data( '_reduced_stock', $qty, true );
			$item->save();
		}

		do_action( 'hbfwc_reduced_stock_zero', $blocked_dates );

		\hbfwc_trigger_stock_change_notifications( $order, $changes );
	}

	/**
	 * Restore room availability on WC restore stock action.
	 *
	 * @param WC_Order $order The order object.
	 */
	public static function restore_room_availability( $order ) {
		$changes = array();
		$release_dates = array();
		// Loop over all items.
		foreach ( $order->get_items() as $item ) {
			if ( ! $item->is_type( 'line_item' ) ) {
				continue;
			}

			// Only increase stock once for each item.
			$product            = $item->get_product();
			$item_stock_reduced = $item->get_meta( '_reduced_stock', true );

			if ( ! $item_stock_reduced || ! $product || ! $product->is_type( 'accommodation' ) ) {
				continue;
			}

			$qty           = $item->get_quantity();
			$allotment     = $product->get_allotment();
			$booking_dates = $item->get_meta( 'booking_date' );

			// If no booking dates or user not set the value of allotment. Don't bother.
			if ( empty( $booking_dates ) || empty( $allotment ) ) {
				continue;
			}

			$booking_dates = json_decode( $booking_dates, true );
			$check_in      = new \DateTime( wp_date( 'Y-m-d', $booking_dates['check_in'] ) );
			$check_out     = new \DateTime( wp_date( 'Y-m-d', $booking_dates['check_out'] ) );

			$room_changes  = array();
			
			while ( $check_in < $check_out ) {
				$current_day = $check_in->format( 'Y-m-d' );

				// Allotment is the max value.
				$roomleft      = (int) $allotment;
				$previous_val  = (int) $allotment;
				$existing_data = HBF_WC()->db->get_single_date_entry( $product->get_id(), $current_day );

				if ( $existing_data ) {
					$previous_val = $existing_data->qty;
					$roomleft     = (int) $previous_val + (int) $qty;
					if ( $roomleft > $allotment ) {
						$roomleft = $allotment;
					}

					if ( $previous_val !== $roomleft ) {
						HBF_WC()->db->update_custom(
							array(
								'qty' => absint( $roomleft ),
							),
							array(
								'post_id'      => $product->get_id(),
								'booking_date' => $current_day,
							),
							array( '%d' ),
							array( '%d', '%s' )
						);
					}
				}

				$change         = array(
					'product' => $product->get_formatted_name(),
					'date'    => $current_day,
					'from'    => $previous_val,
					'to'      => $roomleft,
					'max'     => $allotment,
				);
				$room_changes[] = $change;

				if ( 1 > intval( $previous_val ) ) {
					$release_dates[] = [
						'id'   => $product->get_id(),
						'date' => $current_day
					];
				}

				$check_in->modify( '+1 day' );
			}
			$changes[] = $room_changes;

			$item->delete_meta_data( '_reduced_stock' );
			$item->save();
		}

		do_action( 'hbfwc_release_stock_zero', $release_dates );

		if ( $changes ) {
			$order_notes = array();

			foreach ( $changes as $change ) {
				$product_name = '';
				$inner_change = array();

				foreach ( $change as $date_change ) {
					$product_name = $date_change['product'];

					if ( intval( $date_change['from'] ) === intval( $date_change['to'] ) ) {
						$max = sprintf(
							/* translators: Maximum allotment */
							__( '[No changes] Maximum allotment: %d', 'hotel-booking-for-woocommerce' ),
							intval( $date_change['max'] )
						);

						$inner_change[] = '[' . $date_change['date'] . '] ' . $max;
					} else {
						$inner_change[] = '[' . $date_change['date'] . '] ' . $date_change['from'] . '&rarr;' . $date_change['to'];
					}
				}

				$order_notes[] = $product_name . ' ' . implode( ', ', $inner_change );
			}

			$order->add_order_note( __( 'Room value increased:', 'hotel-booking-for-woocommerce' ) . ' ' . implode( ', ', $order_notes ) );
		}
	}

	/**
	 * Make a global var.
	 */
	public static function make_global() {
		if ( ! isset( $GLOBALS['hbfwc-avail-form'] ) ) {
			$GLOBALS['hbfwc-avail-form'] = true;
		}
	}

	/**
	 * Add to cart via Rest API endpoint.
	 *
	 * @param array           $add_to_cart_data Data for item that will added to the cart.
	 * @param WP_REST_Request $request WordPress Rest Request.
	 *
	 * @throws RouteException Exception in case there are some errors with quantity count.
	 *
	 * @return array
	 */
	public static function rest_add_to_cart_data( $add_to_cart_data, WP_REST_Request $request ) {
		$request_id = $add_to_cart_data['id'] ?? $request['id'] ?? false;
		
		if ( empty( $request['hbfwc'] ) || ! $request_id ) {
			return $add_to_cart_data;
		}

		parse_str( wp_unslash( $request['hbfwc'] ), $data );

		$number_of_room = absint( $add_to_cart_data['quantity'] ?? $request['quantity'] ?? 1 );

		$data_to_adds = array(
			'rate_id'   => isset( $data['rate'] ) ? $data['rate'] : '0',
			'check_in'  => isset( $data['check-in'] ) ? $data['check-in'] : '0',
			'check_out' => isset( $data['check-out'] ) ? $data['check-out'] : '0',
			'adults'    => isset( $data['adults'] ) ? $data['adults'] : '0',
		);

		if ( isset( $data['children'] ) && absint( $data['children'] ) > 0 ) {
			$data_to_adds['children'] = $data['children'];
			
			if ( ! empty( $data['children_age'] ) && is_array( $data['children_age'] ) ) {
				$ages = array_filter(
					array_map(
						'absint',
						wp_unslash( $data['children_age'] )
					)
				);
				
				if ( ! empty( $ages ) ) {
					$data_to_adds['children_ages'] = $ages;
				}
			}
		}

		if ( isset( $data['addon'] ) ) {
			$addons      = array_keys( $data['addon'] );
			$addon_datas = [];
			foreach( $addons as $addon ) {
				$addon_datas[] = [
					'id'    => (int) $addon,
					'price' => \hbfwc_price_to_float( get_post_meta( (int) $addon, 'price', true ) ),
					'qty'   => ( isset( $data['addon_quantity'][$addon] ) ? $data['addon_quantity'][$addon] : 1 ),
				];
			}

			$addon_datas = apply_filters( 'hbfwc_rest_add_to_cart_addons', $addon_datas, $data['addon'] );
			$data_to_adds['addons'] = $addon_datas;
		}

		// Check the rate status. In case the rate status changing when order happen.
		$rate_status = hbfwc_rate_is_active( $request_id, $data_to_adds['rate_id'], $data_to_adds['check_in'], $data_to_adds['check_out'] );
		if ( is_wp_error( $rate_status ) ) {
			throw new RouteException( 'woocommerce_rate_inactive', $rate_status->get_error_message(), 400 ); // phpcs:ignore WordPress.Security.EscapeOutput.ExceptionNotEscaped
		}

		// Check availability.
		$is_available = \hbfwc_get_min_qty_available( $request_id, $data_to_adds['check_in'], $data_to_adds['check_out'] );
		if ( is_array( $is_available ) ) {
			$the_date   = wp_list_pluck( $is_available, 'date' );
			$print_date = \hbfwc_natural_language_join( $the_date, __( 'and', 'hotel-booking-for-woocommerce' ) );

			throw new RouteException(
				'woocommerce_quantity_error',
				sprintf(
					/* translators: Booking date */
					esc_html__( 'The room is not available on %s. Please refresh your browser to get the latest availability data.', 'hotel-booking-for-woocommerce' ),
					esc_html( $print_date )
				),
				400
			);
		}

		// Check cart.
		$quantity_in_cart = hbfwc_validate_quantity_in_cart( $request_id, $data_to_adds['check_in'], $data_to_adds['check_out'], $number_of_room );

		if ( is_wp_error( $quantity_in_cart ) ) {
			throw new RouteException( 'woocommerce_quantity_exceed', $quantity_in_cart->get_error_message(), 400 ); // phpcs:ignore WordPress.Security.EscapeOutput.ExceptionNotEscaped
		}

		$data_to_adds = apply_filters( 'hbfwc_store_api_add_to_cart_data', $data_to_adds, $add_to_cart_data, $request );
		
		foreach ( $data_to_adds as $data_key => $data_value ) {
			$add_to_cart_data['cart_item_data'][ $data_key ] = $data_value;
		}

		$cart_key_parts = array(
			'room_id'       => $request_id,
			'rate_id'       => $data_to_adds['rate_id'] ?? 0,
			'check_in'      => $data_to_adds['check_in'] ?? '',
			'check_out'     => $data_to_adds['check_out'] ?? '',
			'adults'        => $data_to_adds['adults'] ?? 0,
			'children'      => $data_to_adds['children'] ?? 0,
			'children_ages' => $data_to_adds['children_ages'] ?? [],
		);
		$cart_key_parts = apply_filters( 'hbfwc_store_api_cart_key_parts', $cart_key_parts, $data_to_adds );
		
		$add_to_cart_data['cart_item_data']['_hbfwc_cart_id'] = hbfwc_generate_booking_cart_key( $cart_key_parts );

		return $add_to_cart_data;
	}

	/**
	 * Get possible minimum quantity for WC Rest API.
	 *
	 * @param int        $value The default quantity.
	 * @param WC_Product $product The product object.
	 * @param array      $cart_item The cart item values.
	 */
	public static function rest_get_minimum_quantity( $value, $product, $cart_item ) {
		if ( ! $product->is_type( 'accommodation' ) || is_null( $cart_item ) ) {
			return $value;
		}

		return max( 1, absint( $cart_item['quantity'] ?? $value ) );
	}

	/**
	 * Get possible maximum quantity for WC Rest API.
	 *
	 * @param int        $value The default quantity.
	 * @param WC_Product $product The product object.
	 * @param array      $cart_item The cart item values.
	 */
	public static function rest_get_maximum_quantity( $value, $product, $cart_item ) {
		if ( ! $product->is_type( 'accommodation' ) ) {
			return $value;
		}

		$allotment = $product->get_allotment();

		// Allotment not set. Don't bother.
		if ( empty( $allotment ) ) {
			return $value;
		}

		if ( is_null( $cart_item ) ) {
			return absint( $allotment );
		}

		$max_qty_can_added = hbfwc_validate_quantity_in_cart( $product->get_id(), $cart_item['check_in'], $cart_item['check_out'], 1, true );

		if ( false !== $max_qty_can_added ) {
			return absint( $max_qty_can_added ) + absint( $cart_item['quantity'] ?? 0 );
		}
		
		return absint( $allotment );
	}

	/**
	 * Determine whether the cart-block quantity selector should be editable.
	 *
	 * @param bool       $editable Whether the quantity is editable.
	 * @param WC_Product $product The product object.
	 * @param array      $cart_item The cart item values.
	 * @return bool
	 */
	public static function rest_is_quantity_editable( $editable, $product, $cart_item ) {
		if ( ! $product->is_type( 'accommodation' ) || is_null( $cart_item ) ) {
			return $editable;
		}

		return false;
	}

	public static function remove_accommodation_info( $excerpt ) {
        // Remove injected block by comment markers
        $excerpt = preg_replace(
            '/<!-- hbfwc accommodation info -->.*?<!-- end hbfwc accommodation info -->/s',
            '',
            $excerpt
        );

        return $excerpt;
	}
	
	/**
	 * Move accommodation info into own tab.
	 * @since 1.0.42
	 */
	public static function add_accommodation_tab( $tabs ) {
		global $product;

		if ( ! $product || ! $product instanceof \HBFWC_WC_Product_Accommodation ) {
			return $tabs;
		}

		$tabs['hbfwc_accommodation'] = array(
			'title'    => self::get_accommodation_info_tab_title($product),
			'priority' => 25,
			'callback' => [ __CLASS__, 'add_accommodation_info' ],
		);

		return $tabs;
	}
	
	/**
	 * Accommodation info tab content.
	 * @since 1.0.42
	 */
	public static function add_accommodation_info() {
		global $product;

		if ( ! $product || ! $product->is_type( 'accommodation' ) ) {
			return;
		}

		if ( is_single() && in_the_loop() && is_main_query() ) {
			$amenities_groups = hbfwc_get_amenities_group();

			$html = '<h2>' . self::get_accommodation_info_tab_title($product) . '</h2>';

			if ( $product->get_basic_information() ) {
				$html .= '<div class="hbfwc-product-info__information">';
				$html .= wp_kses_post( $product->get_basic_information() );
				$html .= '</div>';
			}

			foreach ( $amenities_groups as $key => $group_name ) {
				$amenities = hbfwc_get_post_amenities_by_group( $product->get_id(), $key );

				if ( $amenities && ! is_wp_error( $amenities ) ) {
					$html .= '<div class="hbfwc__amenities hbfwc__amenities-' . esc_attr( $key ) . '">';
					$html .= '<h4>' . esc_html( $group_name ) . '</h4>';
					$html .= '<ul class="hbfwc__amenities-list">';

					foreach ( $amenities as $amenity ) {
						$icon_type = get_term_meta( $amenity->term_id, 'icon_type', true );

						$html .= '<li><span>' . ( 'svg' === $icon_type ? wp_kses( get_term_meta( $amenity->term_id, 'icon_svg', true ), hbfwc_get_svg_args() ) : '<i class="' . esc_attr( get_term_meta( $amenity->term_id, 'icon_class', true ) ) . '"></i>' ) . ' <span>' . esc_html( $amenity->name ) . '</span></span></li>' . "\n";
					}

					$html .= '</ul>';
					$html .= '</div>';

				}
			}

			$html_content = apply_filters( 'hbfwc_accommodation_info_tab_content', $html, $product );

			echo '<!-- hbfwc accommodation info -->' . wp_kses_post( $html_content ) . '<!-- end hbfwc accommodation info -->';
		}
	}
	
	/**
	 * Show related accommodation products.
	 */
	public static function woocommerce_related_products( $related_products, $product_id, $args ) {
		$product = wc_get_product($product_id);

		if ( ! $product->is_type( 'accommodation' ) ) {
			return $related_products;
		}

		$n_args = array(
			'type'    => 'accommodation',
			'status'  => 'publish',
			'limit'   => $args['limit'],
			'exclude' => array( $product_id ),
			'orderby' => 'rand',
			'return'  => 'ids',
		);
		$related_products = \wc_get_products( $n_args );

		return array_map( 'absint', $related_products );
	}

	public static function disable_cart_quantity_change( $product_quantity, $cart_item_key, $cart_item ) {
		$product_id = absint( $cart_item['product_id'] ?? 0 );
		if ( ! is_cart() || $product_id < 1 ) {
			return $product_quantity;
		}

		$product = wc_get_product( $product_id );

		if ( ! $product->is_type( 'accommodation' ) ) {
			return $product_quantity;
		}

		$room_count = absint( $cart_item['quantity'] ?? 0 );
		$room_label = sprintf(
			/* translators: Number of rooms */
			_n( '%s room', '%s rooms', $room_count, 'hotel-booking-for-woocommerce' ),
			number_format_i18n( $room_count )
		);

		return sprintf(
			'%s <input type="hidden" name="cart[%s][qty]" value="%s" />',
			esc_html( $room_label ),
			esc_attr( $cart_item_key ),
			esc_attr( $room_count )
		);
	}

	/**
	 * Accommodation info tab title.
	 */
	private static function get_accommodation_info_tab_title($product) {
		$def_title = __( 'Accommodation Info', 'hotel-booking-for-woocommerce' );
		return apply_filters( 'hbfwc_accommodation_info_tab_title', $def_title, $product );
	}

	public static function pro_info() {
		if ( class_exists('HBFWC\\Pro\\Utils\\Connection') ) {
			$con = new \HBFWC\Pro\Utils\Connection();
			if ( $con->is_expired() ) {
				\wc_clear_notices();
				\wc_add_notice( 'Your license is expired. Please <a href="https://uptonines.com/my-account/?ref=' . esc_attr( site_url('/') ) . '" style="font-weight:600">re-new your license</a> to continue using the "Hotel Booking for WooCommerce Pro Add-on".', 'error' );
			}
		}
	}
}
