<?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\CacheHandlerInterface;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Component\Cache\Adapter\FilesystemAdapter;
use Symfony\Component\Cache\CacheItem;
use Symfony\Component\HttpKernel\CacheWarmer\CacheWarmerInterface;

class StaticTranslationCacheHandler implements CacheHandlerInterface, CacheWarmerInterface
{
    const CACHE_NS = 'aa.cache';
    const CACHE_KEY = 'aa.cache.translation';

    protected EntityManagerInterface $em;
    protected string $projectDirectory;
    protected FilesystemAdapter $cache;

    public function __construct(EntityManagerInterface $em, string $projectDirectory)
    {
        $this->em = $em;
        $this->projectDirectory = $projectDirectory;
        $this->cache = new FilesystemAdapter(self::CACHE_NS, 0, $projectDirectory.'/var/cache/autoadmin');
    }

    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)
    {
        $this->saveValue();
    }

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

}
