<?php

declare(strict_types=1);

namespace External\FlexiBeeBundle\Admin\Tabs;

use External\FlexiBeeBundle\Exception\FlexiBeeException;
use External\FlexiBeeBundle\Synchronizers\StoreSynchronizer;
use External\FlexiBeeBundle\Util\FlexiBeeApi;
use External\FlexiBeeBundle\Util\FlexiBeeConfiguration;
use External\FlexiBeeBundle\Util\FlexiBeeLocator;
use External\FlexiBeeBundle\Util\FlexiBeeUtil;
use KupShop\AdminBundle\Admin\WindowTab;
use KupShop\KupShopBundle\Email\OrderMessageEmail;

class FlexiBeeSettingsTab extends WindowTab
{
    protected $title = 'flapFlexiBeeSettings';
    protected $template = 'window/settings.flexibee.tpl';

    private FlexiBeeApi $api;
    private FlexiBeeUtil $util;
    private FlexiBeeLocator $locator;
    private FlexiBeeConfiguration $configuration;
    private OrderMessageEmail $orderMessageEmail;

    public function __construct(
        FlexiBeeApi $api,
        FlexiBeeUtil $util,
        FlexiBeeLocator $locator,
        FlexiBeeConfiguration $configuration,
        OrderMessageEmail $orderMessageEmail,
    ) {
        $this->api = $api;
        $this->util = $util;
        $this->locator = $locator;
        $this->configuration = $configuration;
        $this->orderMessageEmail = $orderMessageEmail;
    }

    public static function getTypes()
    {
        return [
            'settings' => 0,
        ];
    }

    public function getVars($smarty_tpl_vars)
    {
        $dbcfg = \Settings::getDefault();

        return [
            'flexibee' => $dbcfg->loadValue('flexibee') ?: [],
            'flexibeeData' => [
                'statuses' => $this->getFlexiBeeOrderStatuses(),
                'stores' => $this->getFlexiBeeStores(),
                'centrals' => $this->getFlexiBeeCentrals(),
                'synchronizers' => $this->getSynchronizers(),
                'pricelists' => $this->getFlexiBeePriceLists(),
            ],
            'orderMessages' => $this->orderMessageEmail->getOrderMessages(),
            'deliveries' => \DeliveryType::getDeliveries(true),
            'payments' => \DeliveryType::getPayments(true),
            'changesApiButton' => $this->isConfigValid() && !$this->isChangesApiAvailable(),
        ];
    }

    public function handleUpdate()
    {
        $this->configuration->refresh();
    }

    /**
     * Otestuje připojení k FlexiBee.
     */
    public function handleCheckConnection(): void
    {
        // kontroluju, zda je vyplněná konfigurace
        if (!$this->isConfigValid()) {
            $this->addHTMLError('<div class="alert alert-danger">Nejsou vyplněny všechny potřebné údaje!</div>');

            return;
        }

        // otestuju komunikaci s API
        if (!$this->api->isConnectionValid()) {
            $this->addHTMLError('<div class="alert alert-danger">Připojení k FlexiBee se nepodařilo! Překontrolujte zadané údaje.</div>');

            return;
        }

        $this->addHTMLError('<div class="alert alert-success">Připojení k FlexiBee proběhlo úspěšné.</div>');

        // zkontroluju, že je zapnuté ChangesAPI, které v synchronizaci používáme
        if (!$this->api->isChangesAPIEnabled()) {
            $this->addHTMLError('<div class="alert alert-danger"><strong>ChangesAPI</strong>, které je pro synchronizaci vyžadováno, není ve FlexiBee aktivní!</div>');
        }
    }

    public function handleChangesAPIEnable(): void
    {
        // tlacitko se zobrazi jen kdyz neni changesAPI aktivni
        $this->api->changesAPIEnable();
    }

    /**
     * Spustí synchronizaci skladů.
     */
    public function handleSynchronizeStores(): void
    {
        try {
            $this->util->synchronize([StoreSynchronizer::getType()]);
        } catch (FlexiBeeException $e) {
            $this->addHTMLError('Sklady se nepodařilo sesynchronizovat!');

            return;
        }

        $this->addHTMLError('Sklady úspěšně sesynchronizovány.');
    }

    public function getLabel()
    {
        return 'FlexiBee';
    }

    /**
     * Vrací seznam typů synchronizací.
     */
    protected function getSynchronizers(): array
    {
        $result = [];
        foreach ($this->locator->getTypes() as $type => $_) {
            // Sklad tady nezobrazuju, protoze ten synchronizuju zvlast podle nastaveni skladu
            if ($type === StoreSynchronizer::getType()) {
                continue;
            }

            $result[$type] = translate('synchronizer_'.$type, 'flexibee');
        }

        return $result;
    }

    /**
     * FlexiBee stavy. Mají je ve FlexiBee natvrdo, tak by to mělo stačit takhle vydefinovaný.
     */
    protected function getFlexiBeeOrderStatuses(): array
    {
        return [
            'stavDoklObch.pripraveno',
            'stavDoklObch.schvaleno',
            'stavDoklObch.castecneNaCeste',
            'stavDoklObch.naCeste',
            'stavDoklObch.castVydano',
            'stavDoklObch.vydano',
            'stavDoklObch.castHotovo',
            'stavDoklObch.hotovo',
        ];
    }

    /**
     * Vrací střediska ve FlexiBee.
     */
    protected function getFlexiBeeCentrals(): array
    {
        if ($centrals = getCache('flexiBeeCentrals')) {
            return $centrals;
        }

        $centrals = $this->api->isConnectionValid() ? $this->api->getCentrals() : [];

        $result = [];
        foreach ($centrals as $central) {
            $result[$central['id']] = $central['nazev'];
        }

        setCache('flexiBeeCentrals', $result, 3600);

        return $result;
    }

    /**
     * Vrací sklady ve FlexiBee.
     */
    protected function getFlexiBeeStores(): array
    {
        if ($stores = getCache('flexiBeeStores')) {
            return $stores;
        }

        $stores = $this->api->isConnectionValid() ? $this->api->getStores(true) : [];

        $result = [];
        foreach ($stores as $store) {
            $result[$store['id']] = $store['nazev'];
        }

        setCache('flexiBeeStores', $result, 3600);

        return $result;
    }

    protected function getFlexiBeePriceLists(): array
    {
        $pricelists = $this->api->isConnectionValid() ? $this->api->getPriceLists() : [];

        $result[0] = 'Všechny ceníky';
        foreach ($pricelists as $pricelist) {
            $result[$pricelist['id']] = $pricelist['nazev'];
        }

        return $result;
    }

    public function isConfigValid(): bool
    {
        try {
            $this->configuration->getAPIConfig();
        } catch (FlexiBeeException $e) {
            return false;
        }

        return true;
    }

    protected function isChangesApiAvailable(): bool
    {
        if (getCache('flexiBeeActiveAPI')) {
            return true;
        }

        if ($result = $this->api->isConnectionValid() && $this->api->isChangesAPIEnabled()) {
            setCache('flexiBeeActiveAPI', $result, 3600);

            return $result;
        }

        return false;
    }
}
