<?php
/**
 * Shortcode loop.
 *
 * @package HBFWC\Shortcode
 */

defined( 'ABSPATH' ) || exit;

/**
 * Shortcode loop class.
 */
class HBFWC_Shortcode_Loop {
	/**
	 * Accommodation ids
	 *
	 * @since 1.0.0
	 * @var   array
	 */
	protected $accommodation_ids = array();

	/**
	 * Has posts
	 *
	 * @since 1.0.0
	 * @var   bool
	 */
	public $has_posts;

	/**
	 * Hide unavailable items.
	 *
	 * @since 1.0.32
	 * @var bool
	 */
	public $should_hide_unavailable;

	/**
	 * Class constructor.
	 *
	 * @param array $args The filter args.
	 */
	public function __construct( $args = array() ) {
		$this->should_hide_unavailable = \hbfwc_hide_unavailable_items_in_search();
		$this->accommodation_ids       = $this->filtered_by_availability( $args );
		$this->has_posts               = ! empty( $this->accommodation_ids );
	}

	/**
	 * Get available ids.
	 */
	public function get_ids() {
		return $this->accommodation_ids;
	}

	/**
	 * Get the available accommodation based on args.
	 *
	 * @param array $args The args from URL.
	 *
	 * @return array
	 */
	protected function filtered_by_availability( $args ) {
		$all_args = array(
			'type'    => 'accommodation',
			'status'  => 'publish',
			'limit'   => -1,
			'orderby' => 'menu_order title',
			'order'   => 'asc',
		);
		$products = \wc_get_products( $all_args );

		$available_ids = array();

		if ( $products && ! empty( $args['checkin'] ) && ! empty( $args['checkout'] ) ) {
			$checkin  = $args['checkin'];
			$checkout = $args['checkout'];
			$rooms    = isset( $args['rooms'] ) ? max( 1, absint( $args['rooms'] ) ) : 1;
			foreach ( $products as $product ) {
				if ( ! $this->should_hide_unavailable ) {
					$available_ids[] = $product->get_id();
					continue;
				}

				// If no rates available on the date provided. Skip.
				if ( empty( $product->has_active_rates_by_date( $checkin, $checkout ) ) ) {
					continue;
				}

				// Check availability by dates (checkin - checkout) and number of rooms.
				$available_by_dates_and_room = $product->check_availability( $checkin, $checkout, $rooms );
				if ( is_wp_error( $available_by_dates_and_room ) ) {
					continue;
				}

				// Check availability by allowed adults (combined capacity of the requested rooms).
				if ( $product->get_max_adults() && ( absint( $product->get_max_adults() ) * $rooms ) < absint( $args['adults'] ) ) {
					continue;
				}

				// Check availability by allowed children.
				if ( ! $product->get_max_children() && intval( $args['children'] ) > 0 ) {
					continue;
				}

				if ( ( absint( $product->get_max_children() ) * $rooms ) < absint( $args['children'] ) ) {
					continue;
				}

				$available_ids[] = $product->get_id();
			}
		}

		return $available_ids;
	}
}
