<?php

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

use DropshippingExportFreeVendor\WPDesk\Library\DropshippingExport\Service\Ucp\Checkout\CheckoutOrderCreatorInterface;
use DropshippingExportFreeVendor\WPDesk\Library\DropshippingExport\Service\Ucp\Checkout\CheckoutPaymentExecutorInterface;
use DropshippingExportFreeVendor\WPDesk\Library\DropshippingExport\Service\Ucp\Checkout\CheckoutStatusResolver;
use DropshippingExportFreeVendor\WPDesk\Library\DropshippingExport\Service\Ucp\Checkout\Violations\CheckoutError;
use DropshippingExportFreeVendor\WPDesk\Library\DropshippingExport\Service\Ucp\Checkout\Payment\PaymentHandlerResolver;
use DropshippingExportFreeVendor\WPDesk\Library\DropshippingExport\Service\Ucp\Checkout\Response\CheckoutResponseMapper;
use DropshippingExportFreeVendor\WPDesk\Library\DropshippingExport\Service\Ucp\Checkout\Response\CouponTitleFormatter;
use DropshippingExportFreeVendor\WPDesk\Library\DropshippingExport\Service\Ucp\Checkout\Response\OrderDataSource;
use DropshippingExportFreeVendor\WPDesk\Library\DropshippingExport\Service\Ucp\Checkout\SessionLoader;
use DropshippingExportFreeVendor\WPDesk\Library\DropshippingExport\Service\Ucp\Checkout\State\CheckoutStateRepository;
use WP_REST_Request;
use WP_REST_Response;
/**
 * Complete a checkout session and create an order.
 */
final class CompleteCheckoutSession implements CheckoutRouteHandler
{
    private SessionLoader $session_loader;
    private CheckoutResponseMapper $mapper;
    private CheckoutOrderCreatorInterface $order_creator;
    private CheckoutPaymentExecutorInterface $payment_executor;
    private CheckoutStatusResolver $status_resolver;
    private CheckoutStateRepository $state;
    private PaymentHandlerResolver $payment_resolver;
    private CouponTitleFormatter $coupon_formatter;
    public function __construct(SessionLoader $session_loader, CheckoutResponseMapper $mapper, CheckoutOrderCreatorInterface $order_creator, CheckoutPaymentExecutorInterface $payment_executor, CheckoutStatusResolver $status_resolver, CheckoutStateRepository $state, PaymentHandlerResolver $payment_resolver, CouponTitleFormatter $coupon_formatter)
    {
        $this->session_loader = $session_loader;
        $this->mapper = $mapper;
        $this->order_creator = $order_creator;
        $this->payment_executor = $payment_executor;
        $this->status_resolver = $status_resolver;
        $this->state = $state;
        $this->payment_resolver = $payment_resolver;
        $this->coupon_formatter = $coupon_formatter;
    }
    public function get_path(): string
    {
        return '/checkout-sessions/(?P<id>[a-zA-Z0-9\-\_\.]+)/complete';
    }
    public function get_method(): string
    {
        return 'POST';
    }
    public function handle(WP_REST_Request $request): WP_REST_Response
    {
        $session_id = $request->get_param('id');
        $this->session_loader->load($session_id);
        if (!$this->state->exists()) {
            return CheckoutError::checkout_not_found($session_id)->to_rest_response();
        }
        $status = $this->status_resolver->get_status($session_id);
        if ('completed' === $status) {
            return CheckoutError::checkout_already_completed()->to_rest_response();
        }
        if ('canceled' === $status) {
            return CheckoutError::checkout_already_canceled()->to_rest_response();
        }
        if ('ready_for_complete' !== $status) {
            return CheckoutError::checkout_not_ready($status)->to_rest_response();
        }
        $payment = $request->get_param('payment');
        if (null === $payment) {
            return CheckoutError::invalid_request('missing', 'Payment information is required to complete checkout')->to_rest_response();
        }
        $instruments = $payment['instruments'] ?? [];
        $instrument = $instruments[0] ?? null;
        if (!$instrument) {
            return CheckoutError::invalid_request('missing', 'Payment instrument is required to complete checkout')->to_rest_response();
        }
        $handler_id = $instrument['handler_id'] ?? '';
        $processor = $this->payment_resolver->resolve($handler_id);
        if (!$processor) {
            return CheckoutError::invalid_request('unsupported', \sprintf('Unsupported payment handler: %s', $handler_id))->to_rest_response();
        }
        try {
            $order = $this->order_creator->create_from_cart($session_id, $payment, (array) ($request->get_param('platform') ?? []));
        } catch (\Exception $e) {
            $message = \wp_specialchars_decode($e->getMessage(), \ENT_QUOTES);
            return CheckoutError::invalid_request('invalid', $message)->to_rest_response();
        }
        $payment_result = $this->payment_executor->execute_payment($order, $processor, $instrument);
        if (!$payment_result->is_success()) {
            return CheckoutError::payment_failed($payment_result->get_error() ?? 'Unknown payment error')->to_rest_response();
        }
        $source = new OrderDataSource($order, $this->coupon_formatter);
        $response_data = $this->mapper->map($session_id, $source);
        return new WP_REST_Response($response_data, 200);
    }
}
