<?php
/**
 * WooCommerce Blocks compatibility.
 *
 * - Registers rental data in the Store API cart item schema so block-based
 *   cart and checkout pages expose rental dates to the REST response.
 * - Redirects rental products' loop "Add to cart" button to the product page
 *   so customers always select dates before adding to cart.
 *
 * @package WooEquipmentRental
 */

declare( strict_types=1 );

if ( ! defined( 'ABSPATH' ) ) {
	exit;
}

/**
 * Class WCRent_Rental_Blocks
 */
class WCRent_Rental_Blocks {

	/**
	 * Registers all hooks.
	 */
	public static function init(): void {
		add_action( 'woocommerce_blocks_loaded', array( self::class, 'register_store_api_extension' ) );
		add_filter( 'woocommerce_product_add_to_cart_url', array( self::class, 'redirect_loop_add_to_cart_url' ), 10, 2 );
		add_filter( 'woocommerce_product_add_to_cart_text', array( self::class, 'redirect_loop_add_to_cart_text' ), 10, 2 );
		add_filter( 'woocommerce_loop_add_to_cart_link', array( self::class, 'loop_add_to_cart_link' ), 10, 3 );
	}

	/**
	 * Registers a Store API extension so rental data is included in the
	 * /wc/store/v1/cart/items endpoint response.
	 */
	public static function register_store_api_extension(): void {
		if ( ! function_exists( 'woocommerce_store_api_register_endpoint_data' ) ) {
			return;
		}

		woocommerce_store_api_register_endpoint_data(
			array(
				'endpoint'        => \Automattic\WooCommerce\StoreApi\Schemas\V1\CartItemSchema::IDENTIFIER,
				'namespace'       => 'wcrent',
				'data_callback'   => array( self::class, 'store_api_data_callback' ),
				'schema_callback' => array( self::class, 'store_api_schema_callback' ),
				'schema_type'     => ARRAY_A,
			)
		);
	}

	/**
	 * Returns rental data for a cart item in the Store API response.
	 *
	 * @param array<string, mixed> $cart_item Cart item data.
	 * @return array{rental_start: string, rental_end: string, rental_days: int}
	 */
	public static function store_api_data_callback( array $cart_item ): array {
		return array(
			'rental_start' => isset( $cart_item['rental_start'] ) ? (string) $cart_item['rental_start'] : '',
			'rental_end'   => isset( $cart_item['rental_end'] ) ? (string) $cart_item['rental_end'] : '',
			'rental_days'  => isset( $cart_item['rental_days'] ) ? (int) $cart_item['rental_days'] : 0,
		);
	}

	/**
	 * Defines the JSON schema for the rental extension data on cart items.
	 *
	 * @return array<string, array<string, mixed>>
	 */
	public static function store_api_schema_callback(): array {
		return array(
			'rental_start' => array(
				'description' => __( 'Rental start date (YYYY-MM-DD).', 'harbor-equipment-rental-for-woocommerce' ),
				'type'        => 'string',
				'context'     => array( 'view', 'edit' ),
				'readonly'    => true,
			),
			'rental_end'   => array(
				'description' => __( 'Rental end date (YYYY-MM-DD).', 'harbor-equipment-rental-for-woocommerce' ),
				'type'        => 'string',
				'context'     => array( 'view', 'edit' ),
				'readonly'    => true,
			),
			'rental_days'  => array(
				'description' => __( 'Number of rental days.', 'harbor-equipment-rental-for-woocommerce' ),
				'type'        => 'integer',
				'context'     => array( 'view', 'edit' ),
				'readonly'    => true,
			),
		);
	}

	/**
	 * Redirects the loop add-to-cart URL for rental products to the product page.
	 * Rental products require date selection; AJAX add-to-cart bypasses this.
	 *
	 * @param string     $url     Default add-to-cart URL.
	 * @param WC_Product $product Product object.
	 * @return string
	 */
	public static function redirect_loop_add_to_cart_url( string $url, WC_Product $product ): string {
		if ( ! WCRent_Utils::is_rental_product( (int) $product->get_id() ) || is_product() ) {
			return $url;
		}
		return (string) get_permalink( $product->get_id() );
	}

	/**
	 * Changes the loop "Add to cart" button text for rental products.
	 *
	 * @param string     $text    Default button text.
	 * @param WC_Product $product Product object.
	 * @return string
	 */
	public static function redirect_loop_add_to_cart_text( string $text, WC_Product $product ): string {
		if ( ! WCRent_Utils::is_rental_product( (int) $product->get_id() ) || is_product() ) {
			return $text;
		}
		return __( 'Select dates', 'harbor-equipment-rental-for-woocommerce' );
	}

	/**
	 * Replaces the loop add-to-cart anchor so it is a plain link (no AJAX classes).
	 * This prevents WooCommerce's AJAX add-to-cart from firing for rental products.
	 *
	 * @param string              $link    Default add-to-cart link HTML.
	 * @param WC_Product          $product Product object.
	 * @param array<string,mixed> $args   Additional args.
	 * @return string
	 */
	public static function loop_add_to_cart_link( string $link, WC_Product $product, array $args ): string {
		if ( ! WCRent_Utils::is_rental_product( (int) $product->get_id() ) || is_product() ) {
			return $link;
		}

		$url = get_permalink( $product->get_id() );

		return sprintf(
			'<a href="%s" class="button product_type_rental">%s</a>',
			esc_url( $url ),
			esc_html__( 'Select dates', 'harbor-equipment-rental-for-woocommerce' )
		);
	}
}
