<?php
namespace App\Controller;
use App\Entity\Booking;
use App\Entity\Participant;
use App\Entity\Session;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\Mailer\MailerInterface;
use Symfony\Bridge\Twig\Mime\TemplatedEmail;
use Symfony\Component\Mime\Address;
use Symfony\Component\Mime\Email;
use Symfony\Component\Mailer\Exception\HttpTransportException;
class DefaultController extends AbstractController
{
/**
* @Route("/", name="app_default")
*/
public function index(Request $request)
{
$em = $this->getDoctrine()->getManager();
if($request->isMethod('POST'))
{
$booking = new Booking();
$booking->setStatus('Brouillon');
$em->persist($booking);
$em->flush();
$p = new Participant();
$p->setBooking($booking)
->setGardianName($request->get('gardianName'))
->setGardianNickname($request->get('gardianNickname'))
->setGardianEmail($request->get('gardianEmail'))
->setGardianPhone($request->get('gardianPhone'))
->setName($request->get('participantName'))
->setNickName($request->get('participantNickname'))
->setPhone($request->get('participantPhone'))
->setEmail($request->get('participantEmail'))
->setDob(new \DateTimeImmutable($request->get('participantDob')));
$em->persist($p);
$em->flush();
return $this->redirectToRoute('step',['id' => $p->getId()]);
}
return $this->render('default/session-step2.html.twig');
}
/**
* @Route("/participants/{id}", name="step.2")
*/
public function stepTwo(Request $request, $id)
{
$em = $this->getDoctrine()->getManager();
$booking = $em->getRepository(Booking::class)->find($id);
if (!$booking) {
throw $this->createNotFoundException('Réservation introuvable.');
}
// Pour réafficher en cas de GET initial (ou si tu veux voir ce qui a été saisi)
$prefill = [];
if ($request->isMethod('POST')) {
// Récupération brute des participants (toujours un tableau)
$params = $request->request->all();
$participantsData = $params['participants'] ?? [];
if (!is_array($participantsData)) { $participantsData = []; }
$prefill = $participantsData;
// 1) On supprime les anciens participants liés au booking (si retour arrière)
foreach ($booking->getParticipants() as $old) { $em->remove($old); }
$booking->getParticipants()->clear();
// 2) On enregistre ce qu'on reçoit, sans se prendre la tête
foreach ($participantsData as $row) {
// On tolère plusieurs conventions de noms pour éviter les 500 :
$name = trim((string)($row['name'] ?? $row['first_name'] ?? ''));
$nickName = trim((string)($row['nickName'] ?? $row['last_name'] ?? ''));
$email = trim((string)($row['email'] ?? ''));
$phone = trim((string)($row['phone'] ?? $row['mobile'] ?? ''));
$dobStr = trim((string)($row['dob'] ?? ''));
$gName = trim((string)($row['gardianName'] ?? $row['gardian_name'] ?? $row['guardian_first_name'] ?? ''));
$gNick = trim((string)($row['gardianNickname'] ?? $row['gardian_nickname'] ?? $row['guardian_last_name'] ?? ''));
$gEmail = trim((string)($row['gardianEmail'] ?? $row['gardian_email'] ?? $row['guardian_email'] ?? ''));
$gPhone = trim((string)($row['gardianPhone'] ?? $row['gardian_phone'] ?? $row['guardian_mobile'] ?? ''));
// case à cocher : on sauvegarde "1" si coché, NULL sinon
$gConsent = !empty($row['gardian_participant_consent'] ?? $row['guardian_participant_consent'] ?? $row['guardian_authorizes_participation'] ?? null) ? '1' : null;
// Si la ligne est complètement vide, on skip
if ($name === '' && $nickName === '' && $email === '' && $phone === '' && $dobStr === '') {
continue;
}
$p = new Participant();
$p->setBooking($booking);
// Setters selon TON entité
$p->setName($name !== '' ? $name : null);
if (method_exists($p, 'setNickName')) {
$p->setNickName($nickName !== '' ? $nickName : null);
} elseif (method_exists($p, 'setNickname')) {
$p->setNickname($nickName !== '' ? $nickName : null);
}
$p->setEmail($email !== '' ? $email : null);
if (method_exists($p, 'setPhone')) {
$p->setPhone($phone !== '' ? $phone : null);
}
if ($dobStr !== '') {
try { $p->setDob(new \DateTimeImmutable($dobStr)); } catch (\Throwable $e) { /* on ignore */ }
}
if (method_exists($p, 'setGardianName')) { $p->setGardianName($gName !== '' ? $gName : null); }
if (method_exists($p, 'setGardianNickname')) { $p->setGardianNickname($gNick !== '' ? $gNick : null); }
elseif (method_exists($p, 'setGardianNickName')) { $p->setGardianNickName($gNick !== '' ? $gNick : null); }
if (method_exists($p, 'setGardianEmail')) { $p->setGardianEmail($gEmail !== '' ? $gEmail : null); }
if (method_exists($p, 'setGardianPhone')) { $p->setGardianPhone($gPhone !== '' ? $gPhone : null); }
if (method_exists($p, 'setGardianParticipantConsent')) {
$p->setGardianParticipantConsent($gConsent); // string nullable
}
$em->persist($p);
if (method_exists($booking, 'addParticipant')) {
$booking->addParticipant($p);
}
}
// 3) On écrit et on file en étape 3
$em->flush();
return $this->redirectToRoute('step.dis', ['id' => $booking->getId()]);
}
// GET initial (ou si tu veux pré-remplir)
return $this->render('default/session-step2.html.twig', [
'booking' => $booking,
'prefill' => $prefill,
]);
}
/**
* @Route("/disclamer/{id}", name="step")
*/
public function stepDix(Request $request, $id)
{
$em = $this->getDoctrine()->getManager();
$booking = $em->getRepository(Booking::class)->find($id);
if (!$booking) {
throw $this->createNotFoundException('Réservation introuvable.');
}
if ($request->isMethod('POST')) {
$consents = $request->get('disclamer');
/// dd('kkikoo');
foreach ($booking->getParticipants() as $p) {
$checked = !empty($consents[$p->getId()]['disclamer'] ?? null);
$p->setDisclamer('1'); // on stocke "1" si coché
$em->persist($p);
}
$em->flush();
return $this->redirectToRoute('step.3', ['id' => $booking->getId()]);
}
return $this->render('default/session-step3-1.html.twig', [
'booking'=> $booking
]);
}
/**
* @Route("/consentement/{id}", name="step.3")
*/
public function stepThree(Request $request, $id, MailerInterface $mailer)
{
$em = $this->getDoctrine()->getManager();
$booking = $em->getRepository(Booking::class)->find($id);
if (!$booking) {
throw $this->createNotFoundException('Réservation introuvable.');
}
// Date d’événement depuis la session si dispo, sinon aujourd’hui
$eventDate = null;
if (method_exists($booking, 'getSession') && $booking->getSession() && method_exists($booking->getSession(), 'getStartsAt')) {
$eventDate = $booking->getSession()->getStartsAt();
}
if (!$eventDate) { $eventDate = new \DateTimeImmutable('today'); }
$eventDatePlus10 = $eventDate->modify('+10 years');
// Qui est mineur ? (pour afficher la bonne phrase côté Twig)
$minors = [];
foreach ($booking->getParticipants() as $p) {
$isMinor = false;
if (method_exists($p, 'getDob') && $p->getDob() instanceof \DateTimeInterface) {
$age = $p->getDob()->diff(new \DateTimeImmutable('today'))->y;
$isMinor = ($age < 18);
}
$minors[$p->getId()] = $isMinor;
}
$errors = [];
if ($request->isMethod('POST')) {
$consents = $request->request->get('consents', []);
foreach ($booking->getParticipants() as $p) {
$checked = !empty($consents[$p->getId()]['imgConsent'] ?? null);
if (!$checked) {
$displayName = trim(($p->getName() ?? '').' '.($p->getNickName() ?? ''));
$errors[] = "Merci d’accepter les droits à l’image pour « {$displayName} ».";
} else {
$p->setImgConsent('1'); // on stocke "1" si coché
$em->persist($p);
}
}
if (empty($errors)) {
if (method_exists($booking, 'setStatus')) {
$booking->setStatus('Confirmé');
$em->persist($booking);
}
$em->flush();
// Construit quelques infos utiles pour l’email
$session = method_exists($booking, 'getSession') ? $booking->getSession() : null;
$startsAt = ($session && method_exists($session,'getStartsAt')) ? $session->getStartsAt() : null;
$endsAt = ($session && method_exists($session,'getEndsAt')) ? $session->getEndsAt() : null;
// Envoi email (on encapsule dans try/catch pour ne pas bloquer l’utilisateur en cas d’échec SMTP)
$email = (new TemplatedEmail())
->from(new Address('noreply@agence58.com', 'JPO EDF'))
->to('sei-guadeloupe-communication@edf.fr')
->subject(sprintf('Nouvelle réservation — JPO EDF — #%d', $booking->getId()))
->htmlTemplate('default/email-booking.html.twig')
->context([
'booking' => $booking,
'startsAt' => $startsAt,
'endsAt' => $endsAt,
]);
$mailer->send($email);
$this->addFlash('success', 'Merci ! Les inscriptions ont bien été prises en compte.');
return $this->redirectToRoute('step.4', ['id' => $booking->getId()]);
}
}
// dd($booking);
return $this->render('default/session-step3.html.twig', [
'booking' => $booking,
'errors' => $errors,
'eventDate' => $eventDate,
'eventDatePlus10' => $eventDatePlus10,
'minors' => $minors,
]);
}
/**
* @Route("/confirmation/{id}", name="step.4")
*/
public function stepFour($id)
{
$em = $this->getDoctrine()->getManager();
$booking = $em->getRepository(Booking::class)->find($id);
return $this->render('default/session-step4.html.twig', [
'booking' => $booking]);
}
/**
* @Route("/mail-test", name="mail.test")
*/
public function mailTest(MailerInterface $mailer): Response {
{
try {
$email = (new Email())
->from('no-reply@agence58.com')
->to('agence.deejayevents@gmail.com')
->subject('Test Brevo API')
->text('Ceci est un test d’envoi via Brevo (API).');
$mailer->send($email);
return new Response('✅ Mail envoyé (vérifie ta boîte ou ton dossier spam)');
}
catch (HttpTransportException $e) {
// Erreurs API Brevo : on récupère le détail JSON
$details = $e->getResponse() ? $e->getResponse()->getContent(false) : '';
return new Response("❌ HttpTransportException: {$e->getMessage()}\n\n{$details}", 500);
}
catch (\Throwable $e) {
return new Response("❌ Exception: {$e->getMessage()}", 500);
}
}
}
}