<?php

namespace App\Controller;

use App\Entity\Account;
use App\Entity\AccountResetPasswordRequest;
use App\Form\RequestPasswordConfirmType;
use App\Form\RequestPasswordRequestType;
use App\Logger\AppLogger;
use App\Service\ResetPassword\Event\ResetPasswordConfirmEvent;
use App\Service\ResetPassword\Event\ResetPasswordEvent;
use Doctrine\ORM\EntityManagerInterface;
use KnpU\OAuth2ClientBundle\Client\ClientRegistry;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\PasswordHasher\Hasher\UserPasswordHasherInterface;
use Symfony\Component\Routing\Attribute\Route;
use Symfony\Component\Security\Http\Authentication\AuthenticationUtils;
use Symfony\Contracts\HttpClient\HttpClientInterface;


class HomeController extends AbstractController
{

    #[Route('/intranet/connect/keycloak', name: 'connect_keycloak_start')]
    public function connect(ClientRegistry $clientRegistry)
    {
        // Redirects to Keycloak
        return $clientRegistry
            ->getClient('keycloak')
            ->redirect(['email', 'profile','openid'], []);
    }


    #[Route('/intranet/oauth/sso', name: 'connect_keycloak_check')]
    public function connectCheck(Request $request)
    {
        // This method stays empty; the authenticator will intercept it!
    }
    #[Route(path: '/intranet', name: 'app_home', options: ['sitemap' => false], methods: ['GET','POST'])]
    public function index(AuthenticationUtils $authenticationUtils): Response
    {
        if($this->getUser()){
            return $this->redirectToRoute('app_crm');
        }
        return $this->render('home.twig',[
            'last_username' => $authenticationUtils->getLastUsername(),
            'error' => $authenticationUtils->getLastAuthenticationError(),
        ]);
    }

    #[Route(path: '/intranet/logout', name: 'app_logout', options: ['sitemap' => false], methods: ['GET','POST'])]
    public function logout(): Response
    {

    }
    #[Route(path: '/intranet/mot-de-passe-oublie', name: 'app_forgot_password', options: ['sitemap' => false], methods: ['GET','POST'])]
    public function forgotPassword(Request $request,EventDispatcherInterface $eventDispatcher): Response
    {
        $requestPasswordRequest = new ResetPasswordEvent();
        $form = $this->createForm(RequestPasswordRequestType::class,$requestPasswordRequest);
        $form->handleRequest($request);
        if ($form->isSubmitted() && $form->isValid()) {
            $eventDispatcher->dispatch($requestPasswordRequest);
            return $this->redirectToRoute('app_forgot_password_sent');
        }
        return $this->render('security/forgot_password.twig', [
            'form' => $form->createView(),
        ]);
    }

    #[Route(path: '/intranet/mot-de-passe-oublie/sent', name: 'app_forgot_password_sent', options: ['sitemap' => false], methods: ['GET','POST'])]
    public function forgotPasswordSent(Request $request,EventDispatcherInterface $eventDispatcher): Response
    {
        return $this->render('security/forgot_password_success.twig', [
        ]);
    }

    #[Route(path: '/intranet/mot-de-passe-oublie/{id}/{token}', name: 'app_forgot_password_confirm', options: ['sitemap' => false], methods: ['GET','POST'])]
    public function forgotPasswordConfirm(UserPasswordHasherInterface $userPasswordHasher,EventDispatcherInterface $eventDispatcher,Request $request,EntityManagerInterface $entityManager,string $id,string $token): Response
    {
        $errorMessage = "Requête non valide.";
        if (!is_numeric($id)) {
            $this->addFlash("error", $errorMessage);
            return $this->redirectToRoute('app_forgot_password');
        }
        $account = $entityManager->getRepository(Account::class)->find((int)$id);
        if (!$account instanceof Account) {
            $this->addFlash("error", $errorMessage);
            return $this->redirectToRoute('app_forgot_password');
        }
        $requestToken = $entityManager->getRepository(AccountResetPasswordRequest::class)->findOneBy([
            'Account' => $account, // Assurez-vous que 'Account' est le nom correct de la propriété/colonne dans votre entité AccountResetPasswordRequest.
            'token' => $token
        ]);
        if (!$requestToken instanceof AccountResetPasswordRequest) {
            $this->addFlash("error", $errorMessage);
            return $this->redirectToRoute('app_forgot_password');
        }
        $now = new \DateTimeImmutable();
        if ($requestToken->getExpiresAt() < $now) {
            $this->addFlash("error", "Le lien de réinitialisation de mot de passe a expiré.");
            return $this->redirectToRoute('app_forgot_password');
        }

        $event = new ResetPasswordConfirmEvent();
        $form = $this->createForm(RequestPasswordConfirmType::class,$event);
        $form->handleRequest($request);
        if ($form->isSubmitted() && $form->isValid()) {
            $account->setPassword($userPasswordHasher->hashPassword($account,$event->getPassword()));
            $entityManager->persist($account);
            $entityManager->flush();
            $this->addFlash("success", "Votre mot de passe a été mis à jour avec succès.");
            return $this->redirectToRoute('app_home');
        }
        return $this->render('security/forgot-password-confirm.twig', [
            'form' => $form->createView(),
            'noIndex' => true,
            'id' => $id,
            'token' => $token,
            'account' => $account,
        ]);
    }

    #[Route('/unscribe/{email}', name: 'app_unscribe', options: ['sitemap' => false], methods: ['GET', 'POST'])]
    public function appUnscribe(
        string $email,
        Request $request,
        EntityManagerInterface $entityManager,
        AppLogger $appLogger
    ): Response {
        // 1. Décodage de l'email (au cas où il y aurait des caractères spéciaux)
        $email = urldecode($email);

        // 3. Gestion du POST (Désinscription en un clic via le client mail)
        if ($request->isMethod('POST')) {
            $appLogger->record('UNSUBSCRIBE', sprintf("Désinscription automatique (One-Click) de : %s", $email));
            return new JsonResponse(['status' => 'success'], Response::HTTP_OK);
        }

        $appLogger->record('UNSUBSCRIBE', sprintf("Désinscription manuelle de : %s", $email));

        return $this->render('security/unscribe_success.twig', [
            'email' => $email
        ]);
    }
    // Remplace par ton DSN exact pour la vérification
    private const ALLOWED_DSN = 'https://803814be6540031b1c37bf92ba9c0f79@sentry.esy-web.dev/24';
    private const SENTRY_HOST = 'sentry.esy-web.dev';
    private const PROJECT_ID = '24';

    #[Route('/sentry-tunnel', name: 'sentry_tunnel', methods: ['POST'])]
    public function tunnel(Request $request, HttpClientInterface $httpClient): Response
    {
        try {
            $envelope = $request->getContent();
            $pieces = explode("\n", $envelope);

            // La première ligne de l'enveloppe Sentry contient le header en JSON
            $header = json_decode($pieces[0], true);

            // --- SÉCURITÉ : On vérifie que le DSN correspond bien au tien ---
            if (isset($header['dsn']) && $header['dsn'] !== self::ALLOWED_DSN) {
                return new Response('Invalid DSN', 401);
            }

            // Construction de l'URL finale vers ton instance Sentry
            $url = "https://" . self::SENTRY_HOST . "/api/" . self::PROJECT_ID . "/envelope/";

            // On renvoie l'enveloppe à Sentry
            $httpClient->request('POST', $url, [
                'body' => $envelope,
                'headers' => [
                    'Content-Type' => 'text/plain;charset=UTF-8',
                ],
            ]);

            return new Response('', 204);
        } catch (\Exception $e) {
            // En cas d'erreur du tunnel, on reste discret pour ne pas polluer la console client
            return new Response('Tunnel Error', 500);
        }
    }
}
