<?php

namespace App\Controller\Admin;

use App\Entity\Revendeur;
use App\Repository\RevendeurRepository;
use App\Service\MailerService;
use App\Service\MeilisearchService;
use App\Service\UserManagementService;
use Doctrine\ORM\EntityManagerInterface;
use Dompdf\Dompdf;
use Psr\Log\LoggerInterface;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\DependencyInjection\Attribute\Autowire;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Attribute\Route;
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
use Symfony\Component\Security\Http\Attribute\IsGranted;
use Twig\Environment;

#[Route('/admin/revendeurs', name: 'app_admin_revendeurs_')]
#[IsGranted('ROLE_EMPLOYE')]
class RevendeursController extends AbstractController
{
    private const LABEL_REVENDEUR = 'Revendeur ';

    public function __construct(
        private LoggerInterface $logger,
    ) {
    }

    #[Route('', name: 'index')]
    public function index(RevendeurRepository $revendeurRepository): Response
    {
        $revendeurs = $revendeurRepository->findBy([], ['createdAt' => 'DESC']);

        return $this->render('admin/revendeurs/index.html.twig', [
            'revendeurs' => $revendeurs,
        ]);
    }

    #[Route('/create', name: 'create')]
    public function create(
        Request $request,
        RevendeurRepository $revendeurRepository,
        EntityManagerInterface $em,
        MailerService $mailer,
        Environment $twig,
        UserManagementService $userService,
    ): Response {
        if ('GET' === $request->getMethod()) {
            return $this->render('admin/revendeurs/create.html.twig');
        }

        $firstName = trim($request->request->getString('firstName'));
        $lastName = trim($request->request->getString('lastName'));
        $email = trim($request->request->getString('email'));
        $raisonSociale = trim($request->request->getString('raisonSociale'));
        $siret = trim($request->request->getString('siret'));
        $phone = trim($request->request->getString('phone'));
        $isUseStripe = $request->request->getBoolean('isUseStripe');

        try {
            $user = $userService->createBaseUser($email, $firstName, $lastName, ['ROLE_REVENDEUR']);

            // Creer le revendeur
            $code = $revendeurRepository->generateUniqueCode();
            $revendeur = new Revendeur($user, $code);
            $revendeur->setRaisonSociale('' !== $raisonSociale ? $raisonSociale : null);
            $revendeur->setSiret('' !== $siret ? $siret : null);
            $revendeur->setEmail($email);
            $revendeur->setPhone('' !== $phone ? $phone : null);
            $revendeur->setAddress(trim($request->request->getString('address')) ?: null);
            $revendeur->setZipCode(trim($request->request->getString('zipCode')) ?: null);
            $revendeur->setCity(trim($request->request->getString('city')) ?: null);
            $revendeur->setIsUseStripe($isUseStripe);

            $em->persist($revendeur);
            $em->flush();

            // Envoyer le mail
            $setPasswordUrl = $this->generateUrl('app_set_password', [
                'token' => $user->getTempPassword(),
            ], UrlGeneratorInterface::ABSOLUTE_URL);

            $mailer->sendEmail(
                $email,
                'CRM E-Cosplay - Bienvenue dans l\'espace revendeur',
                $twig->render('emails/revendeur_created.html.twig', [
                    'firstName' => $firstName,
                    'lastName' => $lastName,
                    'email' => $email,
                    'codeRevendeur' => $code,
                    'setPasswordUrl' => $setPasswordUrl,
                ]),
                null,
                null,
                false,
            );

            $this->addFlash('success', self::LABEL_REVENDEUR.$firstName.' '.$lastName.' cree (Code: '.$code.').');
        } catch (\InvalidArgumentException $e) {
            $this->addFlash('error', $e->getMessage());
        } catch (\Throwable $e) {
            $this->addFlash('error', 'Erreur lors de la creation : '.$e->getMessage());
        }

        return $this->redirectToRoute('app_admin_revendeurs_index');
    }

    #[Route('/search', name: 'search', methods: ['GET'])]
    public function search(Request $request, MeilisearchService $meilisearch): \Symfony\Component\HttpFoundation\JsonResponse
    {
        $query = trim($request->query->getString('q'));

        if ('' === $query) {
            return new \Symfony\Component\HttpFoundation\JsonResponse([]);
        }

        return new \Symfony\Component\HttpFoundation\JsonResponse($meilisearch->searchRevendeurs($query));
    }

    #[Route('/{id}/toggle', name: 'toggle', methods: ['POST'])]
    public function toggle(Revendeur $revendeur, EntityManagerInterface $em): Response
    {
        $revendeur->setIsActive(!$revendeur->isActive());
        $revendeur->setUpdatedAt(new \DateTimeImmutable());
        $em->flush();

        $this->addFlash('success', self::LABEL_REVENDEUR.$revendeur->getCodeRevendeur().' '.($revendeur->isActive() ? 'active' : 'desactive').'.');

        return $this->redirectToRoute('app_admin_revendeurs_index');
    }

    #[Route('/{id}/edit', name: 'edit')]
    public function edit(Revendeur $revendeur, Request $request, EntityManagerInterface $em, MeilisearchService $meilisearch): Response
    {
        if ('POST' === $request->getMethod()) {
            $this->populateRevendeurData($request, $revendeur);
            $revendeur->setUpdatedAt(new \DateTimeImmutable());
            $em->flush();

            $this->indexInMeilisearch($meilisearch, $revendeur);

            $this->addFlash('success', self::LABEL_REVENDEUR.$revendeur->getCodeRevendeur().' mis a jour.');

            return $this->redirectToRoute('app_admin_revendeurs_index');
        }

        return $this->render('admin/revendeurs/edit.html.twig', [
            'revendeur' => $revendeur,
        ]);
    }

    private function populateRevendeurData(Request $request, Revendeur $revendeur): void
    {
        $revendeur->setRaisonSociale(trim($request->request->getString('raisonSociale')) ?: null);
        $revendeur->setSiret(trim($request->request->getString('siret')) ?: null);
        $revendeur->setEmail(trim($request->request->getString('email')) ?: null);
        $revendeur->setPhone(trim($request->request->getString('phone')) ?: null);
        $revendeur->setAddress(trim($request->request->getString('address')) ?: null);
        $revendeur->setZipCode(trim($request->request->getString('zipCode')) ?: null);
        $revendeur->setCity(trim($request->request->getString('city')) ?: null);
        $revendeur->setIsUseStripe($request->request->getBoolean('isUseStripe'));
    }

    private function indexInMeilisearch(MeilisearchService $meilisearch, Revendeur $revendeur): void
    {
        try {
            $meilisearch->indexRevendeur($revendeur);
        } catch (\Throwable $e) {
            $this->logger->error('Meilisearch: Failed to index reseller '.$revendeur->getId().': '.$e->getMessage());
        }
    }

    #[Route('/{id}/contrat', name: 'contrat', methods: ['GET'])]
    public function contrat(
        Revendeur $revendeur,
        Environment $twig,
        #[Autowire('%kernel.project_dir%')] string $projectDir,
    ): Response {
        $logoPath = $projectDir.'/public/logo.jpg';
        $logo = file_exists($logoPath) ? 'data:image/jpeg;base64,'.base64_encode(file_get_contents($logoPath)) : '';

        $html = $twig->render('pdf/contrat_revendeur.html.twig', [
            'revendeur' => $revendeur,
            'logo' => $logo,
            'date' => new \DateTimeImmutable(),
        ]);

        $dompdf = new Dompdf();
        $dompdf->loadHtml($html);
        $dompdf->setPaper('A4');
        $dompdf->render();

        return new Response($dompdf->output(), 200, [
            'Content-Type' => 'application/pdf',
            'Content-Disposition' => 'inline; filename="contrat-'.$revendeur->getCodeRevendeur().'.pdf"',
        ]);
    }
}
