<?php

declare(strict_types=1);

namespace CpCreation\VitiCore\Shop;

use CpCreation\VitiCore\Cart\Model\Cart;
use CpCreation\VitiCore\Shop\DTO\ShippingQuote;
use CpCreation\VitiCore\Shop\Model\DeliveryMethod;
use CpCreation\VitiCore\Shop\DTO\ShippingContext;

final class CartShippingEstimator
{
    public function __construct(
        private readonly ShippingContextFactory $shippingContextFactory,
        private readonly ShippingCalculatorInterface $shippingCalculator,
    ) {
    }

    public function estimate(?Cart $cart): ?ShippingQuote
    {
        if (null === $cart || $cart->getItems()->isEmpty()) {
            return null;
        }

        try {
            $context = $this->shippingContextFactory->createFromCart($cart);

            return $this->shippingCalculator->calculate($context);
        } catch (\Throwable) {
            return null;
        }
    }

    public function estimateStandard(?Cart $cart, ?ShippingContext $baseContext = null): ?ShippingQuote
    {
        if (null === $cart || $cart->getItems()->isEmpty()) {
            return null;
        }

        try {
            $context = ($baseContext ?? $this->shippingContextFactory->createFromCart($cart))
                ->withDeliveryMethod(null);

            return $this->shippingCalculator->calculate($context);
        } catch (\Throwable) {
            return null;
        }
    }

    public function estimateForMethod(
        ?Cart $cart,
        DeliveryMethod $deliveryMethod,
        ?ShippingContext $baseContext = null,
    ): ?ShippingQuote {
        if (null === $cart || $cart->getItems()->isEmpty()) {
            return null;
        }

        try {
            $context = ($baseContext ?? $this->shippingContextFactory->createFromCart($cart))
                ->withDeliveryMethod($deliveryMethod);

            return $this->shippingCalculator->calculate($context);
        } catch (\Throwable) {
            return null;
        }
    }
}
