<?php

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

use DropshippingExportFreeVendor\WPDesk\Library\DropshippingExport\Service\Ucp\Checkout\State\CheckoutSessionDataRepository;
use DropshippingExportFreeVendor\WPDesk\Library\DropshippingExport\Service\Ucp\Checkout\Violations\Violations;
use WC_Cart;
use WC_Customer;
/**
 * Data source from WC_Cart (active checkout session).
 */
final class CartDataSource implements CheckoutDataSource, ProvidesCheckoutMessages
{
    private WC_Cart $cart;
    private WC_Customer $customer;
    private Violations $violations;
    private string $status_override;
    private CheckoutSessionDataRepository $session_data;
    private CouponTitleFormatter $coupon_formatter;
    public function __construct(WC_Cart $cart, WC_Customer $customer, Violations $violations, CheckoutSessionDataRepository $session_data, CouponTitleFormatter $coupon_formatter, string $status_override = '')
    {
        $this->cart = $cart;
        $this->customer = $customer;
        $this->violations = $violations;
        $this->session_data = $session_data;
        $this->coupon_formatter = $coupon_formatter;
        $this->status_override = $status_override;
    }
    public function get_status(): string
    {
        if ('' !== $this->status_override) {
            return $this->status_override;
        }
        if ($this->violations->has_violations()) {
            return 'requires_escalation';
        }
        return 'ready_for_complete';
    }
    public function get_currency(): string
    {
        return \get_woocommerce_currency();
    }
    public function get_line_items(): array
    {
        $cart_items = $this->cart->get_cart();
        $line_items = [];
        $index = 1;
        foreach ($cart_items as $cart_item_key => $cart_item) {
            /** @var \WC_Product $product */
            $product = $cart_item['data'];
            $subtotal_cents = (int) \round((float) $cart_item['line_subtotal'] * 100);
            $total_cents = (int) \round((float) $cart_item['line_total'] * 100);
            $discount_cents = $subtotal_cents - $total_cents;
            $line_items[] = ['id' => 'li_' . $index, 'item' => ['id' => (string) $product->get_id(), 'title' => $product->get_name(), 'price' => (int) \round((float) $product->get_price() * 100)], 'quantity' => (int) $cart_item['quantity'], 'totals' => [['type' => 'subtotal', 'amount' => $subtotal_cents], ['type' => 'discount', 'amount' => $discount_cents], ['type' => 'total', 'amount' => $total_cents]]];
            ++$index;
        }
        return $line_items;
    }
    public function get_totals(): array
    {
        $subtotal_cents = (int) \round($this->cart->get_subtotal() * 100);
        $discount_cents = (int) \round($this->cart->get_discount_total() * 100);
        $chosen_methods = \WC()->session ? \WC()->session->get('chosen_shipping_methods', []) : [];
        $has_shipping = !empty($chosen_methods) && !empty($chosen_methods[0]);
        $shipping_cents = $has_shipping ? (int) \round((float) $this->cart->get_shipping_total() * 100) : 0;
        $tax_cents = $has_shipping ? (int) \round((float) $this->cart->get_total_tax() * 100) : 0;
        $total_cents = $subtotal_cents - $discount_cents + $shipping_cents + $tax_cents;
        return [['type' => 'subtotal', 'amount' => $subtotal_cents], ['type' => 'discount', 'amount' => $discount_cents], ['type' => 'fulfillment', 'amount' => $shipping_cents], ['type' => 'tax', 'amount' => $tax_cents], ['type' => 'total', 'amount' => $total_cents]];
    }
    public function get_buyer(): array
    {
        $buyer = ['email' => $this->customer->get_billing_email() ?: '', 'first_name' => $this->customer->get_billing_first_name() ?: '', 'last_name' => $this->customer->get_billing_last_name() ?: '', 'phone_number' => $this->customer->get_billing_phone() ?: ''];
        $consent = $this->session_data->get_buyer_consent();
        if (null !== $consent) {
            $buyer['consent'] = $consent;
        }
        return $buyer;
    }
    public function get_fulfillment(): array
    {
        $destinations = [];
        $groups = [];
        if ($this->customer->get_shipping_address_1()) {
            $dest_id = $this->session_data->get_destination_id();
            $destinations[] = ['id' => $dest_id, 'address_country' => $this->customer->get_shipping_country(), 'postal_code' => $this->customer->get_shipping_postcode(), 'address_region' => $this->customer->get_shipping_state(), 'address_locality' => $this->customer->get_shipping_city(), 'street_address' => $this->customer->get_shipping_address_1()];
        }
        $packages = \WC()->shipping() ? \WC()->shipping()->get_packages() : [];
        $chosen = \WC()->session ? \WC()->session->get('chosen_shipping_methods', []) : [];
        if (!empty($packages)) {
            $options = [];
            $rates = $packages[0]['rates'] ?? [];
            foreach ($rates as $rate_id => $rate) {
                $options[] = ['id' => $rate_id, 'title' => $rate->get_label(), 'totals' => [['type' => 'total', 'amount' => (int) \round($rate->get_cost() * 100)]]];
            }
            $line_item_ids = $this->get_line_item_ids();
            $groups[] = ['id' => 'group_1', 'line_item_ids' => $line_item_ids, 'selected_option_id' => $chosen[0] ?? null, 'options' => $options];
        }
        $method = ['id' => 'method_1', 'type' => 'shipping', 'line_item_ids' => $this->get_line_item_ids()];
        if (!empty($destinations)) {
            $dest_id = $this->session_data->get_destination_id();
            $method['destinations'] = $destinations;
            $method['selected_destination_id'] = $dest_id;
        }
        if (!empty($groups)) {
            $method['groups'] = $groups;
        }
        return ['methods' => [$method]];
    }
    public function get_discounts(): array
    {
        $codes = [];
        $applied = [];
        foreach ($this->cart->get_coupons() as $wc_code => $coupon) {
            $codes[] = $wc_code;
            $discount_amount_cents = (int) \round($this->cart->get_coupon_discount_amount($wc_code) * 100);
            if ($discount_amount_cents > 0) {
                $applied[] = ['code' => $wc_code, 'title' => $this->coupon_formatter->from_coupon($coupon), 'amount' => $discount_amount_cents, 'allocations' => []];
            }
        }
        return ['codes' => $codes, 'applied' => $applied];
    }
    public function get_messages(): array
    {
        if (!$this->violations->has_violations()) {
            return [];
        }
        return $this->violations->to_array();
    }
    /**
     * @return array<string>
     */
    private function get_line_item_ids(): array
    {
        $line_item_ids = [];
        $index = 1;
        foreach ($this->cart->get_cart() as $cart_item) {
            $line_item_ids[] = 'li_' . $index;
            ++$index;
        }
        return $line_item_ids;
    }
}
