<?php

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

use DropshippingExportFreeVendor\WPDesk\Library\DropshippingExport\Service\Ucp\Checkout\Builder\CartSetupException;
use DropshippingExportFreeVendor\WPDesk\Library\DropshippingExport\Service\Ucp\Checkout\Builder\CheckoutSessionBuilder;
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\Response\CartDataSource;
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\SessionLoader;
use DropshippingExportFreeVendor\WPDesk\Library\DropshippingExport\Service\Ucp\Checkout\State\CheckoutSessionDataRepository;
use DropshippingExportFreeVendor\WPDesk\Library\DropshippingExport\Service\Ucp\Checkout\State\CheckoutStateRepository;
use WP_REST_Request;
use WP_REST_Response;
/**
 * Update an existing checkout session.
 */
final class UpdateCheckoutSession implements CheckoutRouteHandler
{
    private SessionLoader $session_loader;
    private CheckoutSessionBuilder $builder;
    private CheckoutResponseMapper $mapper;
    private CheckoutStatusResolver $status_resolver;
    private CheckoutStateRepository $state;
    private CheckoutSessionDataRepository $session_data;
    private CouponTitleFormatter $coupon_formatter;
    public function __construct(SessionLoader $session_loader, CheckoutSessionBuilder $builder, CheckoutResponseMapper $mapper, CheckoutStatusResolver $status_resolver, CheckoutStateRepository $state, CheckoutSessionDataRepository $session_data, CouponTitleFormatter $coupon_formatter)
    {
        $this->session_loader = $session_loader;
        $this->builder = $builder;
        $this->mapper = $mapper;
        $this->status_resolver = $status_resolver;
        $this->state = $state;
        $this->session_data = $session_data;
        $this->coupon_formatter = $coupon_formatter;
    }
    public function get_path(): string
    {
        return '/checkout-sessions/(?P<id>[a-zA-Z0-9\-\_\.]+)';
    }
    public function get_method(): string
    {
        return 'PUT';
    }
    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();
        }
        try {
            $violations = $this->builder->with_line_items($request->get_param('line_items'))->with_buyer($request->get_param('buyer') ?? [])->with_fulfillment($request->get_param('fulfillment') ?? [])->with_coupons($request->get_param('discounts'))->build(\WC()->customer);
        } catch (CartSetupException $e) {
            return $e->get_error()->to_rest_response();
        } catch (\Exception $e) {
            $message = \wp_specialchars_decode($e->getMessage(), \ENT_QUOTES);
            return CheckoutError::processing_error('totals_calculation_error', $message)->to_rest_response();
        }
        $this->state->set_has_violations($violations->has_violations());
        $source = new CartDataSource(\WC()->cart, \WC()->customer, $violations, $this->session_data, $this->coupon_formatter);
        $response_data = $this->mapper->map($session_id, $source);
        return new WP_REST_Response($response_data, 200);
    }
}
