<?php

namespace App\Controller\Admin;

use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\Security\Http\Attribute\IsGranted;
use Psr\Log\LoggerInterface;

/**
 * Gère le mode maintenance et la synchronisation.
 *
 * Routes protégées : seul le rôle ROLE_ADMIN peut y accéder.
 * Le fichier maintenance.flag est lu par le kernel event listener
 * pour afficher la page de maintenance à tous les autres utilisateurs.
 */
#[Route('/admin/sync', name: 'admin_sync_')]
#[IsGranted('ROLE_ADMIN')]
class SyncController extends AbstractController
{
    public function __construct(
        private string $projectDir,
        private LoggerInterface $logger,
    ) {}

    /**
     * Page principale : bouton "Synchroniser avec le serveur"
     */
    #[Route('', name: 'index', methods: ['GET'])]
    public function index(): \Symfony\Component\HttpFoundation\Response
    {
        $flagPath   = $this->projectDir . '/public/maintenance.flag';
        $logPath    = $this->projectDir . '/var/log/sync.log';
        $lastLines  = [];

        if (file_exists($logPath)) {
            $lines     = file($logPath, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
            $lastLines = array_slice($lines, -20); // 20 dernières lignes
        }

        return $this->render('admin/sync/index.html.twig', [
            'maintenance_active' => file_exists($flagPath),
            'last_log_lines'     => $lastLines,
        ]);
    }

    /**
     * Active le mode maintenance.
     * Appelé par le script local avant l'export.
     */
    #[Route('/maintenance/on', name: 'maintenance_on', methods: ['POST'])]
    public function maintenanceOn(): JsonResponse
    {
        $flagPath = $this->projectDir . '/public/maintenance.flag';

        try {
            file_put_contents($flagPath, date('Y-m-d H:i:s'));
            $this->logger->info('Maintenance activée', ['ip' => $_SERVER['REMOTE_ADDR'] ?? 'cli']);

            return new JsonResponse(['status' => 'ok', 'message' => 'Maintenance activée']);
        } catch (\Throwable $e) {
            return new JsonResponse(['status' => 'error', 'message' => $e->getMessage()], 500);
        }
    }

    /**
     * Désactive le mode maintenance.
     * Appelé à la fin de la synchronisation.
     */
    #[Route('/maintenance/off', name: 'maintenance_off', methods: ['POST'])]
    public function maintenanceOff(): JsonResponse
    {
        $flagPath = $this->projectDir . '/public/maintenance.flag';

        try {
            if (file_exists($flagPath)) {
                unlink($flagPath);
            }
            $this->logger->info('Maintenance désactivée');

            return new JsonResponse(['status' => 'ok', 'message' => 'Maintenance désactivée']);
        } catch (\Throwable $e) {
            return new JsonResponse(['status' => 'error', 'message' => $e->getMessage()], 500);
        }
    }

    /**
     * Lance la synchronisation depuis l'interface web.
     * Exécute le script sync.sh en arrière-plan et retourne immédiatement.
     */
    #[Route('/launch', name: 'launch', methods: ['POST'])]
    public function launch(Request $request): JsonResponse
    {
        // Protection CSRF
        if (!$this->isCsrfTokenValid('sync_launch', $request->request->get('_token'))) {
            return new JsonResponse(['status' => 'error', 'message' => 'Token CSRF invalide'], 403);
        }

        $syncScript = $this->projectDir . '/sync/scripts/sync.sh';

        if (!file_exists($syncScript)) {
            return new JsonResponse([
                'status'  => 'error',
                'message' => 'Script de synchronisation introuvable : ' . $syncScript,
            ], 500);
        }

        $logPath = $this->projectDir . '/var/log/sync.log';

        // Lancement en arrière-plan (non bloquant)
        $cmd = sprintf(
            'bash %s >> %s 2>&1 &',
            escapeshellarg($syncScript),
            escapeshellarg($logPath)
        );

        exec($cmd);
        $this->logger->info('Synchronisation lancée via interface web');

        return new JsonResponse([
            'status'  => 'ok',
            'message' => 'Synchronisation démarrée. Suivez la progression dans les logs.',
        ]);
    }

    /**
     * Retourne le statut en cours (pour polling AJAX).
     */
    #[Route('/status', name: 'status', methods: ['GET'])]
    public function status(): JsonResponse
    {
        $flagPath = $this->projectDir . '/public/maintenance.flag';
        $logPath  = $this->projectDir . '/var/log/sync.log';

        $lastLine  = '';
        $isRunning = false;

        if (file_exists($logPath)) {
            $lines    = file($logPath, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
            $lastLine = end($lines) ?: '';

            // On considère qu'une synchro est en cours si maintenance active
            $isRunning = file_exists($flagPath);
        }

        // Déterminer le résultat si terminé
        $lastStatus = null;
        if (!$isRunning && str_contains($lastLine, 'succès')) {
            $lastStatus = 'success';
        } elseif (!$isRunning && str_contains(strtoupper($lastLine), 'ERREUR')) {
            $lastStatus = 'error';
        }

        return new JsonResponse([
            'maintenance' => file_exists($flagPath),
            'running'     => $isRunning,
            'last_line'   => $lastLine,
            'last_status' => $lastStatus,
        ]);
    }
}
