<?php
/**
 * Copyright since 2025 InPost S.A.
 *
 * For the full license information, please view the LICENSE file bundled with the module.
 *
 * @author InPost S.A.
 * @copyright since 2025 InPost S.A.
 * @license MIT
 */

declare(strict_types=1);

namespace InPost\International\Delivery\Util;

use InPost\International\Country;
use InPost\International\PrestaShop\ObjectModel\Repository\ObjectRepositoryInterface;
use InPost\International\PrestaShop\ShopConfigurationRepository;

if (!defined('_PS_VERSION_')) {
    exit;
}

class DeliveryCountryResolver
{
    /**
     * @var ObjectRepositoryInterface<\Country>
     */
    private $countryRepository;

    /**
     * @var ShopConfigurationRepository
     */
    private $configuration;

    /**
     * @param ObjectRepositoryInterface<\Country> $countryRepository
     */
    public function __construct(ObjectRepositoryInterface $countryRepository, ShopConfigurationRepository $configuration)
    {
        $this->countryRepository = $countryRepository;
        $this->configuration = $configuration;
    }

    public function resolve(\Cart $cart): ?Country
    {
        $country = $this->findCountryByDeliveryAddress($cart) ?? $this->getDefaultCountry();

        return Country::tryFrom($country->iso_code);
    }

    private function findCountryByDeliveryAddress(\Cart $cart): ?\Country
    {
        if (0 >= $addressId = (int) $cart->id_address_delivery) {
            return null;
        }

        /** @var \Address[] $addresses */
        $addresses = $cart->getAddressCollection();
        if (null === $address = $addresses[$addressId] ?? null) {
            throw new \RuntimeException('Address not found.');
        }

        return $this->countryRepository->find((int) $address->id_country);
    }

    private function getDefaultCountry(): \Country
    {
        $countryId = $this->configuration->getDefaultCountryId();

        if (null === $country = $this->countryRepository->find($countryId)) {
            throw new \RuntimeException('Default country does not exist.');
        }

        return $country;
    }
}
