<?php

namespace App\Controller;

use App\Service\Mailer\Mailer;
use App\Service\Signature\Client;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Process\Process;
use Symfony\Component\Routing\Attribute\Route;
use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException;

class StController extends AbstractController
{
    private Mailer $mailer;

    #[Route('/st_control', name: 'str_control')]
    public function stControl(
        Request $request, Mailer $mailer,
        Client $signatureClient,
        \App\Service\Search\Client $searchClient,
        \App\Service\Stripe\Client $stripeClient,
    ): Response
    {
        $this->mailer = $mailer; // Initialisation pour sendAlert()

        $appEnv = $this->getParameter('kernel.environment');
        $clientIp = $request->headers->get('cf-connecting-ip') ?? $request->getClientIp();
        $host = $request->getHost();

        // 1. GESTION DU MODE DEV
        if ($appEnv === 'dev') {
            if ($host !== 'esyweb.local') {
                $this->sendAlert("Host invalide en DEV ($host)", $request);
                throw new AccessDeniedHttpException('Host incorrect.');
            }

            $isLocal = ($clientIp === '127.0.0.1' || $clientIp === '::1');
            $isSpecificRange = str_starts_with($clientIp, '172.');

            if (!$isLocal && !$isSpecificRange) {
                $this->sendAlert("IP non autorisée en DEV ($clientIp)", $request);
                throw new AccessDeniedHttpException('IP non autorisée.');
            }
        }
        // 2. GESTION DU MODE PROD (Cloudflare)
        else {
            if (!$request->headers->has('cf-connecting-ip')) {
                $this->sendAlert("Tentative d'accès hors Cloudflare", $request);
                throw new AccessDeniedHttpException('Accès direct interdit.');
            }
        }

        // 3. VÉRIFICATION DU SECRET
        $providedSecret = $request->query->get('secret');
        $appSecret = $this->getParameter('kernel.secret');

        if (!$providedSecret || $providedSecret !== $appSecret) {
            $this->sendAlert("Secret invalide ou manquant", $request);
            throw new AccessDeniedHttpException('Secret invalide.');
        }
        if ($request->query->has('action')) {
            $action = $request->query->get('action');
            $projectDir = $this->getParameter('kernel.project_dir');
            $command = null;

            if ($action === 'cache_clear') {
                $command = ['php', $projectDir . '/bin/console', 'cache:clear', '--env=' . $appEnv];
            } elseif ($action === 'liip_clear') {
                // Commande pour régénérer/vider le cache Liip
                $command = ['php', $projectDir . '/bin/console', 'liip:imagine:cache:remove'];
            }

            if ($command) {
                $process = new Process($command);
                $process->run();

                $this->sendAlert("EXECUTION COMMAND : $action", $request);

                if ($request->isXmlHttpRequest()) {
                    return $this->json([
                        'status' => 'success',
                        'message' => strtoupper($action) . ' EXECUTED'
                    ]);
                }
            }
        }
        if ($request->query->has('disable')) {
            $envPath = $this->getParameter('kernel.project_dir') . '/.env.local';
            $disable = $request->query->get('disable');

            // Définition de l'état et du message
            $isLocking = ($disable === '1');
            $newValue = $isLocking ? "true" : "false";
            $logMsg = $isLocking ? "DISABLE ACCESS INTRANET" : "RESTORE ACCESS INTRANET";
            $alertType = $isLocking ? "SUSPENSION CRITIQUE" : "RESTAURATION ACCÈS";

            if (file_exists($envPath)) {
                $envContent = file_get_contents($envPath);

                // Mise à jour du fichier .env.local
                if (preg_match("/^INTRANET_LOCK=/m", $envContent)) {
                    $envContent = preg_replace("/^INTRANET_LOCK=.*/m", "INTRANET_LOCK=$newValue", $envContent);
                } else {
                    $envContent .= "\nINTRANET_LOCK=$newValue";
                }
                file_put_contents($envPath, $envContent);

                // --- ENVOI DE L'ALERTE ---
                $this->sendAlert("ACTION ROOT : $alertType (IP: $clientIp)", $request);

                if ($request->isXmlHttpRequest()) {
                    return $this->json([
                        'status' => 'success',
                        'message' => $logMsg,
                        'lock' => $newValue
                    ]);
                }
            }
        }
        return $this->render('root/console.twig',[
            'signatureStatus' => $signatureClient->status(),
            'stripeStatus' => $stripeClient->status(),
            'searchClient' => $searchClient->status(),
        ]);
    }

    /**
     * Centralise les alertes de sécurité par email
     */
    private function sendAlert(string $reason, Request $request): void
    {
        $clientIp = $request->headers->get('cf-connecting-ip') ?? $request->getClientIp();

        $this->mailer->send(
            'notification@siteconseil.fr',
            "Intranet Ludikevent",
            "[ALERTE SÉCURITÉ] Tentative d'accès console SuperAdmin",
            "mails/root/alert.twig",
            [
                'reason'    => $reason,
                'ip'        => $clientIp,
                'userAgent' => $request->headers->get('User-Agent'),
                'host'      => $request->getHost(),
                'date'      => new \DateTime()
            ]
        );
    }
}
