<?php

namespace Lc\SovBundle\Controller;

use Doctrine\ORM\EntityManagerInterface;
use EasyCorp\Bundle\EasyAdminBundle\Router\AdminUrlGenerator;
use Knp\Component\Pager\PaginatorInterface;
use Lc\SovBundle\Component\FileComponent;
use Lc\SovBundle\Container\ComponentContainer;
use Lc\SovBundle\Container\File\FileContainer;
use Lc\SovBundle\Container\Newsletter\NewsletterContainer;
use Lc\SovBundle\Container\Reminder\ReminderContainer;
use Lc\SovBundle\Container\Setting\SiteSettingContainer;
use Lc\SovBundle\Container\Site\NewsContainer;
use Lc\SovBundle\Container\Site\PageContainer;
use Lc\SovBundle\Container\Site\SiteContainer;
use Lc\SovBundle\Container\Ticket\TicketContainer;
use Lc\SovBundle\Container\Ticket\TicketMessageContainer;
use Lc\SovBundle\Container\User\GroupUserContainer;
use Lc\SovBundle\Container\User\UserContainer;
use Lc\SovBundle\Definition\ApplicationDefinition;
use Lc\SovBundle\Field\Filter\FilterManager;
use Lc\SovBundle\Generator\PdfGenerator;
use Lc\SovBundle\Repository\EntityRepository;
use Lc\SovBundle\Solver\Setting\SettingSolver;
use Lc\SovBundle\Translation\FlashBagTranslator;
use Lc\SovBundle\Translation\TranslatorAdmin;
use Mailjet\MailjetSwiftMailer\SwiftMailer\MailjetTransport;
use Psr\Log\LoggerInterface;
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\RequestStack;
use Symfony\Component\HttpFoundation\Session\SessionInterface;
use Symfony\Component\HttpKernel\KernelInterface;
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
use Symfony\Component\Security\Core\Security;
use Symfony\Component\Security\Http\RememberMe\TokenBasedRememberMeServices;
use Symfony\Contracts\Translation\TranslatorInterface;
use Twig\Environment;

trait ControllerTrait
{
    /*
  * Fonctions privées
  */
    protected function _setNoLimitMemoryAndTime()
    {
        ini_set('memory_limit', '-1');
        set_time_limit(0);
    }

    //TODO si vous avez une erreur avec le :array c'est qu'il faut passer à symfony 5.4.
    //Suivez la procédure suivante : https://symfony.com/doc/current/setup/unstable_versions.html#upgrading-your-project-to-an-unstable-symfony-version
    //En gros il faut changer tout les dépendances symfony/ qui sont en 5.3 par 5.4 dans composer.json
    public static function getSubscribedServices(): array
    {
        return array_merge(
                parent::getSubscribedServices(),
                ApplicationDefinition::getSubscribedContainerServices(),
                [
                        ApplicationDefinition::class => ApplicationDefinition::class,
                        Environment::class => Environment::class,
                        Security::class => Security::class,
                        EntityManagerInterface::class => EntityManagerInterface::class,
                        UrlGeneratorInterface::class => UrlGeneratorInterface::class,
                        SessionInterface::class => SessionInterface::class,
                        PaginatorInterface::class => PaginatorInterface::class,
                        RequestStack::class => RequestStack::class,
                        EventDispatcherInterface::class => EventDispatcherInterface::class,
                        LoggerInterface::class => LoggerInterface::class,
                        ParameterBagInterface::class => ParameterBagInterface::class,
                        TranslatorInterface::class => TranslatorInterface::class,
                        PdfGenerator::class => PdfGenerator::class,
                        TranslatorAdmin::class => TranslatorAdmin::class,
                        FilterManager::class => FilterManager::class,
                        FlashBagTranslator::class => FlashBagTranslator::class,
                        MailjetTransport::class => MailjetTransport::class,
                        AdminUrlGenerator::class => AdminUrlGenerator::class,
                        SettingSolver::class => SettingSolver::class,
                        ComponentContainer::class => ComponentContainer::class,
                        EntityRepository::class => EntityRepository::class,
                        FileComponent::class => FileComponent::class,
                        KernelInterface::class => KernelInterface::class
                ]
        );
    }

    public function addFlashTranslator(
            string $type,
            $translationKeyName,
            $translationEntityName = null,
            $translationParam = array()
    ): void {
        if ($translationEntityName === null && method_exists($this, 'getTranslationEntityName')) {
            $translationEntityName = $this->getTranslationEntityName();
        }


        $this->get(FlashBagTranslator::class)->add(
                $type,
                $translationKeyName,
                $translationEntityName,
                $translationParam
        );
    }

    public function isInstanceOf(string $interfaceName): bool
    {
        return in_array($interfaceName, class_implements($this->getEntityFqcn()));
    }

    public function generateEaUrl(
            string $controller = null,
            string $action = null,
            int $entityId = null,
            array $extraParam = array()
    ): string {
        $adminUrlGenerator = $this->get(AdminUrlGenerator::class);
        if ($controller) {
            $adminUrlGenerator->setController($controller);
        }
        if ($action) {
            $adminUrlGenerator->setAction($action);
        }
        if ($entityId) {
            $adminUrlGenerator->setEntityId($entityId);
        }
        if ($extraParam) {
            foreach ($extraParam as $key => $value) {
                $adminUrlGenerator->set($key, $value);
            }
        }
        return $adminUrlGenerator->generateUrl();
    }

    public function getReferer(Request $request): ?string
    {
        return $request->headers->get('referer');
    }

    public function getTemplating(): Environment
    {
        return $this->get(Environment::class);
    }

    public function getApplicationDefinition(): ApplicationDefinition
    {
        return $this->get(ApplicationDefinition::class);
    }

    public function getEntityManager(): EntityManagerInterface
    {
        return $this->get(EntityManagerInterface::class);
    }

    public function getRouter(): UrlGeneratorInterface
    {
        return $this->get(UrlGeneratorInterface::class);
    }

    public function getSession(): SessionInterface
    {
        return $this->get(SessionInterface::class);
    }

    public function getSecurity(): Security
    {
        return $this->get(Security::class);
    }

    public function getPaginator(): PaginatorInterface
    {
        return $this->get(PaginatorInterface::class);
    }

    public function getRequestStack(): RequestStack
    {
        return $this->get(RequestStack::class);
    }

    public function getEventDispatcher(): EventDispatcherInterface
    {
        return $this->get(EventDispatcherInterface::class);
    }

    public function getParameterBag(): ParameterBagInterface
    {
        return $this->get(ParameterBagInterface::class);
    }

    public function getTranslator(): TranslatorInterface
    {
        return $this->get(TranslatorInterface::class);
    }

    public function getPdfGenerator(): PdfGenerator
    {
        return $this->get(PdfGenerator::class);
    }

    public function getTranslatorAdmin(): TranslatorAdmin
    {
        return $this->get(TranslatorAdmin::class);
    }

    public function getLogger(): LoggerInterface
    {
        return $this->get(LoggerInterface::class);
    }

    public function getMailjetTransport(): MailjetTransport
    {
        return $this->get(MailjetTransport::class);
    }

    public function getAdminUrlGenerator(): AdminUrlGenerator
    {
        return $this->get(AdminUrlGenerator::class);
    }

    public function getUrlGenerator(): UrlGeneratorInterface
    {
        return $this->get(UrlGeneratorInterface::class);
    }

    public function getKernel(): KernelInterface
    {
        return $this->get(KernelInterface::class);
    }

    public function getSettingSolver(): SettingSolver
    {
        return $this->get(SettingSolver::class);
    }

    public function getSettingValue($entity, $settingName)
    {
        return $this->getSettingSolver()->getSettingValue($entity, $settingName);
    }

    public function getComponentContainer(): ComponentContainer
    {
        return $this->get(ComponentContainer::class);
    }

    public function getFileContainer(): FileContainer
    {
        return $this->get(FileContainer::class);
    }

    public function getNewsletterContainer(): NewsletterContainer
    {
        return $this->get(NewsletterContainer::class);
    }

    public function getReminderContainer(): ReminderContainer
    {
        return $this->get(ReminderContainer::class);
    }

    public function getNewsContainer(): NewsContainer
    {
        return $this->get(NewsContainer::class);
    }

    public function getPageContainer(): PageContainer
    {
        return $this->get(PageContainer::class);
    }

    public function getSiteContainer(): SiteContainer
    {
        return $this->get(SiteContainer::class);
    }

    public function getTicketContainer(): TicketContainer
    {
        return $this->get(TicketContainer::class);
    }

    public function getTicketMessageContainer(): TicketMessageContainer
    {
        return $this->get(TicketMessageContainer::class);
    }

    public function getGroupUserContainer(): GroupUserContainer
    {
        return $this->get(GroupUserContainer::class);
    }

    public function getUserContainer(): UserContainer
    {
        return $this->get(UserContainer::class);
    }

    public function getSiteSettingContainer(): SiteSettingContainer
    {
        return $this->get(SiteSettingContainer::class);
    }

    public function setNoMemoryAndTimeLimit(): void
    {
        ini_set('memory_limit', '-1');
        set_time_limit(0);
    }

}
