<?php


namespace AutoAdmin\Bundle\Content\Cache;


use AutoAdmin\Bundle\Content\Entity\StaticText;
use AutoAdmin\Bundle\Content\Entity\StaticTextTranslation;
use AutoAdmin\Bundle\Content\Repository\StaticTextRepository;
use AutoAdmin\Bundle\Core\Cache\CacheAdapterConfigurator;
use AutoAdmin\Bundle\Core\Cache\CacheHandlerInterface;
use Doctrine\ORM\EntityManagerInterface;
use Exception;
use Symfony\Component\Cache\Adapter\FilesystemAdapter;
use Symfony\Component\Cache\CacheItem;
use Symfony\Component\HttpKernel\CacheWarmer\CacheWarmerInterface;

class StaticTranslationCacheHandler implements CacheHandlerInterface, CacheWarmerInterface
{
    const CACHE_KEY = 'translation';

    protected FilesystemAdapter $cache;

    public function __construct(
        protected EntityManagerInterface $em,
        CacheAdapterConfigurator $configurator,
    ) {
        $this->cache = $configurator->configure();
    }

    public function fetchValue(): array
    {
        /** @var StaticTextRepository $translationRepo */
        $translationRepo = $this->em->getRepository(StaticText::class);

        /** @var StaticText[] $translations */
        $translations = $translationRepo->findAllIndexed();

        $translationsArray = [];
        foreach ($translations as $translation) {
            /** @var StaticTextTranslation[] $translationsLocales */
            $translationsLocales = $translation->getTranslations();

            foreach ($translationsLocales as $translationsLocale) {
                $localeCode = $translationsLocale->getLocale()->getCode();
                $siteSlug = $translation->getSite()->getSlug();
                $trDomain = $translation->getDomain();
                $translationsArray[$siteSlug][$localeCode][$trDomain][$translation->getKey()]
                    = $translationsLocale->getValue();
            }
        }

        return $translationsArray;
    }

    public function getValue(bool $generateIfCacheMiss = true): ?array
    {
        if (!$this->cache->hasItem(self::CACHE_KEY) && $generateIfCacheMiss) {
            $this->saveValue();
        }

        /** @var CacheItem $cacheItem */
        $cacheItem = $this->cache->getItem(self::CACHE_KEY);
        $translationsArray = $cacheItem->get();

        return $translationsArray;
    }

    public function saveValue(): mixed
    {
        $value = $this->fetchValue();

        /** @var CacheItem $cacheItem */
        $cacheItem = $this->cache->getItem(self::CACHE_KEY);
        $cacheItem->set($value);
        $saved = $this->cache->save($cacheItem);

        return $value;
    }

    public function deleteValue(): mixed
    {
        return $this->cache->delete(self::CACHE_KEY);
    }

    public function warmUp(string $cacheDir)
    {
        if (!$this->isSchemaReady()) {
            return;
        }

        $this->saveValue();
    }

    public function isOptional(): bool
    {
        return true;
    }

    private function isSchemaReady(): bool
    {
        try {
            $schemaManager = $this->em->getConnection()->createSchemaManager();
            return $schemaManager->tablesExist(['static_text', 'static_text_translation']);
        } catch (Exception) {
            return false;
        }
    }
}
