<?php
namespace Prodigy\Includes\Frontend\Actions;

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

use Prodigy\Includes\Content\Prodigy_Product_Parser;
use Prodigy\Includes\Content\Prodigy_Request_Maker;
use Prodigy\Includes\Helpers\Prodigy_Cookies;
use Prodigy\includes\models\Prodigy_Order;
use Prodigy\Includes\Prodigy_Cart;

/**
 * Prodigy buy now action
 *
 * @version    3.0.3
 * @package    Prodigy
 * @subpackage Prodigy/includes
 */
class Prodigy_Buy_Now {

	/** @var int */
	const NUMBER_OF_ITEMS = 1;
	const ACTION_NAME     = 'buy_now';

	/** @var Prodigy_Request_Maker  */
	private Prodigy_Request_Maker $request_maker;

	/** @var string  */
	private string $product_parser_class;

	/** @var Prodigy_Order  */
	private Prodigy_Order $order;

	/** @var Prodigy_Cart  */
	private Prodigy_Cart $cart;

	/**
	 * @param Prodigy_Request_Maker $request_maker
	 * @param Prodigy_Order         $order
	 * @param Prodigy_Cart          $cart
	 */
	public function __construct(
		Prodigy_Request_Maker $request_maker,
		Prodigy_Order $order,
		Prodigy_Cart $cart
	) {
		$this->request_maker        = $request_maker;
		$this->product_parser_class = Prodigy_Product_Parser::class;
		$this->order                = $order;
		$this->cart                 = $cart;

		add_action( 'init', array( $this, 'custom_url_structure' ), 999 );
		add_action( 'template_redirect', array( $this, 'custom_action_listener' ), 999 );
		add_filter( 'query_vars', array( $this, 'custom_query_vars' ), 999 );
	}

	/**
	 * Add rewrite rule for the custom URL structure (buy-now?product-id)
	 *
	 * @return void
	 */
	public function custom_url_structure() {
		add_rewrite_rule( '^buy-now/?', 'index.php?custom_action=buy_now', 'top' );
	}

	/**
	 * @param array $vars
	 *
	 * @return array
	 */
	public function custom_query_vars( array $vars ): array {
		$vars[] = 'custom_action';

		return $vars;
	}

	/**
	 * @throws \Exception
	 */
	public function custom_action_listener() {
		if ( ! isset( $_GET['_wpnonce'] ) || ! wp_verify_nonce( sanitize_key( $_GET['_wpnonce'] ), 'buy-now' ) ) {
			return;
		}

		$custom_action = get_query_var( 'custom_action' );
		if ( $custom_action !== self::ACTION_NAME && ! isset( $_GET['product-id'] ) ) {
			return;
		}

		$product_id    = filter_var( wp_unslash( $_GET['product-id'] ), FILTER_VALIDATE_INT );
		$custom_action = get_query_var( 'custom_action' );
		if ( $custom_action === self::ACTION_NAME && isset( $product_id ) ) {
			$product_data   = $this->request_maker->do_product_request( (int) $product_id );
			$product        = new $this->product_parser_class( $product_data );
			$master_variant = $product->get_master_variant();

			$cart_user_session = Prodigy_Cookies::get_user_cart_cookie();
			$order_token       = $this->order->get_order_token( $cart_user_session );

			if ( $order_token !== null ) {
				$this->request_maker->do_delete_order_request( $order_token );
			}

			$item                      = $_POST;
			$item['remote_product_id'] = $master_variant['id'];
			$item['count']             = self::NUMBER_OF_ITEMS;
			$request                   = $this->cart->set_cart_prepare_request( $item );

			$cart_response = $this->request_maker->do_init_order_request( $request );
			if ( ! isset( $cart_response['errors'] ) ) {
				$this->order->create_order( $cart_response, $cart_user_session );
				$order_token = $cart_response['data']['attributes']['token'];
			} elseif ( $cart_response['code'] !== \WP_Http::OK ) {
				wp_safe_redirect( home_url( '404' ) );
				$this->prodigy_exit();
			}

			$order        = Prodigy_Order::get_order_number( $order_token );
			$checkout_url = Prodigy_Cart::get_checkout_url( $order, $order_token );

			wp_redirect( $checkout_url );
			$this->prodigy_exit();
		}
	}

	/**
	 * Wrapper for exit to allow mocking in tests.
	 */
	protected function prodigy_exit() {
		exit;
	}
}
