<?php

namespace WeDevs\DokanPro\Modules\PayPalMarketplace\Blocks;

use Exception;
use WC_Order;
use WeDevs\DokanPro\Modules\PayPalMarketplace\Helper;

/**
 * Dokan PayPal Marketplace Woocommerce block support class.
 *
 * @since 3.15.0
 */
class BlockHooks {

    /**
     * Class constructor.
     *
     * @since 3.15.0
     *
     * @return void
     */
    public function __construct() {
        add_action( 'woocommerce_blocks_loaded', [ $this, 'checkout_blocks_support' ] );
        // Runs before WooCommerce's legacy gateway handler, which is hooked at priority 999.
        add_action( 'woocommerce_rest_checkout_process_payment_with_context', [ $this, 'validate_paypal_order_id' ], 9 );
    }

    /**
     * Verify the PayPal order id submitted from the checkout block.
     *
     * With Smart Payment Buttons the customer approves the payment before placing
     * their order, and the block sends back the id of the PayPal order they
     * approved. It must match the PayPal order this WooCommerce order was created
     * against, otherwise the capture belongs to a different order and the payment
     * must not be treated as settled.
     *
     * @since 5.0.8
     *
     * @param \Automattic\WooCommerce\StoreApi\Payments\PaymentContext $context Payment context.
     *
     * @throws Exception If the submitted PayPal order id does not belong to this order.
     *
     * @return void
     */
    public function validate_paypal_order_id( $context ) {
        // The context exposes its protected properties through a magic getter.
        if ( ! is_object( $context ) || Helper::get_gateway_id() !== $context->payment_method ) { // @phpstan-ignore-line
            return;
        }

        $order = $context->order; // @phpstan-ignore-line

        if ( ! $order instanceof WC_Order ) {
            return;
        }

        $payment_data = (array) $context->payment_data; // @phpstan-ignore-line

        $submitted_paypal_order_id = isset( $payment_data['dokan_paypal_order_id'] )
            ? sanitize_text_field( $payment_data['dokan_paypal_order_id'] )
            : '';

        // The standard button flow approves after placing the order, so it sends nothing here.
        if ( '' === $submitted_paypal_order_id ) {
            return;
        }

        if ( $submitted_paypal_order_id !== $order->get_meta( '_dokan_paypal_order_id' ) ) {
            throw new Exception( esc_html__( 'The PayPal payment could not be verified for this order. Please try again.', 'dokan' ) );
        }
    }

    /**
     * Register cart checkout block support class.
     * As mentioned in woocommerce docs the class needs to be hooked in 'woocommerce_blocks_loaded` hook.
     *
     * @since 3.15.0
     *
     * @return void
     */
    public function checkout_blocks_support() {
        if ( ! class_exists( 'Automattic\WooCommerce\Blocks\Payments\Integrations\AbstractPaymentMethodType' ) ) {
            return;
        }

        add_action( 'woocommerce_blocks_payment_method_type_registration', [ $this, 'register_block_support_class' ] );
    }

    /**
     * Registering the block support class.
     *
     * @param \Automattic\WooCommerce\Blocks\Payments\PaymentMethodRegistry $payment_method_registry
     *
     * @return void
     */
    public function register_block_support_class( $payment_method_registry ) {
        $payment_method_registry->register( new CartCheckoutBlockSupport() );
    }
}
