<?php

declare (strict_types=1);
namespace DropshippingExportFreeVendor\WPDesk\Library\DropshippingExport\Service\Ucp\Checkout\Handler\Decorator;

use DropshippingExportFreeVendor\WPDesk\Library\DropshippingExport\Service\Ucp\Checkout\Violations\CheckoutError;
use DropshippingExportFreeVendor\WPDesk\Library\DropshippingExport\Service\Ucp\Checkout\Handler\CheckoutRouteHandler;
use DropshippingExportFreeVendor\WPDesk\Library\DropshippingExport\Service\Ucp\Checkout\IdempotencyStore;
use WP_REST_Request;
use WP_REST_Response;
/**
 * Provides idempotency guarantees for checkout mutations.
 */
final class IdempotentCheckoutRouteHandler implements CheckoutRouteHandler
{
    private CheckoutRouteHandler $inner;
    private IdempotencyStore $store;
    public function __construct(CheckoutRouteHandler $inner, IdempotencyStore $store)
    {
        $this->inner = $inner;
        $this->store = $store;
    }
    public function get_path(): string
    {
        return $this->inner->get_path();
    }
    public function get_method(): string
    {
        return $this->inner->get_method();
    }
    public function handle(WP_REST_Request $request): WP_REST_Response
    {
        $idempotency_key = $request->get_header('idempotency-key') ?? '';
        if ('' === $idempotency_key) {
            // Without an idempotency key, we cannot provide idempotency guarantees, but
            // we let HeaderValidator handle the error response if it's required.
            // Or we just proceed if it happens to be a GET request.
            return $this->inner->handle($request);
        }
        $request_data = $request->get_json_params() ?? [];
        $request_hash = $this->store->compute_hash($request_data);
        $cached = $this->store->get($idempotency_key);
        if (null !== $cached) {
            if ($cached['hash'] === $request_hash) {
                return new WP_REST_Response($cached['response'], $cached['status_code']);
            }
            return CheckoutError::idempotency_conflict()->to_rest_response();
        }
        $response = $this->inner->handle($request);
        // Only save successful mutating requests (2xx status codes)
        $status_code = $response->get_status();
        if ($status_code >= 200 && $status_code < 300) {
            $this->store->save($idempotency_key, $request_hash, $status_code, $response->get_data());
        }
        return $response;
    }
}
