<?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\Carrier\Configurator;

use InPost\International\Carrier\CarrierConfiguration;
use InPost\International\Carrier\Message\CreateCarrierCommand;
use InPost\International\PrestaShop\ObjectModel\Repository\CountryRepository;
use InPost\International\PrestaShop\ObjectModel\Repository\ObjectRepositoryInterface;
use InPost\International\PrestaShop\ObjectModel\Repository\TaxRulesGroupRepository;

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

final class TaxConfigurator implements CarrierConfiguratorInterface
{
    private const DEFAULT_TAX_RATE = 23.;
    private const DEFAULT_COUNTRY = 'PL';

    /**
     * @var CountryRepository
     */
    private $countryRepository;

    /**
     * @var TaxRulesGroupRepository
     */
    private $taxRulesGroupRepository;

    /**
     * @var string
     */
    private $countryCode;

    /**
     * @var float
     */
    private $taxRatePercent;

    /**
     * @var array{trg?: \TaxRulesGroup|null}
     */
    private $cache = [];

    /**
     * @param CountryRepository $countryRepository
     * @param TaxRulesGroupRepository $taxRulesGroupRepository
     * @param string $countryCode tax rules group search parameter - the country in which a given tax rate is applicable
     */
    public function __construct(ObjectRepositoryInterface $countryRepository, ObjectRepositoryInterface $taxRulesGroupRepository, float $taxRatePercent = self::DEFAULT_TAX_RATE, string $countryCode = self::DEFAULT_COUNTRY)
    {
        if (0. > $taxRatePercent) {
            throw new \DomainException('Tax rate cannot be negative.');
        }

        $this->countryRepository = $countryRepository;
        $this->taxRulesGroupRepository = $taxRulesGroupRepository;
        $this->countryCode = $countryCode;
        $this->taxRatePercent = $taxRatePercent;
    }

    public function configure(CarrierConfiguration $configuration, CreateCarrierCommand $command): void
    {
        if (null === $taxRulesGroup = $this->getTaxRulesGroup()) {
            return;
        }

        $configuration->setTaxRulesGroupId((int) $taxRulesGroup->id);
    }

    private function getTaxRulesGroup(): ?\TaxRulesGroup
    {
        if (array_key_exists('trg', $this->cache)) {
            return $this->cache['trg'];
        }

        if (null === $country = $this->countryRepository->findOneByIsoCode($this->countryCode)) {
            return $this->cache['trg'] = null;
        }

        return $this->cache['trg'] = $this->taxRulesGroupRepository->findOneByTaxRateAndCountryId($this->taxRatePercent, (int) $country->id);
    }
}
