<?php

namespace AutoAdmin\Bundle\Seo\Cache;

use AutoAdmin\Bundle\Content\Site\SiteContextHelper;
use AutoAdmin\Bundle\Core\Cache\CacheAdapterConfigurator;
use AutoAdmin\Bundle\Seo\Sitemap\SitemapRenderer;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Component\Cache\Adapter\FilesystemAdapter;
use Symfony\Component\Cache\CacheItem;
use Symfony\Component\HttpKernel\CacheWarmer\CacheWarmerInterface;

class SitemapCacheHandler implements CacheWarmerInterface
{
    const CACHE_KEY = 'sitemap';

    protected FilesystemAdapter $cache;

    public function __construct(
        protected EntityManagerInterface $em,
        protected SitemapRenderer $renderer,
        protected SiteContextHelper $contextHelper,
        CacheAdapterConfigurator $configurator,
    ) {
        $this->cache = $configurator->configure([
            'lifetime' => CacheAdapterConfigurator::LIFE_TIME_24H,
        ]);
    }

    public function buildKey()
    {
        $this->contextHelper->validateCurrentContext(true);

        return $this::CACHE_KEY
            .'.'.$this->contextHelper->getSite()->getSlug()
            .'.locale_'.$this->contextHelper->getLocale()->getCode();
    }

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

        /** @var CacheItem $cacheItem */
        $cacheItem = $this->cache->getItem($this->buildKey());
        $cacheItem->set($value);
        $this->cache->save($cacheItem);

        return $value;
    }

    public function saveAllSiteValues(): void
    {
        $previous = $this->contextHelper->getCurrentContext();

        foreach ($this->contextHelper->getAllSiteConfigs() as $siteConfig) {
            $this->contextHelper->loadSiteAndLocale($siteConfig->getSite(), $siteConfig->getLocale());

            $value = $this->fetchValue();

            /** @var CacheItem $cacheItem */
            $cacheItem = $this->cache->getItem($this->buildKey());
            $cacheItem->set($value);

            $this->cache->save($cacheItem);
        }

        if ($previous) {
            $this->contextHelper->loadContext($previous);
        }
    }

    public function getValue(bool $generateIfCacheMiss = true): mixed
    {
        $cacheItem = $this->cache->getItem($key = $this->buildKey());

        if (empty($cacheItem->get()) && $generateIfCacheMiss) {
            $this->saveSiteValue();
            $cacheItem = $this->cache->getItem($key);
        }

        return $cacheItem->get() ?? null;
    }

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

    public function fetchValue(): mixed
    {
        $this->contextHelper->validateCurrentContext(true);

        $sitemaps = [];
        $domainStr = $this->contextHelper->getDomain()->getDomain();

        foreach ($this->renderer->getSections() as $section) {
            $output = $this->renderer->render('https://'.$domainStr, $section);
            $sitemaps[$section] = $output;
        }

        return $sitemaps;
    }

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

    public function warmUp(string $cacheDir)
    {
        $this->saveAllSiteValues();
    }
}