<?php

namespace KupShop\KupShopBundle\Context;

use KupShop\KupShopBundle\Util\Contexts;
use Symfony\Contracts\Service\Attribute\Required;

class VatContext implements ContextInterface
{
    private $activeId;

    protected $vatsCache;
    protected $defaultVatsCache;

    private bool $loaded = false;

    public const NO_VAT = 'NO_VAT';

    private $countryContext;

    /**
     * @required
     */
    public function setCountryContext(CountryContext $countryContext): void
    {
        $this->countryContext = $countryContext;
    }

    public static function getAdminVats(bool $forceAll = false): array
    {
        static $cache = [];

        if (($cache[$forceAll] ?? null) === null) {
            $vatsQb = sqlQueryBuilder()->select('v.id, v.descr, v.vat, JSON_VALUE(v.data, \'$.level\') level')->from('vats', 'v');
            if (findModule(\Modules::OSS_VATS)) {
                if ($forceAll) {
                    $vatsQb->addSelect('IF(v.id_country IS NULL, v.descr, CONCAT(v.id_country, " ", v.descr)) AS descr')
                        ->orderBy('v.id_country');
                } else {
                    $vatsQb->andWhere('v.automanaged=0');
                }
            }
            $vatsQb->addOrderBy('(v.is_default = "Y")', 'DESC')
                ->addOrderBy('v.vat', 'DESC');
            $cache[$forceAll] = sqlFetchAll($vatsQb, 'id');
        }

        return $cache[$forceAll];
    }

    public function translate($vat)
    {
        $active = $this->getActive();

        if ($active == self::NO_VAT) {
            return 0;
        } elseif ($active) {
            return $active[$vat] ?? $vat;
        }

        return $vat;
    }

    public function getDefault(?string $activeCountry = null)
    {
        if (!$this->vatsCache) {
            $this->loadVats();
        }

        if ($this->isOssActive()) {
            if (!$activeCountry) {
                $countryContext = Contexts::get(CountryContext::class);
                $activeCountry = $countryContext->getActiveId();
            }

            return $this->defaultVatsCache[$activeCountry] ?? $this->defaultVatsCache[null];
        }

        return $this->defaultVatsCache;
    }

    public function getVat($id)
    {
        if (!$this->vatsCache) {
            $this->loadVats();
        }

        return $this->vatsCache[$id];
    }

    protected function loadVats()
    {
        $ossVatsActive = $this->isOssActive();
        $allVats = sqlQueryBuilder()->select('*')->from('vats');

        foreach ($allVats->execute() as $vat) {
            $this->vatsCache[$vat['id']] = $vat;

            if ($vat['is_default'] == 'Y') {
                if ($ossVatsActive) {
                    $this->defaultVatsCache[$vat['id_country']] = &$this->vatsCache[$vat['id']];
                } elseif (($vat['id_country'] ?? null) === null) {
                    $this->defaultVatsCache = &$this->vatsCache[$vat['id']];
                }
            }
        }
    }

    public function isCountryOssActive(?string $activeCountry = null)
    {
        if (!$this->isOssActive()) {
            return false;
        }

        if (!$this->vatsCache) {
            $this->loadVats();
        }

        if (!$activeCountry) {
            $activeCountry = Contexts::get(CountryContext::class)->getActiveId();
        }

        $homeCountry = $this->getHomeCountry() ?? false;

        return $homeCountry != $activeCountry && !empty($this->defaultVatsCache[$activeCountry]);
    }

    public function getHomeCountry(): ?string
    {
        return \Settings::getDefault()['oss_vats']['homeCountry'] ?? null;
    }

    public function isOssActive()
    {
        $dbCfg = \Settings::getDefault();

        return findModule(\Modules::OSS_VATS) && ($dbCfg['oss_vats']['active'] ?? 'N') == 'Y';
    }

    public function activate(?string $id)
    {
        if (null === $id) {
            trigger_error('Passing $id=null into ContextInterface::activate is deprecated! Use ::clearCache instead.', \E_USER_DEPRECATED);
        }

        $this->loaded = true;
        $this->activeId = $id;

        return true;
    }

    public function getActiveId(): ?string
    {
        if (!$this->loaded) {
            $this->activeId = $this->loadActive();
        }

        return $this->activeId;
    }

    public function getActive()
    {
        $activeId = $this->getActiveId();

        return ($activeId === self::NO_VAT) ? $activeId : $this->getSupported()[$activeId] ?? null;
    }

    public function getSupported(): array
    {
        return [];
    }

    protected function loadActive(): ?string
    {
        $this->loaded = true;
        if ($this->isOssActive() && $this->isVatFree()) {
            return self::NO_VAT;
        }

        return null;
    }

    protected function isVatFree(): bool
    {
        // pokud je pro danou zemi aktivni OSS
        if ($this->isCountryOssActive($this->countryContext->getActiveId())) {
            $ossVats = \Settings::getDefault()->oss_vats ?? [];

            // pokud se jedna o B2B prodej (je vyplnene DIC)
            if (Contexts::get(UserContext::class)->isVatPayer()) {
                // pokud je platcem DPH pro danou zemi, tak nechceme aplikovat 0% DPH, takze vratime false
                if (in_array($this->countryContext->getActiveId(), $ossVats['vatPayerCountry'] ?? [])) {
                    return false;
                }

                return true;
            }
        }

        return !$this->isEUCountry();
    }

    public function clearCache(): void
    {
        $this->activeId = null;
        $this->loaded = false;
    }

    public function isValid(string $id): bool
    {
        return true;
    }

    public function isEUCountry(): bool
    {
        return in_array(Contexts::get(CountryContext::class)->getActiveId(), CountryContext::EU_COUNTRIES);
    }
}
