<?php

/**
 * The endpoint to get a PayPal order.
 *
 * @package WooCommerce\PayPalCommerce\Button\Endpoint
 */
declare (strict_types=1);
namespace WooCommerce\PayPalCommerce\Button\Endpoint;

use Exception;
use WooCommerce\PayPalCommerce\Vendor\Psr\Log\LoggerInterface;
use WooCommerce\PayPalCommerce\ApiClient\Endpoint\OrderEndpoint;
use WooCommerce\PayPalCommerce\ApiClient\Exception\PayPalApiException;
use WooCommerce\PayPalCommerce\ApiClient\Exception\RuntimeException;
use WooCommerce\PayPalCommerce\Button\Exception\NonceValidationException;
use WooCommerce\PayPalCommerce\Button\Session\CartDataTransientStorage;
/**
 * Class GetOrderEndpoint
 */
class GetOrderEndpoint implements \WooCommerce\PayPalCommerce\Button\Endpoint\EndpointInterface
{
    public const ENDPOINT = 'ppc-get-order';
    private \WooCommerce\PayPalCommerce\Button\Endpoint\RequestData $request_data;
    private OrderEndpoint $api_endpoint;
    private LoggerInterface $logger;
    private CartDataTransientStorage $cart_data_storage;
    public function __construct(\WooCommerce\PayPalCommerce\Button\Endpoint\RequestData $request_data, OrderEndpoint $order_endpoint, LoggerInterface $logger, CartDataTransientStorage $cart_data_storage)
    {
        $this->request_data = $request_data;
        $this->api_endpoint = $order_endpoint;
        $this->logger = $logger;
        $this->cart_data_storage = $cart_data_storage;
    }
    public static function nonce(): string
    {
        return self::ENDPOINT;
    }
    public function handle_request(): void
    {
        try {
            $data = $this->request_data->read_request($this->nonce());
            $order_id = $data['order_id'] ?? '';
            if (empty($order_id)) {
                wp_send_json_error(array('message' => __('Order ID is required', 'woocommerce-paypal-payments')));
            }
            $cart_data = $this->cart_data_storage->get_by_paypal_order_id($order_id);
            if (!$cart_data) {
                $this->logger->warning(sprintf('Unauthorized GetOrder attempt for PayPal order %s. No CartData found.', $order_id));
                wp_send_json_error(array('message' => __('Invalid or expired order access', 'woocommerce-paypal-payments')));
            }
            $stored_user_id = $cart_data->user_id();
            $current_user_id = get_current_user_id();
            $authorized = \false;
            if ($stored_user_id !== 0 && $current_user_id === $stored_user_id) {
                $authorized = \true;
            } elseif ($stored_user_id === 0 && $current_user_id === 0) {
                $stored_session = $cart_data->session_customer_id();
                $current_session = WC()->session ? (string) WC()->session->get_customer_id() : null;
                if ($stored_session !== null && $current_session === $stored_session) {
                    $authorized = \true;
                }
            }
            if (!$authorized) {
                $this->logger->warning(sprintf('Unauthorized GetOrder attempt for PayPal order %s. Session mismatch.', $order_id));
                wp_send_json_error(array('message' => __('Invalid or expired order access', 'woocommerce-paypal-payments')));
            }
            $order = $this->api_endpoint->order($order_id);
            wp_send_json_success($order->to_array());
        } catch (NonceValidationException $error) {
            wp_send_json_error(array('message' => $error->getMessage()), 400);
        } catch (RuntimeException $error) {
            $this->logger->error('Get order failed: ' . $error->getMessage());
            wp_send_json_error(array('name' => $error instanceof PayPalApiException ? $error->name() : '', 'message' => $error->getMessage(), 'code' => $error->getCode(), 'details' => $error instanceof PayPalApiException ? $error->details() : array()));
        } catch (Exception $exception) {
            $this->logger->error('Get order failed: ' . $exception->getMessage());
            wp_send_json_error(array('message' => $exception->getMessage()));
        }
    }
}
