<?php

namespace App\Controller;

use App\Exception\TooManyOtpRequestsException;
use App\Service\ConcessionsProvider;
use App\Service\EmailDomainPolicy;
use App\Service\OtpManager;
use Psr\Log\LoggerInterface;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Attribute\Route;

final class AuthController extends AbstractController
{
    #[Route('/auth/login', name: 'app_login', methods: ['GET'])]
    public function login(ConcessionsProvider $concessions): Response
    {
        // Déjà connecté → accueil
        if ($this->getUser()) {
            return $this->redirectToRoute('app_home');
        }

        return $this->render('auth/login.html.twig', [
            'concessions' => $concessions->all(),
            'selectedConcessions' => [],
        ]);
    }

    #[Route('/api/auth/send-code', name: 'app_auth_send_code', methods: ['POST'])]
    public function sendCode(
        Request $request,
        EmailDomainPolicy $domainPolicy,
        OtpManager $otp,
        LoggerInterface $logger,
    ): JsonResponse {
        $data = json_decode($request->getContent(), true);
        if (!\is_array($data) || !isset($data['email']) || !\is_string($data['email'])) {
            return $this->json(['error' => 'Email requis'], Response::HTTP_BAD_REQUEST);
        }

        $email = strtolower(trim($data['email']));

        if (!$domainPolicy->isAllowed($email)) {
            return $this->json([
                'error' => sprintf(
                    'Seuls les emails des domaines %s sont autorisés.',
                    implode(' et ', $domainPolicy->allowedDomains())
                ),
            ], Response::HTTP_FORBIDDEN);
        }

        try {
            $otp->requestCode($email);
        } catch (TooManyOtpRequestsException $e) {
            return $this->json(['error' => $e->getMessage()], Response::HTTP_TOO_MANY_REQUESTS);
        } catch (\Throwable $e) {
            $logger->error('Erreur envoi OTP', ['exception' => $e]);

            return $this->json(
                ['error' => "Erreur lors de l'envoi de l'email. Vérifiez la configuration SMTP."],
                Response::HTTP_INTERNAL_SERVER_ERROR
            );
        }

        return $this->json(['success' => true]);
    }

    #[Route('/api/auth/me', name: 'app_auth_me', methods: ['GET'])]
    public function me(): JsonResponse
    {
        $user = $this->getUser();
        if (null === $user) {
            return $this->json(['error' => 'Non authentifié'], Response::HTTP_UNAUTHORIZED);
        }

        return $this->json(['email' => $user->getUserIdentifier()]);
    }

    /**
     * Interceptée par OtpAuthenticator (vérification du code OTP).
     * La route doit exister pour que la requête atteigne le firewall ; le corps n'est jamais exécuté.
     */
    #[Route('/api/auth/verify', name: 'app_auth_verify', methods: ['POST'])]
    public function verify(): never
    {
        throw new \LogicException('Interceptée par OtpAuthenticator.');
    }

    /**
     * Interceptée par le firewall (déconnexion). Le corps n'est jamais exécuté.
     */
    #[Route('/api/auth/logout', name: 'app_logout', methods: ['GET', 'POST'])]
    public function logout(): never
    {
        throw new \LogicException('Interceptée par le firewall de sécurité.');
    }
}
