<?php
namespace App\Controller;
use App\Entity\Configuration;
use App\Entity\Space;
use App\Entity\User;
use App\Entity\ToDoLogs;
use App\Entity\WidgetNotes;
use App\Form\WidgetNotesType;
use App\MDS\VenuesBundle\Entity\Reservation;
use App\MDS\VenuesBundle\Entity\ReservationLoungeDetails;
use App\MDS\VenuesBundle\Entity\ReservationLoungeSimple;
use App\MDS\VenuesBundle\Entity\ReservationVisit;
use App\Service\CalendarService;
use App\Service\UserNotificationService;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\Security\Http\Authentication\AuthenticationUtils;
use Symfony\Contracts\Translation\TranslatorInterface;
use Google_Client;
use Google_Service_Calendar;
use Doctrine\ORM\Query;
class HomeController extends AbstractController
{
private $googleCalendar;
private $translator;
private $userNotificationService;
public function __construct(TranslatorInterface $translator, UserNotificationService $userNotificationService)
{
$redirectUri = 'https://' . ($_SERVER['HTTP_HOST'] ?? '') . '/calendar/token';
$client = new Google_Client();
$client->setApplicationName('Google Calendar API');
$client->setClientId('YOUR_GOOGLE_CLIENT_ID');
$client->setClientSecret('YOUR_GOOGLE_CLIENT_SECRET');
$client->setRedirectUri($redirectUri);
$client->addScope(Google_Service_Calendar::CALENDAR);
$guzzle = new \GuzzleHttp\Client(['curl' => [CURLOPT_SSL_VERIFYPEER => false]]);
$client->setHttpClient($guzzle);
$this->googleCalendar = $client;
$this->translator = $translator;
$this->userNotificationService = $userNotificationService;
}
/**
* @Route("/inicio", name="ruta_inicio")
*/
public function inicioAction(AuthenticationUtils $authenticationUtils)
{
$em = $this->getDoctrine()->getManager();
$configuration = $em->getRepository(Configuration::class)->findOneBy([]);
return $this->render('login/login.html.twig', [
'last_username' => $authenticationUtils->getLastUsername(),
'error' => $authenticationUtils->getLastAuthenticationError(),
'configuration' => $configuration,
]);
}
/**
* @Route("/", name="homepage")
*/
public function index(EntityManagerInterface $em): Response
{
$user = $this->getUser();
if (!$user) return $this->redirectToRoute('ruta_inicio');
$tz = new \DateTimeZone('Europe/Madrid');
$from = (new \DateTimeImmutable('today', $tz))->setTime(0, 0);
$to = $from->modify('+30 days')->setTime(23, 59, 59);
// 1. DETECTAR ROL "LEGENDS" Y SU ESPACIO
$isLegendUser = false;
$lSpace = null;
$rol = $user->getSettingsRol();
if ($rol && strtoupper(trim($rol->getRol())) === 'LEGENDS') {
$isLegendUser = true;
$lSpace = $em->getRepository(Space::class)->createQueryBuilder('s')
->where('s.name LIKE :n')->setParameter('n', '%LEGEND%')
->setMaxResults(1)->getQuery()->getOneOrNullResult();
}
/** --- TABLA RESERVAS --- */
$qbR = $em->createQueryBuilder()
->select('r')->from(Reservation::class, 'r')
->where('r.dateStart <= :to')
->andWhere('r.dateEnd >= :from')
->setParameter('from', $from)->setParameter('to', $to);
if ($isLegendUser && $lSpace) {
$qbR->innerJoin(ReservationLoungeSimple::class, 'rls_f', 'WITH', 'rls_f.idReservation = r.id')
->innerJoin(ReservationLoungeDetails::class, 'rld_f', 'WITH', 'rld_f.id = rls_f.idLounge')
->andWhere('rld_f.space = :lSpace')->setParameter('lSpace', $lSpace);
}
$rowsR = $qbR->orderBy('r.dateStart', 'ASC')->getQuery()->getResult();
$upcomingReservationsTbl = [];
foreach ($rowsR as $resObj) {
$rooms = [];
$rlsRows = $em->getRepository(ReservationLoungeSimple::class)->findBy(['idReservation' => $resObj->getId()]);
foreach ($rlsRows as $rls) {
$lounge = $em->getRepository(ReservationLoungeDetails::class)->find($rls->getIdLounge());
if ($lounge) {
if (!$isLegendUser || ($lSpace && $lounge->getSpace() && $lounge->getSpace()->getId() === $lSpace->getId())) {
$rooms[] = $lounge->getName();
}
}
}
if ($isLegendUser && empty($rooms)) continue;
$upcomingReservationsTbl[] = [
'title' => $resObj->getTitle(), 'dateStart' => $resObj->getDateStart(),
'dateEnd' => $resObj->getDateEnd(), 'room' => implode(', ', array_unique($rooms))
];
}
$qbV = $em->createQueryBuilder()
->select('v')->from(ReservationVisit::class, 'v')
->where('v.dateStart <= :to')
// Usamos COALESCE para que si no hay dateEnd, use dateStart (igual que en el calendario)
->andWhere('COALESCE(v.dateEnd, v.dateStart) >= :from')
->setParameter('from', $from)->setParameter('to', $to);
if ($isLegendUser && $lSpace) {
// Filtramos por las salas que pertenecen al espacio Legend
$qbV->andWhere('v.idLounge IN (SELECT d.id FROM '.ReservationLoungeDetails::class.' d WHERE d.space = :sid)')
->setParameter('sid', $lSpace->getId());
}
//dd($qbV);
$rowsV = $qbV->orderBy('v.dateStart', 'ASC')->getQuery()->getResult();
$upcomingVisitsTbl = [];
foreach ($rowsV as $visitObj) {
$roomName = '-';
// Probamos ambos posibles getters para el ID de la sala
$idL = method_exists($visitObj, 'getIdLounge') ? $visitObj->getIdLounge() :
(method_exists($visitObj, 'getLoungeId') ? $visitObj->getLoungeId() : null);
if ($idL) {
$lounge = $em->getRepository(ReservationLoungeDetails::class)->find($idL);
if ($lounge) $roomName = $lounge->getName();
}
$upcomingVisitsTbl[] = [
'title' => $visitObj->getTitle() ?? 'Visita',
'dateStart' => $visitObj->getDateStart(),
'dateEnd' => $visitObj->getDateEnd(),
'room' => $roomName
];
}
$this->userNotificationService->checkRecentNotifications($user);
return $this->render('home/index.html.twig', [
'upcomingReservations' => $upcomingReservationsTbl,
'upcomingVisits' => $upcomingVisitsTbl,
'from' => $from, 'to' => $to,
'notifications' => $this->userNotificationService->getForModal($user)
]);
}
/**
* @Route("/calendar/global/visits", name="calendar_global_visits", methods={"GET"})
*/
public function globalVisits(Request $request, CalendarService $calendar, EntityManagerInterface $em): JsonResponse
{
$user = $this->getUser();
$spaceId = null;
if ($user && $user->getSettingsRol() && strtoupper(trim($user->getSettingsRol()->getRol())) === 'LEGENDS') {
$lSpace = $em->getRepository(Space::class)->createQueryBuilder('s')
->where('s.name LIKE :n')->setParameter('n', '%LEGEND%')
->setMaxResults(1)->getQuery()->getOneOrNullResult();
$spaceId = $lSpace ? $lSpace->getId() : null;
}
$from = new \DateTimeImmutable($request->query->get('start', 'first day of this month'));
$to = new \DateTimeImmutable($request->query->get('end', 'last day of next month'));
return new JsonResponse($calendar->getVisitsForCalendar($spaceId, null, $from, $to));
}
/**
* @Route("/calendar/global/reservations", name="calendar_global_reservations", methods={"GET"})
*/
public function globalReservations(Request $request, CalendarService $calendar, EntityManagerInterface $em): JsonResponse
{
$user = $this->getUser();
$spaceId = null;
if ($user && $user->getSettingsRol() && strtoupper(trim($user->getSettingsRol()->getRol())) === 'LEGENDS') {
$lSpace = $em->getRepository(Space::class)->createQueryBuilder('s')
->where('s.name LIKE :n')->setParameter('n', '%LEGEND%')
->setMaxResults(1)->getQuery()->getOneOrNullResult();
$spaceId = $lSpace ? $lSpace->getId() : null;
}
$from = new \DateTimeImmutable($request->query->get('start', 'first day of this month'));
$to = new \DateTimeImmutable($request->query->get('end', 'last day of next month'));
return new JsonResponse($calendar->getReservationsForCalendar($spaceId, null, $from, $to));
}
/**
* @Route("/ChangeLanguage/{lang}", name="change_language")
*/
public function changeLanguage(Request $request, string $lang): Response
{
$this->translator->setLocale($lang);
$request->getSession()->set('_locale', $lang);
return $this->redirect($request->headers->get('referer'));
}
}