<?php

namespace Lc\SovBundle\Twig;

use App\Controller\Ticket\TicketAdminController;
use App\Repository\ReminderRepository;
use Doctrine\ORM\EntityManagerInterface;
use EasyCorp\Bundle\EasyAdminBundle\Router\AdminUrlGenerator;
use Lc\SovBundle\Component\DateComponent;
use Lc\SovBundle\Component\FileComponent;
use Lc\SovBundle\Component\MetaComponent;
use Lc\SovBundle\Component\StringComponent;
use Lc\SovBundle\Doctrine\EntityInterface;
use Lc\SovBundle\Form\Newsletter\NewsletterType;
use Lc\SovBundle\Model\File\FileInterface;
use Lc\SovBundle\Repository\Reminder\ReminderStore;
use Lc\SovBundle\Translation\TranslatorAdmin;
use Liip\ImagineBundle\Imagine\Cache\CacheManager;
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;
use Symfony\Component\Form\FormFactoryInterface;
use Symfony\Component\HttpFoundation\RequestStack;
use Symfony\Component\HttpKernel\KernelInterface;
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
use Symfony\Component\Security\Core\Security;
use Symfony\Contracts\Translation\TranslatorInterface;
use Twig\Extension\AbstractExtension;
use Twig\TwigFilter;
use Twig\TwigFunction;

class TwigExtension extends AbstractExtension
{
    protected EntityManagerInterface $em;
    protected KernelInterface $kernel;
    protected ParameterBagInterface $parameterBag;
    protected CacheManager $cacheManager;
    protected RequestStack $requestStack;
    protected UrlGeneratorInterface $router;
    protected TranslatorInterface $translator;
    protected TranslatorAdmin $translatorAdmin;
    protected ReminderStore $reminderStore;
    protected Security $security;
    protected FormFactoryInterface $formFactory;
    protected StringComponent $stringComponent;
    protected MetaComponent $metaComponent;
    protected DateComponent $dateComponent;
    protected FileComponent $fileComponent;
    protected AdminUrlGenerator $adminUrlGenerator;

    public function __construct(
        KernelInterface $kernel,
        ParameterBagInterface $parameterBag,
        CacheManager $cacheManager,
        EntityManagerInterface $entityManager,
        RequestStack $requestStack,
        UrlGeneratorInterface $router,
        TranslatorInterface $translator,
        TranslatorAdmin $translatorAdmin,
        ReminderStore $reminderStore,
        Security $security,
        FormFactoryInterface $formFactory,
        StringComponent $stringComponent,
        MetaComponent $metaComponent,
        DateComponent $dateComponent,
        FileComponent $fileComponent,
        AdminUrlGenerator $adminUrlGenerator
    ) {
        $this->kernel = $kernel;
        $this->parameterBag = $parameterBag;
        $this->cacheManager = $cacheManager;
        $this->em = $entityManager;
        $this->requestStack = $requestStack;
        $this->router = $router;
        $this->translator = $translator;
        $this->translatorAdmin = $translatorAdmin;
        $this->reminderStore = $reminderStore;
        $this->security = $security;
        $this->formFactory = $formFactory;
        $this->stringComponent = $stringComponent;
        $this->metaComponent = $metaComponent;
        $this->dateComponent = $dateComponent;
        $this->fileComponent = $fileComponent;
        $this->adminUrlGenerator = $adminUrlGenerator;
    }

    public function getFunctions()
    {
        return [
            new TwigFunction('sov_liip', [$this, 'liip']),
            new TwigFunction('liip', [$this, 'liip']),
            new TwigFunction('sov_get_by_devalias', [$this, 'getByDevAlias']),
            new TwigFunction('sov_parameter', [$this, 'getParameter']),
            new TwigFunction('sov_homepage_route', [$this, 'getHomepageRoute']),
            new TwigFunction('lc_format_price', [$this, 'formatPrice']),
            new TwigFunction('die', [$this, 'die']),
            new TwigFunction('get_form_newsletter', [$this, 'getFormNewsletter']),
            new TwigFunction('sov_limit_text', [$this, 'limitText']),
            new TwigFunction('day_by_number', [$this, 'getDayByNumber']),
            new TwigFunction('user_current', [$this, 'getUserCurrent']),
            new TwigFunction('ea_url_short', [$this, 'generateEaUrl']),
            new TwigFunction('is_instance_of', [$this, 'isInstanceOf']),
            new TwigFunction('logo_admin', [$this, 'getLogoAdmin']),
            new TwigFunction('asset_url', [$this, 'getAssetUrl']),
        ];
    }

    public function die()
    {
        die();
    }

    public function getFilters()
    {
        return [
            new TwigFilter('uc_first', [$this, 'ucFirst']),
            new TwigFilter('format_price', [$this, 'formatPrice']),
            new TwigFilter('sov_cache', [$this, 'sovCache']),
            new TwigFilter('slugify', [$this, 'slugify']),
            new TwigFilter('md5', [$this, 'md5']),
            new TwigFilter('rot13', [$this, 'rot13']),
        ];
    }

    public function getAssetUrl($path)
    {
        return $this->fileComponent->getAssetUrl($path);
    }

    public function rot13(string $string): string
    {
        return str_rot13($string);
    }

    public function isInstanceOf(EntityInterface $entity, string $interfaceName)
    {
        $reflection = new \ReflectionClass($entity);
        $interfaceNameArray = $reflection->getInterfaceNames();

        foreach ($interfaceNameArray as $interfaceNameEntity) {
            if (strpos($interfaceNameEntity, $interfaceName) !== false) {
                return true;
            }
        }

        return false;
    }

    public function sovCache($file)
    {
        $cacheTime = filemtime($this->kernel->getProjectDir() . '/public' . $file);
        if ($cacheTime) {
            return $file . '?c=' . $cacheTime;
        } else {
            return $file . "?c=0";
        }
    }

    public function formatPrice($price, $unbreakableSpace = true)
    {
        $price = number_format($price, 2, ',', ' ');
        $price .= $unbreakableSpace ? '&nbsp;' : ' ';
        $price .= '€';

        return $price;
    }

    public function ucFirst($string)
    {
        return ucfirst($string);
    }

    public function liip($path, $thumb = 'tile', $default = 'default.jpg')
    {
        return $this->fileComponent->liip($path, $thumb, $default);
    }

    public function getFileManagerFolder()
    {
        return $this->parameterBag->get('app.path_uploads');
    }

    public function getHomepageRoute()
    {
        return $this->parameterBag->get('lc_sov.homepage_route');
    }

    public function getParameter($name)
    {
        return $this->parameterBag->get($name);
    }

    public function getFormNewsletter()
    {
        $form = $this->formFactory->create(NewsletterType::class);
        return $form->createView();
    }

    public function limitText(string $text, int $limit)
    {
        return $this->stringComponent->limitText($text, $limit);
    }

    public function getDayByNumber($day): string
    {
        return $this->dateComponent->getDayByNumber($day);
    }

    public function slugify($string)
    {
        return $this->stringComponent->slugify($string);
    }

    public function getUserCurrent()
    {
        return $this->security->getUser();
    }

    public function generateEaUrl(
        string $controller = null,
        string $action = null,
        int $entityId = null,
        array $extraParam = array()
    ): string {
        $adminUrlGenerator = $this->adminUrlGenerator;

        if ($controller) {
            $adminUrlGenerator->setController($controller);
        }
        if ($action) {
            $adminUrlGenerator->setAction($action);
        }

        $adminUrlGenerator->setEntityId($entityId);

        if ($extraParam) {
            foreach ($extraParam as $key => $value) {
                $adminUrlGenerator->set($key, $value);
            }
        }
        return $adminUrlGenerator->generateUrl();
    }

    public function md5(string $text): string
    {
        return md5($text);
    }

    public function getLogoAdmin(): string
    {
        $image = $this->getParameter('app.admin.logo_sidebar');
        if(!$image) {
            $image = $this->getParameter('app.admin.logo');
        }

        return '<img class="logo-admin" src="assets/img/' . $image . '" >';
    }
}
