<?php

namespace App\Controller\Dashboard;

use App\Entity\Backup;
use App\Logger\AppLogger;
use App\Repository\BackupRepository;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\BinaryFileResponse;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpFoundation\ResponseHeaderBag;
use Symfony\Component\Routing\Attribute\Route;

#[Route('/crm/sauvegarde')]
class BackupController extends AbstractController
{
    public function __construct(
        private readonly AppLogger $appLogger,
        private readonly EntityManagerInterface $em
    ) {
    }

    #[Route('', name: 'app_crm_backup', options: ['sitemap' => false], methods: ['GET'])]
    public function index(BackupRepository $backupRepository): Response
    {
        $this->appLogger->record('VIEW', 'Consultation de la liste des sauvegardes système');

        return $this->render('dashboard/backup.twig', [
            'backups' => $backupRepository->findBy([], ['createdAt' => 'DESC']),
        ]);
    }

    #[Route('/download/{id}', name: 'app_crm_backup_download', options: ['sitemap' => false], methods: ['GET'])]
    public function download(Backup $backup): Response
    {
        $filePath = $this->getBackupFilePath($backup);
        $fileName = basename($filePath);

        if (!file_exists($filePath)) {
            $this->appLogger->record(
                'SECURITY_ALERT',
                sprintf("Fichier de sauvegarde introuvable : %s (ID: %d)", $fileName, $backup->getId())
            );

            $this->addFlash('error', "Le fichier physique est introuvable sur le serveur.");
            return $this->redirectToRoute('app_crm_backup');
        }

        $this->appLogger->record('INFO', "Téléchargement de la sauvegarde : $fileName");

        $response = new BinaryFileResponse($filePath);
        $response->setContentDisposition(ResponseHeaderBag::DISPOSITION_ATTACHMENT, $fileName);

        return $response;
    }

    #[Route('/delete/{id}', name: 'app_crm_backup_delete', options: ['sitemap' => false], methods: ['GET'])]
    public function delete(Backup $backup): RedirectResponse
    {
        if (!$this->isGranted('ROLE_ROOT')) {
            $this->appLogger->record(
                'SECURITY_ALERT',
                "Tentative de suppression de sauvegarde sans droits ROOT (ID Backup: {$backup->getId()})"
            );

            $this->addFlash('error', "Accès refusé. Rôle ROOT requis.");
            return $this->redirectToRoute('app_crm_backup');
        }

        $filePath = $this->getBackupFilePath($backup);
        $fileName = basename($filePath);

        try {
            if (file_exists($filePath)) {
                unlink($filePath);
            }

            $backupId = $backup->getId();
            $this->em->remove($backup);
            $this->em->flush();

            $this->appLogger->record(
                'SECURITY_ALERT',
                "Suppression définitive de la sauvegarde ID: $backupId et du fichier $fileName"
            );

            $this->addFlash('success', "La sauvegarde a été supprimée.");

        } catch (\Exception $e) {
            $this->appLogger->record(
                'ERROR',
                "Erreur lors de la suppression de la sauvegarde : " . $e->getMessage()
            );
            $this->addFlash('error', "Erreur lors de la suppression.");
        }

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

    /**
     * Génère le chemin absolu vers le fichier de sauvegarde
     */
    private function getBackupFilePath(Backup $backup): string
    {
        $projectDir = $this->getParameter('kernel.project_dir');
        $fileName = sprintf('db_backup_%s.zip', $backup->getCreatedAt()->format('Y-m-d_H-i'));

        return $projectDir . '/sauvegarde/' . $fileName;
    }
}
