<?php
/**
 * Checkout page recommendations.
 *
 * @package PRECO
 */

namespace PRECO\Includes\Frontend\Pages;

use PRECO\Includes\Frontend\Core\PageRecommendationsBase;

defined( 'ABSPATH' ) || exit;

/**
 * Checkout page recommendations.
 */
class CheckoutPageRecommendations extends PageRecommendationsBase {

	/**
	 * Page key in option structure.
	 *
	 * @return string
	 */
	protected function page_key() {
		return 'checkout';
	}

	/**
	 * Is the current request the relevant page?
	 *
	 * @return bool
	 */
	protected function is_active_page() {
		if ( ! function_exists( 'is_checkout' ) || ! \is_checkout() ) {
			return false;
		}
		// Exclude thank-you (order received) screen.
		return ! ( function_exists( 'is_order_received_page' ) && \is_order_received_page() );
	}

	/**
	 * Map of location key => hook definition.
	 *
	 * @return array
	 */
	protected function locations() {
		return array(
			'before-checkout-form'        => array(
				'hook'          => 'woocommerce_before_checkout_form',
				'priority'      => 10,
				'accepted_args' => 1,
			),
			'after-checkout-form'         => array(
				'hook'          => 'woocommerce_after_checkout_form',
				'priority'      => 10,
				'accepted_args' => 1,
			),
			'after-checkout-order-totals' => array(
				'hook'          => 'woocommerce_review_order_after_payment',
				'priority'      => 10,
				'accepted_args' => 1,
			),
		);
	}

	/**
	 * Register hooks for both classic and block-based checkout.
	 *
	 * Classic checkout: uses woocommerce_before/after_checkout_form actions.
	 * Block checkout:   uses the render_block_woocommerce/checkout filter.
	 *
	 * @return void
	 */
	public function register_hooks() {
		if ( ! $this->is_active_page() ) {
			return;
		}
		if ( ! $this->is_page_enabled_for_request() ) {
			return;
		}

		// Classic checkout hooks (shortcode-based checkout page).
		foreach ( $this->locations() as $location_key => $def ) {
			$hook          = isset( $def['hook'] ) ? (string) $def['hook'] : '';
			$priority      = isset( $def['priority'] ) ? (int) $def['priority'] : 10;
			$accepted_args = isset( $def['accepted_args'] ) ? (int) $def['accepted_args'] : 0;
			if ( ! $hook ) {
				continue;
			}
			add_action(
				$hook,
				function ( ...$args ) use ( $location_key ) {
					$this->render_location( $location_key, $args );
				},
				$priority,
				max( 0, $accepted_args )
			);
		}

		// Block checkout: inject via render_block filter on the woocommerce/checkout block.
		add_filter(
			'render_block_woocommerce/checkout',
			function ( $block_content ) {
				ob_start();
				$this->render_location( 'before-checkout-form', array() );
				$before = ob_get_clean();

				ob_start();
				$this->render_location( 'after-checkout-form', array() );
				$after = ob_get_clean();

				return $before . $block_content . $after;
			},
			10,
			1
		);
		add_filter(
			'render_block_woocommerce/checkout-order-summary-block',
			function ( $block_content ) {

				ob_start();
				$this->render_location( 'after-checkout-order-totals', array() );
				$after = ob_get_clean();

				return $block_content . $after;
			},
			10,
			1
		);
	}

	/**
	 * Build context for rule evaluation.
	 *
	 * @param string $location_key Location key.
	 * @param array  $hook_args Hook args.
	 * @return array
	 */
	protected function build_context( $location_key, $hook_args ) {
		$exclude_ids = array();
		if ( function_exists( 'WC' ) && \WC() && \WC()->cart && method_exists( \WC()->cart, 'get_cart' ) ) {
			foreach ( \WC()->cart->get_cart() as $item ) {
				if ( isset( $item['product_id'] ) ) {
					$exclude_ids[] = absint( $item['product_id'] );
				}
			}
		}

		return array(
			'page'         => $this->page_key(),
			'location_key' => (string) $location_key,
			'exclude_ids'  => array_values( array_unique( array_filter( $exclude_ids ) ) ),
		);
	}
}
