<?php
/**
 * Timed Products frontend guards.
 *
 * @package FoodOrd
 */

defined( 'ABSPATH' ) || exit;

/**
 * Class Foodord_Timed_Products_Frontend
 */
class Foodord_Timed_Products_Frontend {
	/**
	 * Initialize hooks.
	 */
	public function init(): void {
		if ( ! class_exists( 'Foodord_Timed_Products' ) ) {
			return;
		}

		add_action( 'wp_ajax_foodord_get_products_availability', array( $this, 'ajax_get_products_availability' ) );
		add_action( 'wp_ajax_nopriv_foodord_get_products_availability', array( $this, 'ajax_get_products_availability' ) );

		if ( is_admin() && ! wp_doing_ajax() ) {
			return;
		}

		add_filter( 'woocommerce_product_is_visible', array( $this, 'filter_product_visible' ), 10, 2 );
		add_filter( 'woocommerce_variation_is_visible', array( $this, 'filter_variation_visible' ), 10, 3 );
		add_filter( 'woocommerce_cart_item_visible', array( $this, 'filter_cart_item_visibility' ), 10, 2 );
		add_action( 'woocommerce_cart_loaded_from_session', array( $this, 'maybe_prune_cart_items' ) );
	}

	/**
	 * Hide products from loops when rule blocks them.
	 *
	 * @param bool $visible   Current visibility flag.
	 * @param int  $product_id Product ID.
	 */
	public function filter_product_visible( bool $visible, int $product_id ): bool {
		if ( ! $visible ) {
			return false;
		}

		return Foodord_Timed_Products::product_is_allowed( $product_id );
	}

	/**
	 * Hide variations when blocked.
	 *
	 * @param bool $visible   Visibility flag.
	 * @param int  $variation_id Variation ID.
	 * @param int  $parent_id Parent product ID.
	 */
	public function filter_variation_visible( bool $visible, int $variation_id, int $parent_id ): bool {
		if ( ! $visible ) {
			return false;
		}

		if ( $variation_id > 0 && ! Foodord_Timed_Products::product_is_allowed( $variation_id ) ) {
			return false;
		}

		if ( $parent_id > 0 && ! Foodord_Timed_Products::product_is_allowed( $parent_id ) ) {
			return false;
		}

		return true;
	}

	/**
	 * Hide cart line items when rule blocks them.
	 *
	 * @param bool  $visible  Current flag.
	 * @param array $cart_item Cart item data.
	 */
	public function filter_cart_item_visibility( bool $visible, array $cart_item ): bool {
		if ( ! $visible ) {
			return false;
		}

		$product_id = isset( $cart_item['variation_id'] ) && $cart_item['variation_id'] > 0
			? (int) $cart_item['variation_id']
			: (int) ( $cart_item['product_id'] ?? 0 );

		return Foodord_Timed_Products::product_is_allowed( $product_id );
	}

	/**
	 * Remove hidden products from cart and show notice.
	 */
	public function maybe_prune_cart_items(): void {
		if ( ! function_exists( 'WC' ) || ! WC()->cart ) {
			return;
		}

		$cart        = WC()->cart;
		$removed_any = false;

		foreach ( $cart->get_cart() as $cart_item_key => $cart_item ) {
			$product_id = isset( $cart_item['variation_id'] ) && $cart_item['variation_id'] > 0
				? (int) $cart_item['variation_id']
				: (int) ( $cart_item['product_id'] ?? 0 );

			if ( $product_id <= 0 ) {
				continue;
			}

			if ( Foodord_Timed_Products::product_is_allowed( $product_id ) ) {
				continue;
			}

			$cart->remove_cart_item( $cart_item_key );
			$removed_any = true;
		}

		if ( $removed_any && function_exists( 'wc_add_notice' ) ) {
			wc_add_notice( __( 'Some products were removed because they are currently unavailable.', 'foodord' ), 'notice' );
		}
	}

	/**
	 * Return current availability map for product cards.
	 */
	public function ajax_get_products_availability(): void {
		$nonce = filter_input( INPUT_POST, 'nonce', FILTER_SANITIZE_FULL_SPECIAL_CHARS );
		$nonce = is_string( $nonce ) ? sanitize_text_field( wp_unslash( $nonce ) ) : '';

		if ( '' !== $nonce ) {
			$nonce_valid = wp_verify_nonce( $nonce, 'foodord_timed_products_nonce' ) || wp_verify_nonce( $nonce, 'foodord_product_modal_nonce' );
			if ( ! $nonce_valid ) {
				wp_send_json_error(
					array(
						'message' => __( 'Invalid availability nonce.', 'foodord' ),
					),
					403
				);
			}
		}

		$product_ids_raw = filter_input( INPUT_POST, 'product_ids', FILTER_DEFAULT, FILTER_REQUIRE_ARRAY );
		$product_ids     = is_array( $product_ids_raw ) ? array_values( array_unique( array_filter( array_map( 'absint', wp_unslash( $product_ids_raw ) ) ) ) ) : array();

		if ( empty( $product_ids ) ) {
			wp_send_json_success(
				array(
					'products' => array(),
				)
			);
		}

		$products = array();

		foreach ( $product_ids as $product_id ) {
			$products[ $product_id ] = array(
				'available' => class_exists( 'Foodord_Product_Availability' ) ? Foodord_Product_Availability::is_available( $product_id ) : true,
			);
		}

		wp_send_json_success(
			array(
				'products' => $products,
			)
		);
	}
}
