<?php

namespace Opencart\Extension\Alsendo\Services;

require_once(DIR_EXTENSION . 'alsendo/wrapper/src/Map/MapConfig.php');
require_once(DIR_EXTENSION . 'alsendo/wrapper/src/Map/MapRegion.php');
require_once(DIR_EXTENSION . 'alsendo/wrapper/src/Map/MapService.php');

use Alsendo\AlsendoWrapper\Map\MapConfig;
use Alsendo\AlsendoWrapper\Map\MapRegion;
use Alsendo\AlsendoWrapper\Map\MapService;

class MapWidgetService
{
    private const REGION_MAP = [
        'poland' => MapRegion::PL,
        'czechia' => MapRegion::CZ,
        'romania' => MapRegion::RO,
    ];

    public const OPERATOR_ALIAS_MAP = [
        'pl' => [
            'inpost' => 'INPOST',
            'dhl' => 'DHL',
            'dhl_parcel' => 'DHL',
            'dhl_int' => 'DHL',
            'poczta' => 'POCZTA',
            'poczta_polska' => 'POCZTA',
            'dpd' => 'DPD',
            'ups' => 'UPS',
            'gls' => 'GLS',
            'ruch' => 'RUCH',
            'orlen' => 'RUCH',
            'orlen_paczka' => 'RUCH',
            'pwr' => 'RUCH',
            'fedex' => 'FEDEX',
            'inpost_international' => 'INPOST_INTERNATIONAL',
            'pp_packeta' => 'PACKETA',
        ],
        'cz' => [
            'ppl' => 'PPL',
            'packeta' => 'PACKETA',
            'zasilkovna' => 'PACKETA',
            'balikovna' => 'BALIKOVNA',
            'dpd' => 'DPD',
            'gls' => 'GLS',
            'wedo' => 'ONE_DELIVERY'
        ],
        'ro' => [
            'dpd' => 'DPD',
            'sameday' => 'SAMEDAY',
            'fan_courier' => 'FAN_COURIER',
            'cargus' => 'CARGUS',
            'gls' => 'GLS',
        ],
    ];

    private MapService $mapService;
    private string $wrapperRegion;

    public function __construct(string $pluginRegionCode)
    {
        $this->mapService = new MapService();
        $this->wrapperRegion = self::REGION_MAP[$pluginRegionCode] ?? MapRegion::PL;
    }

    public function getWrapperRegion(): string
    {
        return $this->wrapperRegion;
    }

    public function getAssetUrls(): array
    {
        $config = new MapConfig();
        $config->region = $this->wrapperRegion;
        $config->callbackFunctionName = '_';
        return $this->mapService->getAssetUrls($config);
    }

    public function getClientConfig(): array
    {
        $config = new MapConfig();
        $config->region = $this->wrapperRegion;
        $config->callbackFunctionName = '_';
        $config = $this->mapService->applyRegionDefaults($config);

        return [
            'region' => $this->wrapperRegion,
            'language' => $config->language,
            'countryCodes' => $config->countryCodes,
            'operators' => $config->operators,
            'operatorMarkers' => $config->operatorMarkers,
            'codeSearch' => $config->codeSearch,
            'testMode' => $config->testMode,
            'operatorAliases' => self::OPERATOR_ALIAS_MAP[$this->wrapperRegion] ?? [],
        ];
    }

    public function resolveOperator(string $operatorAlias): ?string
    {
        $aliases = self::OPERATOR_ALIAS_MAP[$this->wrapperRegion] ?? [];
        $key = strtolower($operatorAlias);

        if (isset($aliases[$key])) {
            return $aliases[$key];
        }

        $upper = strtoupper($operatorAlias);
        $regionOperators = MapRegion::DEFAULT_OPERATORS[$this->wrapperRegion] ?? [];

        if (in_array($upper, $regionOperators, true)) {
            return $upper;
        }

        return null;
    }

    public function hasValidMapOperator(string $operatorAlias): bool
    {
        return $this->resolveOperator($operatorAlias) !== null;
    }

    public static function getOperatorKeyFromValue(string $operatorValue): ?string
    {
        $operatorUpper = strtoupper(trim($operatorValue));
        if ($operatorUpper === '') {
            return null;
        }
        foreach (self::OPERATOR_ALIAS_MAP as $regionOperators) {
            foreach ($regionOperators as $key => $value) {
                if (strtoupper((string) $value) === $operatorUpper) {
                    return $key;
                }
            }
        }
        return null;
    }
}
