<?php

namespace AutoAdmin\Bundle\Content\Twig\Extension;

use AutoAdmin\Bundle\Content\Model\SiteConfig;
use AutoAdmin\Bundle\Content\Model\TranslatableInterface;
use AutoAdmin\Bundle\Content\Provider\TranslationProvider;
use AutoAdmin\Bundle\Content\Site\SiteContextHelper;
use AutoAdmin\Bundle\Content\Translation\EntityTranslator;
use AutoAdmin\Bundle\Content\Translation\LocaleSwitchHelper;
use Doctrine\Common\Collections\ArrayCollection;
use Twig\Extension\AbstractExtension;
use Twig\TwigFilter;
use Twig\TwigFunction;

class TranslationExtension extends AbstractExtension
{
    public function __construct(
        protected EntityTranslator $entityTranslator,
        protected TranslationProvider $translationProvider,
        protected SiteContextHelper $contextHelper,
        protected LocaleSwitchHelper $localeSwitchHelper,
    ) {
    }

    /**
     * @return TwigFilter[]
     */
    public function getFilters(): array
    {
        return [
            // return entity translation for field and locale: aa_content_translate(content, 'title', 'en')
            new TwigFilter('aa_content_translate', [$this, 'translate']),
            // return static trans: aa_trans('key')
            // fallback on symfony |trans system if nothing is found
            new TwigFilter('aa_trans', [$this, 'staticTranslate'], ['is_safe' => ['html']]),

        ];
    }

    public function getFunctions(): array
    {
        return [
            // lock/unlock static text locale from template
            new TwigFunction('aa_trans_lock', [$this, 'staticTranslateLock']),
            new TwigFunction('aa_trans_unlock', [$this, 'staticTranslateUnlock']),
            new TwigFunction('aa_site_locales', [$this, 'getSiteLocales']),
        ];
    }

    public function translate(TranslatableInterface $translatable, $field, $locale = null): ?string
    {
        return $this->entityTranslator->translate($translatable, $field, $locale);
    }

    public function staticTranslate(string $key, array $options = [], string $domain = 'messages', $locale = null): ?string
    {
        return $this->translationProvider->translate($key, $domain, $options, $locale);
    }

    public function staticTranslateLock(mixed $locale): void
    {
        $this->translationProvider->lockLocale($locale);
    }

    public function staticTranslateUnlock(): void
    {
        $this->translationProvider->unlockLocale();
    }

    /**
     * @param bool $checkDomain
     * @return array
     * @deprecated use {@see getSiteLocales}
     */
    public function getSiteLocalesLegacy(bool $checkDomain = true): array
    {
        $currentLocale = $this->contextHelper->getLocale();
        /** @var ArrayCollection $locales */
        $siteConfigs = $this->contextHelper->getCurrentContextSiteConfigs();
        $siteConfigs = array_filter($siteConfigs, function (SiteConfig $sc) use ($currentLocale) {
            return $sc->getLocale() !== $currentLocale;
        });
        $locales = array_map(fn(SiteConfig $sc) => $sc->getLocale(), $siteConfigs);

        return [
            'current' => $currentLocale,
            'alternates' => $locales,
        ];
    }

    public function getSiteLocales(): array
    {
        $localeSwitch = $this->localeSwitchHelper->buildCurrentSwitch();
        $localeSwitchers = $this->localeSwitchHelper->buildAlternateSwitches();

        return [
            // old format
            ...$this->getSiteLocalesLegacy(),
            // new format using site-configs
            'locale_current_switch' => $localeSwitch,
            'locale_alternate_switches' => $localeSwitchers,
        ];
    }
}
