<?php

namespace Opencart\Extension\Alsendo\OrderDetails;

require_once(DIR_EXTENSION . 'alsendo/src/OrderDetails/CreateOrderDetails.php');
require_once(DIR_EXTENSION . 'alsendo/src/OrderDetails/Apaczka/ApaczkaCreateOrderDetails.php');
require_once(DIR_EXTENSION . 'alsendo/src/OrderDetails/Ecolet/EcoletCreateOrderDetails.php');
require_once(DIR_EXTENSION . 'alsendo/src/OrderDetails/Zaslat/ZaslatCreateOrderDetails.php');
require_once(DIR_EXTENSION . 'alsendo/src/DTO/Entity/AlsendoRegionEntity.php');

use Opencart\Extension\Alsendo\DTO\Entity\AlsendoRegionEntity;
use Opencart\Extension\Alsendo\OrderDetails\Apaczka\ApaczkaCreateOrderDetails;
use Opencart\Extension\Alsendo\OrderDetails\Ecolet\EcoletCreateOrderDetails;
use Opencart\Extension\Alsendo\OrderDetails\Zaslat\ZaslatCreateOrderDetails;
use Opencart\System\Engine\Registry;

class CreateOrderDetailsFactory
{
    private const REGION_TO_PROVIDER = [
        'poland' => 'apaczka',
        'romania' => 'ecolet',
        'czechia' => 'zaslat',
    ];

    private Registry $registry;
    private array $instances = [];

    public function __construct(Registry $registry)
    {
        $this->registry = $registry;
    }

    public function getCreateOrderDetailsForRegionCode(string $regionCode): CreateOrderDetails
    {
        $provider = self::REGION_TO_PROVIDER[strtolower($regionCode)] ?? 'apaczka';
        if (!isset($this->instances[$provider])) {
            $this->instances[$provider] = $this->create($provider);
        }
        return $this->instances[$provider];
    }

    public function getCreateOrderDetailsForRegion(AlsendoRegionEntity $region): CreateOrderDetails
    {
        return $this->getCreateOrderDetailsForRegionCode($region->code);
    }

    public static function getProviderFromRegionCode(string $regionCode): string
    {
        return self::REGION_TO_PROVIDER[strtolower($regionCode)] ?? 'apaczka';
    }

    private function create(string $provider): CreateOrderDetails
    {
        return match ($provider) {
            'zaslat' => new ZaslatCreateOrderDetails($this->registry),
            'ecolet' => new EcoletCreateOrderDetails($this->registry),
            'apaczka' => new ApaczkaCreateOrderDetails($this->registry),
            default => new ApaczkaCreateOrderDetails($this->registry),
        };
    }
}
