<?php

namespace App\Controller\Admin;

use App\Entity\User;
use App\Repository\AppLogRepository;
use App\Service\AppLoggerService;
use Doctrine\ORM\EntityManagerInterface;
use Dompdf\Dompdf;
use Endroid\QrCode\Builder\Builder;
use Endroid\QrCode\Writer\PngWriter;
use Knp\Component\Pager\PaginatorInterface;
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/logs', name: 'app_admin_logs')]
#[IsGranted('ROLE_ROOT')]
class LogsController extends AbstractController
{
    #[Route('', name: '')]
    public function index(
        Request $request,
        AppLogRepository $repository,
        PaginatorInterface $paginator,
        AppLoggerService $loggerService,
    ): Response {
        $query = $repository->createPaginatedQueryBuilder();

        $pagination = $paginator->paginate(
            $query,
            $request->query->getInt('page', 1),
            20,
        );

        $hmacResults = [];
        foreach ($pagination as $log) {
            $hmacResults[$log->getId()] = $loggerService->verifyLog($log); // @codeCoverageIgnore
        }

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

    #[Route('/purge', name: '_purge', methods: ['POST'])]
    public function purge(EntityManagerInterface $em, AppLoggerService $loggerService): Response
    {
        $count = (int) $em->createQueryBuilder()
            ->select('COUNT(l.id)')
            ->from('App\Entity\AppLog', 'l')
            ->getQuery()
            ->getSingleScalarResult();

        $em->createQueryBuilder()
            ->delete('App\Entity\AppLog', 'l')
            ->getQuery()
            ->execute();

        $user = $this->getUser();
        $loggerService->logDirect(
            'DELETE',
            '/admin/logs/purge',
            'app_admin_logs_purge',
            'Suppression de tous les logs ('.$count.' entrees supprimees)',
            $user instanceof User ? $user : null,
        );

        $this->addFlash('success', $count.' log(s) supprime(s).');

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

    #[Route('/{id}/delete', name: '_delete', methods: ['POST'])]
    public function delete(int $id, AppLogRepository $repository, EntityManagerInterface $em, AppLoggerService $loggerService): Response
    {
        $log = $repository->find($id);

        if (null === $log) {
            throw $this->createNotFoundException('Log introuvable.');
        }

        $logInfo = 'Suppression du log #'.$log->getId().' ('.$log->getAction().' du '.$log->getCreatedAt()->format('d/m/Y H:i:s').')';

        $em->remove($log);
        $em->flush();

        $user = $this->getUser();
        $loggerService->logDirect(
            'DELETE',
            '/admin/logs/'.$id.'/delete',
            'app_admin_logs_delete',
            $logInfo,
            $user instanceof User ? $user : null,
        );

        $this->addFlash('success', 'Log #'.$id.' supprime.');

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

    #[Route('/{id}/pdf', name: '_pdf', methods: ['GET'])]
    public function pdf(
        int $id,
        AppLogRepository $repository,
        AppLoggerService $loggerService,
        Environment $twig,
        #[Autowire('%kernel.project_dir%')] string $projectDir,
    ): Response {
        $log = $repository->find($id);

        if (null === $log) {
            throw $this->createNotFoundException('Log introuvable.');
        }

        $hmacValid = $loggerService->verifyLog($log);

        $logoPath = $projectDir.'/public/logo.jpg';
        $logo = file_exists($logoPath) ? 'data:image/png;base64,'.base64_encode((string) file_get_contents($logoPath)) : '';

        $verifyUrl = $this->generateUrl('app_log_verify', [
            'id' => $log->getId(),
            'hmac' => substr($log->getHmac(), 0, 16),
        ], UrlGeneratorInterface::ABSOLUTE_URL);

        $qrCode = (new Builder(writer: new PngWriter(), data: $verifyUrl, size: 200, margin: 10))->build();
        $qrCodeBase64 = 'data:image/png;base64,'.base64_encode($qrCode->getString());

        $html = $twig->render('admin/logs/pdf.html.twig', [
            'log' => $log,
            'hmacValid' => $hmacValid,
            'logo' => $logo,
            'verifyUrl' => $verifyUrl,
            'qrcode' => $qrCodeBase64,
        ]);

        $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="log-'.$log->getId().'.pdf"',
        ]);
    }
}
