<?php

declare(strict_types=1);

namespace External\HannahBundle\Util;

use KupShop\DropshipBundle\Util\DropshipmentUtil;
use KupShop\SynchronizationBundle\Util\SynchronizationConfiguration;

class Configuration
{
    public const SHOP_HANNAH = 'hannah';
    public const SHOP_RAFIKI = 'rafiki';
    public const SHOP_KEEN = 'keen';
    public const SHOP_ROCKPOINT = 'rockpoint';

    private array $staticConfiguration;

    public function __construct(
        private SynchronizationConfiguration $configuration,
        private ?DropshipmentUtil $dropshipmentUtil,
    ) {
    }

    public function setStaticConfiguration(array $staticConfiguration): void
    {
        $this->staticConfiguration = $staticConfiguration;
    }

    public function has(string $name): bool
    {
        return isset($this->staticConfiguration[$name]);
    }

    public function get(string $name, $default = null)
    {
        if (!$this->has($name)) {
            return $default;
        }

        return $this->staticConfiguration[$name];
    }

    public function getShopId(): ?string
    {
        return $this->get('shop');
    }

    public function getProcess(): ?string
    {
        return $this->get('sap.api')['process'] ?? null;
    }

    public function getProcessByLanguage(?string $language): ?string
    {
        $prefix = $this->getOrderConfig()['prefix'][$language] ?? false;
        if (empty($prefix)) {
            $prefix = $this->get('orders')['prefix'] ?? false;
        }

        return $prefix ?: $this->getProcess();
    }

    /** @deprecated Use `getProcessByLanguage` or `External\HannahBundle\Util\OrderUtil::getOrderProcess` */
    public function getOrderProcess(?string $language): ?string
    {
        return $this->getProcessByLanguage($language);
    }

    public function getLanguageByProcess(string $process): ?string
    {
        return array_flip($this->getOrderConfig()['prefix'] ?? [])[$process] ?? null;
    }

    public function getProcessByUser(\User $user): ?string
    {
        $language = $user->id_language;

        if (empty($language)) {
            return null;
        }

        $prefixes = $this->getOrderConfig()['prefix'] ?? [];

        return $prefixes[$language] ?? null;
    }

    public function getOrderErrorStatus(): int
    {
        if (empty($this->get('orders')['errorStatus'])) {
            throw new \RuntimeException('Error status is missing in configuration!');
        }

        return $this->get('orders')['errorStatus'];
    }

    public function getParameterIdByKey(string $key): ?int
    {
        static $map;

        if (!$map) {
            $map = $this->getParametersMap();
        }

        return !empty($map[$key]) ? (int) $map[$key] : null;
    }

    /**
     * ID parametru, ktere se pouzivaji v synchronizaci. Jelikoz kazdy shop to muze mit pod jinym ID, tak je
     * potreba to mit konfigurovatelny.
     */
    public function getParametersMap(): array
    {
        $defaultMap = [
            'labelSize' => 13,
            'labelShoesSize' => 13,
            'labelSkiShoesSize' => 19,
            'labelColor' => 15,

            'paramColor' => 55,
            'paramFilterColor' => 88,
            'paramGender' => 25,
        ];

        $map = $this->get('parameter.map');

        return array_merge($defaultMap, $map ?: []);
    }

    public function getMaileonConfig(): array
    {
        return $this->getDynamicConfiguration('maileon') ?: [];
    }

    public function getOrderConfig(): array
    {
        return $this->getDynamicConfiguration('order') ?: [];
    }

    public function getProductsConfig(): array
    {
        return $this->getDynamicConfiguration('products') ?: [];
    }

    public function getSAPSupportedProcesses(): array
    {
        if (!$this->configuration->has('ocSAPSupportedProcesses')) {
            $this->configuration->set('ocSAPSupportedProcesses', function () {
                $supported = array_values(array_filter($this->getOrderConfig()['prefix'] ?? []));

                foreach ($this->dropshipmentUtil?->getDropshipments() ?? [] as $dropshipment) {
                    if (!empty($dropshipment['data']['sap_order_prefix'])) {
                        $supported[] = $dropshipment['data']['sap_order_prefix'];
                    }

                    // load all prefixes configured in sap_order_prefix_by_country
                    foreach (array_filter($dropshipment['data']['sap_order_prefix_by_country'] ?? []) as $prefix) {
                        $supported[] = $prefix;
                    }

                    // load all prefixes configured in sap.prefix_by_filter
                    foreach ($dropshipment['data']['sap']['prefix_by_filter'] ?? [] as $item) {
                        if (empty($item['prefix'])) {
                            continue;
                        }

                        $supported[] = $item['prefix'];
                    }
                }

                return array_unique($supported);
            }, 600);
        }

        return $this->configuration->get('ocSAPSupportedProcesses');
    }

    public function refreshDynamicConfiguration(): void
    {
        $this->configuration->clear('ocConfig');
        $this->configuration->clear('ocSAPSupportedProcesses');
    }

    private function getDynamicConfiguration(string $key)
    {
        if (!$this->configuration->has('ocConfig')) {
            $this->configuration->set('ocConfig', function () {
                $dbcfg = \Settings::getDefault();

                return $dbcfg->loadValue('outdoorconcept');
            });
        }

        return $this->configuration->get('ocConfig')[$key] ?? null;
    }
}
