<?php

namespace KupShop\KupShopBundle\Context;

use KupShop\I18nBundle\Entity\Country;
use KupShop\KupShopBundle\Config;
use KupShop\KupShopBundle\Util\Functional\Mapping;

class CountryContext implements ContextInterface
{
    /** @var string */
    protected $activeId;

    /** @var Country[] */
    protected $supported;

    public const EU_COUNTRIES = [
        'AT', 'BE', 'BG', 'CY', 'CZ', 'DE', 'DK',
        'EE', 'ES', 'FI', 'FR', 'GR', 'HU', 'HR',
        'IE', 'IT', 'LT', 'LU', 'LV', 'MT', 'NL',
        'PL', 'PT', 'RO', 'SE', 'SI', 'SK',
    ];

    /**
     * @var array of pairs country ID => Country object
     */
    protected $countries;

    public function __construct()
    {
    }

    public function remember(string $id)
    {
    }

    public function activate(string $id)
    {
        $this->activeId = $id;

        return true;
    }

    /**
     * @return Country
     */
    public function getActive()
    {
        $active = $this->getActiveId();

        return $this->getAll()[$active];
    }

    /**
     * @return Country[]
     */
    public function getSupported()
    {
        if (!$this->supported) {
            $this->supported = $this->getAll();
        }

        return $this->supported;
    }

    /**
     * @return bool
     */
    protected function validate($id)
    {
        if (isAdministration()) {
            return array_key_exists($id, $this->getAll());
        }

        return array_key_exists($id, $this->getSupported());
    }

    /**
     * @return Country[]
     */
    public function getAll()
    {
        if (!isset($this->countries)) {
            $countries = Config::get()->getFromArray('Order')['Countries'];

            $position = 0;
            $this->countries = Mapping::withKeys($countries, function ($code, $country) use (&$position) {
                return (new Country())->setId($code)->setName($country)->setPosition($position++);
            });
        }

        return $this->countries;
    }

    protected function loadActive()
    {
        return key($this->getSupported());
    }

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

        return $this->activeId;
    }

    public function getDefaultId()
    {
        // select country with the lowest position
        $countries = $this->getSupported();
        uasort($countries, function (Country $a, Country $b) {
            return $a->getPosition() - $b->getPosition();
        });

        return reset($countries)->getId();
    }

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

    public function isValid(string $id): bool
    {
        return $this->validate($id);
    }
}
