<?php

namespace App\Controller\Admin\Security;

use DateTimeImmutable;
use Exception;
use LogicException;
use Symfony\Bundle\FrameworkBundle\Console\Application;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\Console\Input\ArrayInput;
use Symfony\Component\Console\Output\BufferedOutput;
use Symfony\Component\Filesystem\Exception\IOException;
use Symfony\Component\Filesystem\Filesystem;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\KernelInterface;
use Symfony\Component\Routing\Annotation\Route;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Security as Security;

#[Route('/admin/databases/backup')]
#[Security("is_granted('ROLE_SUPER_ADMIN')")]
class AdminDatabaseBackupController extends AbstractController
{
    #[Route('/', name: "admin.databases.index", methods: ['GET'])]
    public function index(KernelInterface $kernel, string $projectDirectory): Response
    {
        $this->denyAccessUnlessGranted('IS_AUTHENTICATED_FULLY');
        $user = $this->getUser();
        if ($user === null) {
            throw new LogicException('User can not be null');
        }

        $application = new Application($kernel);
        $application->setAutoExit(false);

        $backupDir = "$projectDirectory/var/backup";
        $backupFile = "$backupDir/backup.sql";
        $currentDatetimeString = (new DateTimeImmutable('now'))->format('d-m-Y-H-i-s');
        $backupFileRenamed = "$backupDir/backup-$currentDatetimeString.sql";

        $fileSystem = new Filesystem();
        if (!$fileSystem->exists($backupDir)) {
            $fileSystem->mkdir($backupDir, 0777);
        }

        $input = new ArrayInput(['command' => 'app:database-backup']);
        $output = new BufferedOutput();

        try {
            $application->run($input, $output);
        } catch (Exception $error) {
            throw new Exception('Erreur lors de l’exécution du backup : ' . $error->getMessage());
        }

        // Vérifie si le fichier a bien été créé
        if (!file_exists($backupFile)) {
            throw new \RuntimeException("Le fichier de sauvegarde '$backupFile' est introuvable après la commande.");
        }

        sleep(1); // pour laisser Windows stabiliser le fichier

        try {
            $fileSystem->rename($backupFile, $backupFileRenamed);
        } catch (IOException $error) {
            throw new IOException("Impossible de renommer le fichier : " . $error->getMessage());
        }

        // Envoi du fichier en téléchargement
        if (file_exists($backupFileRenamed)) {
            return $this->file($backupFileRenamed);
        }

        return new Response('Erreur : le fichier de sauvegarde renommé est introuvable.');
    }
}
