<?php

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

use Automattic\WooCommerce\StoreApi\Utilities\CartController;
use DropshippingExportFreeVendor\WPDesk\Library\DropshippingExport\Service\Ucp\Checkout\Violations\Violations;
use DropshippingExportFreeVendor\WPDesk\Library\DropshippingExport\Service\Ucp\Checkout\Violations\CheckoutError;
use WC_Customer;
/**
 * Orchestrates checkout session cart setup.
 *
 * @see https://ucp.dev/2026-01-23/schemas/shopping/checkout.json
 *
 * @phpstan-type Item array{id: string, title?: string, price?: int, image_url?: string}
 * @phpstan-type LineItem array{id?: string, item: Item, quantity: int, totals?: array<string, mixed>, parent_id?: string}
 * @phpstan-type Buyer array{first_name?: string, last_name?: string, email?: string, phone_number?: string, consent?: array<string, mixed>}
 * @phpstan-type ShippingDestination array{id: string, street_address?: string, address_locality?: string, address_region?: string, address_country?: string, postal_code?: string, extended_address?: string, first_name?: string, last_name?: string, phone_number?: string, root?: array<string, mixed>}
 * @phpstan-type FulfillmentOption array{id: string, title: string, description?: string, carrier?: string, totals?: array<string, mixed>}
 * @phpstan-type FulfillmentGroup array{id: string, line_item_ids?: array<int, string>, options?: array<int, FulfillmentOption>, selected_option_id?: string|null}
 * @phpstan-type FulfillmentMethod array{id: string, type: 'shipping'|'pickup', line_item_ids: array<int, string>, destinations?: array<int, ShippingDestination>, selected_destination_id?: string|null, groups?: array<int, FulfillmentGroup>}
 * @phpstan-type Fulfillment array{methods?: array<int, FulfillmentMethod>}
 * @phpstan-type Discounts array{codes?: array<int, string>}
 */
final class CheckoutSessionBuilder
{
    private CartController $cart_controller;
    private ItemPopulator $item_populator;
    private BuyerApplier $buyer_applier;
    private FulfillmentApplier $fulfillment_applier;
    private CouponApplier $coupon_applier;
    /**
     * @var array<int, LineItem>|null
     */
    private ?array $line_items = null;
    /**
     * @var Buyer
     */
    private array $buyer;
    /**
     * @var Fulfillment
     */
    private ?array $fulfillment = null;
    /**
     * @var Discounts|null
     */
    private ?array $discounts = null;
    public function __construct(CartController $cart_controller, ItemPopulator $item_populator, BuyerApplier $buyer_applier, FulfillmentApplier $fulfillment_applier, CouponApplier $coupon_applier)
    {
        $this->cart_controller = $cart_controller;
        $this->item_populator = $item_populator;
        $this->buyer_applier = $buyer_applier;
        $this->fulfillment_applier = $fulfillment_applier;
        $this->coupon_applier = $coupon_applier;
    }
    /**
     * Set line items to add to cart.
     *
     * @param array<int, LineItem>|null $items UCP line items.
     */
    public function with_line_items(?array $items): self
    {
        $this->line_items = $items;
        return $this;
    }
    /**
     * Set buyer data to apply to customer.
     *
     * @param Buyer $buyer UCP buyer object.
     */
    public function with_buyer(array $buyer): self
    {
        $this->buyer = $buyer;
        return $this;
    }
    /**
     * Set fulfillment data to apply to shipping.
     *
     * @param Fulfillment|null $fulfillment UCP fulfillment object.
     */
    public function with_fulfillment(?array $fulfillment): self
    {
        $this->fulfillment = $fulfillment;
        return $this;
    }
    /**
     * Set discounts to apply.
     *
     * @param Discounts|null $discounts UCP discounts object.
     */
    public function with_coupons(?array $discounts): self
    {
        $this->discounts = $discounts;
        return $this;
    }
    /**
     * @throws CartSetupException On hard failure.
     */
    public function build(WC_Customer $customer): Violations
    {
        $violations = Violations::empty();
        if (null !== $this->line_items) {
            $violations = $this->item_populator->populate($this->line_items);
        }
        $violations = $violations->merge($this->buyer_applier->apply($this->buyer, $customer));
        $violations = $violations->merge($this->fulfillment_applier->apply($this->fulfillment, $customer));
        if (null !== $this->discounts) {
            $violations = $violations->merge($this->coupon_applier->apply($this->discounts));
        }
        $this->cart_controller->calculate_totals();
        return $violations;
    }
}
