<?php

namespace Twnt4All\Checkout;

use Twnt4All\Engine\Adapter\DirectLogger;
use Twnt4All\Engine\TwintCore;

class CheckoutAjax
{
    const ACTION_BG_TASK = 'background_task';

    public static function init()
    {
        add_action( 'wp_ajax_t4a_twint_frontend', [ new static(), 'ajax_handler' ] );
        add_action( 'wp_ajax_nopriv_t4a_twint_frontend', [ new static(), 'ajax_handler' ] );
    }

    /**
     * The AJAX handler for orders.
     *
     * This endpoint is registered for both logged-in and anonymous users
     * (`nopriv`) because it is the internal loopback target of the async
     * background polling task started when the customer initiates a TWINT
     * payment. No WP nonce is possible here — the request is generated by
     * the plugin itself and the customer's session may not exist yet.
     *
     * Origin check is done by requiring the caller to present the (order_id,
     * order_uuid) pair : the order_uuid is the SOAP transaction UUID we
     * stored server-side when we called TWINT ; only the plugin knows it.
     * Uses hash_equals to avoid timing enumeration.
     */
    public function ajax_handler()
    {
        // phpcs:disable WordPress.Security.NonceVerification.Missing -- Origin validated below via server-side order_uuid comparison ; no WP nonce possible for this internal loopback.
        $order_id  = isset( $_POST[ 'order_id' ] ) ? absint( wp_unslash( $_POST[ 'order_id' ] ) ) : 0;
        $order_uuid_in = isset( $_POST[ 'order_uuid' ] ) ? sanitize_text_field( wp_unslash( (string) $_POST[ 'order_uuid' ] ) ) : '';
        $action    = isset( $_POST[ 'twnt_tw_action' ] ) ? sanitize_key( wp_unslash( (string) $_POST[ 'twnt_tw_action' ] ) ) : '';
        // phpcs:enable WordPress.Security.NonceVerification.Missing

        if ( $order_id <= 0 || $order_uuid_in === '' ) {
            return;
        }

        $expected_uuid = (string) OrderDataRepository::get_order_data( $order_id, 'order_uuid' );
        if ( $expected_uuid === '' || !hash_equals( $expected_uuid, $order_uuid_in ) ) {
            DirectLogger::log_error( 'ajax_handler', 'Invalid order_uuid for order', $order_id );
            return;
        }

        if ( $action == static::ACTION_BG_TASK ) {

            DirectLogger::log_event( 'ajax_handler:background_task', 'start', $order_id );

            $twint = TwintCore::create_for_transaction( $order_id, T4A_MERCHANT_UUID );
            if ( !$twint ) {
                DirectLogger::log_error( 'ajax_handler:background_task', 'Could not create TWINT object.', $order_id );
                return;
            }

            $iteration = 0;
            do {
                $order_uuid = $twint->dataProvider->get_order_uuid( false );

                session_write_close();
                sleep( 2 );
                $iteration++;

            } while ( !$order_uuid && $iteration < 60 );

            if ( empty( $order_uuid ) ) {
                DirectLogger::log_error( 'ajax_handler:background_task', 'No order UUID.', $order_id );
                return;
            }

            DirectLogger::log_event( 'ajax_handler:background_task', 'Order UUID: ' . $order_uuid, $order_id );
            $twint->transactionHandler->background_task();
        }
    }
}