<?php

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

use Automattic\WooCommerce\StoreApi\Exceptions\RouteException;
use Automattic\WooCommerce\StoreApi\Utilities\CartController;
use DropshippingExportFreeVendor\WPDesk\Library\DropshippingExport\Service\Ucp\Checkout\Violations\Violation;
use DropshippingExportFreeVendor\WPDesk\Library\DropshippingExport\Service\Ucp\Checkout\Violations\Violations;
use DropshippingExportFreeVendor\WPDesk\Library\DropshippingExport\Service\Ucp\Checkout\ProductResolver;
use DropshippingExportFreeVendor\WPDesk\Library\DropshippingExport\Service\Ucp\Checkout\Violations\CheckoutError;
/**
 * Populates WooCommerce cart with UCP line items.
 *
 * @see https://ucp.dev/2026-01-23/schemas/shopping/types/line_item.json
 *
 * @phpstan-import-type Item from CheckoutSessionBuilder
 * @phpstan-import-type LineItem from CheckoutSessionBuilder
 */
final class ItemPopulator
{
    private CartController $cart_controller;
    private ProductResolver $product_resolver;
    public function __construct(CartController $cart_controller, ProductResolver $product_resolver)
    {
        $this->cart_controller = $cart_controller;
        $this->product_resolver = $product_resolver;
    }
    /**
     * Add line items to cart.
     *
     * @param array<int, LineItem> $line_items UCP line items.
     *
     * @throws CartSetupException On hard failure.
     */
    public function populate(array $line_items): Violations
    {
        $violations = Violations::empty();
        $this->cart_controller->empty_cart();
        foreach ($line_items as $item_index => $line_item) {
            $product_id = \wc_clean(\wp_unslash($line_item['item']['id'] ?? ''));
            if (empty($product_id)) {
                throw new CartSetupException(CheckoutError::invalid_request('missing', 'Product ID is required', "\$.line_items[{$item_index}].item.id"));
            }
            $product = $this->product_resolver->get_product($product_id);
            if (null === $product) {
                throw new CartSetupException(CheckoutError::invalid_request('missing', "Product not found: {$product_id}", "\$.line_items[{$item_index}].item.id"));
            }
            $product_id = $product->get_id();
            $quantity = (int) ($line_item['quantity'] ?? 1);
            try {
                $this->cart_controller->add_to_cart(['id' => $product_id, 'quantity' => $quantity]);
            } catch (RouteException $e) {
                $violations = $this->handle_cart_exception($e, $item_index, $violations);
            }
        }
        return $violations;
    }
    private function handle_cart_exception(RouteException $e, int $item_index, Violations $violations): Violations
    {
        $message = \wp_specialchars_decode($e->getMessage(), \ENT_QUOTES);
        $param = '$.items[' . $item_index . ']';
        switch ($e->getErrorCode()) {
            case 'woocommerce_rest_product_out_of_stock':
            case 'woocommerce_rest_product_partially_out_of_stock':
                return $violations->add(Violation::out_of_stock($message, $param));
        }
        throw new CartSetupException(CheckoutError::invalid_request('invalid', $message, $param));
    }
}
