"use strict";

const moment = require("moment");
const generateControllers = require("../../core/controllers");
const eventService = require("./event.service");
const eventReservationService = require("./events_reservations.service");
const eventInscriptionService = require("./events_inscriptions.service");
const mailService = require("./mail.service");
const userService = require("../auth/user.service");
const marketingListService = require("./marketing_list.service");

const {
  extractParamsFromRequest,
  handleErrorResponse,
  handleResultResponse,
  httpStatus,
} = require("../../helpers/controller.helper");
const emailHelper = require("../../helpers/mail.helper");
const path = require("path");
const responseTime = require("response-time");

// Module Name
const MODULE_NAME = "[eventReservation.controller]";

const controllerOptions = { MODULE_NAME };

/**** Activa una reserva que está en borrador (Draft), descontando asistentes del aforo total del evento
 * Devuelve la reserva pasada por parametro publicada (publish) o null en el caso de error
 */
async function activeReservation(reservation) {
  if (!reservation) throw new Error("activeReservation: reservation should be an object");

  //En el caso de ya estar publicada no hacemos nada se devuelve tal cual
  if (reservation.state === "publish") return reservation;

  await eventService._updateAforoOfEventReservation(reservation, reservation.assistants);

  //REvisar confirmados en lista de espera
  //Finalmente publicamos la reserva solo si no está asociada a la lista de espera
  if (!reservation.overflow_reservationId) {
    if (!(await eventReservationService._updatePublishReservation(reservation.id))) {
      console.log("No se ha podido publicar la reserva del evento");
      return null;
    }
    reservation.state = "publish";

    //Finalmente hay que validar la inscripción del tutor en el caso de aquellos centros que no son aliados
    if (
      (await eventInscriptionService._validateInscriptionTutorOfReservation(reservation.id, reservation.userId)) <= 0
    ) {
      //En el caso de ser un centro aliado no se puede validar la inscripcion ya que se hace a posteriori por lo tanto no se hace nada
      //      console.log("No se ha podido validar la inscripción del tutor por ser de un centro aliado se hace a posteriori en este caso");
      //      return null;
    }

    console.log("reservation.userId>>>>>>  ", reservation.userId);
    //Mandamos el código de reserva para que registra a sus alumnos
    const user = await userService._getUserById(reservation.userId);
    reservation.contact_email = user.email;
    reservation.contact_name = user.name;
    console.log("reservation.userId>>>>>>  ", user.email);
    console.log("reservation.userId>>>>>>  ", user.email);

    try {
      console.log("envio correo>>>>>>>>>>> ", user);
      mailService.sendReservationCollegeEmail(reservation);
    } catch (error) {
      console.log(error);
    }

    return reservation;
  }
}

async function activeReservationById(id) {
  //Buscar reserva con evento y entidad
  let reservation = await eventReservationService._getReservaByIdWithEntityAndEvent(id);
  if ((await activeReservation(reservation)) === null) {
    console.log("Error activeReservationById");
    return false;
  }
  return true;
}

const extraControllers = {
  checkReservationCode: async (req, res, next) => {
    const params = extractParamsFromRequest(req, res, {});
    const appVersion = req && req.headers && req.headers["accept-version"] ? req.headers["accept-version"] : null;
    console.log("checkReservationCode - appVersion: ", appVersion);
    console.log("checkReservationCode - PARAMS ", params);

    const eventId = params.params.id;
    const encodedInvitationCode = params.params.encodedInvitationCode;

    const registrationCode = Buffer.from(req.params.encodedInvitationCode, "base64").toString("ascii");

    try {
      const result = await eventReservationService._getReservaByCode(eventId, registrationCode);

      console.log('>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>RESULT>>>>>>>>>>>>>>>>>>>>>>>>>><<', result);

      if (appVersion) {
        if (appVersion == "1.0.0" || appVersion == "1.0.1" || appVersion == "1.0.2")
          return handleResultResponse(!!result, null, params, res, httpStatus.OK);
        else return handleResultResponse(result, null, params, res, httpStatus.OK);
      } else return handleResultResponse(!!result, null, params, res, httpStatus.OK);
    } catch (error) {
      return handleErrorResponse(MODULE_NAME, "checkReservationCode", error, res);
    }
  },

  getReservationFromCode: async (req, res, next) => {
    const params = extractParamsFromRequest(req, res, {});
    const encodedInvitationCode = params.params.code;
    const registrationCode = Buffer.from(encodedInvitationCode, "base64").toString("ascii");

    try {
      const result = await eventReservationService._getReservaByOnlyCode(registrationCode);
      // No se ha encontrado
      if (!result)
         return handleResultResponse("Código de reserva no encontrado", null, params, res, httpStatus.NOT_FOUND)
  
      //MAPEO SALIDA API4
      //En lugar de estar quitando campo creamos un DTO nuevo con la información que nos interesa
      const Reservation = {
        id : result.id, 
        stateText : result.stateText, 
        code : result.reservation_code,    
        eventId : result.Event.id,
        eventName : result.Event.name,
        entityId : result.Entity.id,  
        entityName : result.Entity.name,  
      };
//      console.log('>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>RESULT>>>>>>>>>>>>>>>>>>>>>>>>>><<', Reservation);
        return handleResultResponse(Reservation, null, params, res, httpStatus.OK);

    } catch (error) {
      return handleErrorResponse(MODULE_NAME, "getReservationFromCode", error, res);
    }
  },

  getReservationsExcel: async (req, res, next) => {
    const params = extractParamsFromRequest(req, res, {});
    const eventId = params.params.id;
    const userId = req.user.id;
    let entityType = null;
    let entityId = null;
    //    console.log('params.params.typeOrId>>>>++++++++++++++++++++++++++ 1 ', params.params.typeOrId);
    //typeOrId puede ser college, partner o el id de la entidad de la reserva
    const typeOrId = params.params.typeOrId;
    if (typeOrId !== null) {
      if (typeOrId === "colleges" || params.params.typeOrId === "partners") entityType = typeOrId;
      else entityId = typeOrId;
    }
    //    console.log('params.params.typeOrId>>>>++++++++++++++++++++++++++ 2 ', entityId);
    //    console.log('params.params.typeOrId>>>>++++++++++++++++++++++++++ 3 ', entityType);

    const reservations = await eventReservationService._getReservationsExcel(
      req.user,
      eventId,
      entityId,
      entityType,
      function (result, status) {
        if (result.messenger.code == "S99001") {
          console.log(result);
          res.setHeader("Content-Type", "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
          res.setHeader("Content-Disposition", "attachment; filename=" + result.data.name);
          res.attachment(result.data.name);
          res.download(path.resolve(result.data.path), result.data.name);
        } else {
          res.status(status).json(result);
        }
      }
    );
  },

  sendMailReservation: async (req, res, next) => {
    const params = extractParamsFromRequest(req, res, {});
    const reservationId = params.params.id;
    const user = req.user;
    try {
      const reservation = await eventReservationService._getReservaByIdWithEntityAndEvent(reservationId);
      if (!reservation) return handleResultResponse("Reserva no encontrada", null, params, res, httpStatus.NOT_FOUND);

      try {
        if (reservation.Entity.contact_email)
          emailHelper.sendReservationCode(
            mailService.generateHeaderMailReservation(reservation),
            mailService.generateBodyMailReservation(reservation)
          );
      } catch (error) {
        //                console.log(error);
        console.log("No se ha podido mandar email con los códigos de invitación");
      }

      return handleResultResponse(null, null, params, res, httpStatus.OK);
    } catch (error) {
      return handleResultResponse("Error al buscar la reserva", null, params, res, httpStatus.NOT_FOUND);
    }
  },

  sendMailReservationsEvent: async (req, res, next) => {
    const params = extractParamsFromRequest(req, res, {});
    const eventId = params.params.id;
    const entityId = params.params.entityId;
    const type = params.params.type;
    const user = req.user;
    let reservations = null;
    let result = "";

    try {
      if (!entityId) reservations = await eventReservationService._getReservasByEventAndType(eventId, type);
      else reservations = await eventReservationService._getReservasByEventAndEntity(eventId, entityId);

      if (!reservations)
        return handleResultResponse("Reservas no encontradas", null, params, res, httpStatus.NOT_FOUND);

      try {
        reservations.forEach(function (reservation) {
          console.log("mando correo: ", reservation.Entity.name);
          if (reservation.Entity.contact_email && reservation.Entity.contact_email.length !== 0) {
            console.log("correo: ", reservation.Entity.contact_email);
            emailHelper.sendReservationCode(
              mailService.generateHeaderMailReservation(reservation),
              mailService.generateBodyMailReservation(reservation)
            );
            result =
              result +
              "Invitación con código " +
              reservation.reservation_code +
              " enviada a " +
              reservation.Entity.name +
              " al destinatario " +
              reservation.Entity.contact_email +
              "\n";
          } else result = result + "Invitación con código " + reservation.reservation_code + " no se ha enviado proque el correo (" + reservation.Entity.contact_email + ") no es válido\n";
        });
      } catch (error) {
        //                console.log(error);
        console.log("No se ha podido mandar email con los códigos de invitación");
      }

      return handleResultResponse(result, null, params, res, httpStatus.OK);
    } catch (error) {
      return handleResultResponse("Error al buscar las reservas", null, params, res, httpStatus.NOT_FOUND);
    }
  },

  recuperateReservationByCode: async (req, res, next) => {
    const params = extractParamsFromRequest(req, res, {});
    let dataInscription = res.locals.dataInscription;
    if (!dataInscription)
      return handleResultResponse(
        "Error recuperateReservationByCode, prepareDataInscription requerida",
        null,
        params,
        res,
        httpStatus.NOT_FOUND
      );
      console.log(">>>>>>>>>>>>>>>>>>>>  recuperateReservationByCode", dataInscription.type);
      
    //SI VIENE CODIGO DE RESERVA, RECUPERAMOS LA RESERVA Y EL EVENTO
    if (dataInscription.reservationCode) {
      try {
        dataInscription.reservation = await eventReservationService._getReservaByCode(
          dataInscription.eventId,
          dataInscription.reservationCode
        );
        if (dataInscription.reservation) {
          dataInscription.reservation = await dataInscription.reservation.toJSON();
          dataInscription.event = dataInscription.reservation.Event;
        } else {
          // No se ha encontrado
          return handleResultResponse("Código de reserva no encontrado", null, params, res, httpStatus.NOT_FOUND);
        }
        res.locals.dataInscription = dataInscription;
      } catch (error) {
        return handleErrorResponse(MODULE_NAME, "recuperateReservationByCode", error, res);
      }
    }
    next();
  },

  createReservationToEntity: async (req, res, next) => {
    console.log(">>>>>>>>>>>>>>>>>>>>  createReservationToEntity>>>> ",res.locals.dataUser);
    const params = extractParamsFromRequest(req, res, {});
    let dataInscription = res.locals.dataInscription;
    if (!dataInscription || !dataInscription.event)
      return handleResultResponse(
        "Error createReservationToEntity, prepareDataInscription, requerida",
        null,
        params,
        res,
        httpStatus.NOT_FOUND
      );
    let dataUser = res.locals.dataUser;
    if (!dataUser)
      return handleResultResponse(
        "Error createReservationToEntity, prepareDataInscription, getOrCreateUser requerida",
        null,
        params,
        res,
        httpStatus.NOT_FOUND
      );

    console.log(">>>>>>>>>>>>>>>>>>>>  createReservationToEntity>>>>>>", dataInscription.type);
    //Si viene group_size crearemos un código de reserva
    if (dataInscription.groupSize > 1) {
      if (!dataUser.entityId) {
        return handleResultResponse(
          "Error No es posible crear reserva grupal si no pertences a una entidad educativa",
          null,
          params,
          res,
          httpStatus.NOT_FOUND
        );
      }

      const reservationData = {
        reservation_code: eventReservationService._generateReservatioCode(dataInscription.event, dataUser.entityName),
        state: "draft", //sin confirmar, publish es cuando se descuenta del aforo del evento
        color: "orange",
        description: dataInscription.type === "online group" ? "Incripción online en grupo" : "Reserva",
        init_available_date: dataInscription.event.init_available_date,
        end_available_date: dataInscription.event.end_available_date,
        entityId: dataUser.entityId,
        eventId: dataInscription.event.id,
        gmt: dataInscription.event.gmt,
        assistants: dataInscription.groupSize,
        virtual: dataInscription.type === "online" || dataInscription.type === "online group",
        userId: dataUser.id,
        allow_overflow: false,
      };

      //Comprobamos aforo si no es online, si no es posible apuntarse iria a lista de espera
      if (dataInscription.type !== "online" && dataInscription.type !== "online group") {
        const plazasDisponibles = dataInscription.event.assistants - dataInscription.event.confirmed;
        if (plazasDisponibles < reservationData.assistants)
          if (dataInscription.event.allow_overflow) {
            reservationData.overflowEventId = dataInscription.event.overflow_eventId;
            reservationData.description = reservationData.description + " en lista de espera";
            console.log("Asigno lista de espera>>>>>>>>>>>>>>>>>>>>>>>", reservationData.eventId);
          } else
            return handleResultResponse(
              "Aforo lleno no es posible efectuar la reserva",
              null,
              params,
              res,
              httpStatus.NOT_FOUND
            );
      }

      ///Aqui podríamos validar si ya hay reserva y dar error ya que no pueden meter codigo de reserva y darnos un group_size superior a 1.
      dataInscription.reservation = await eventReservationService.create(
        reservationData,
        generateControllers.buildContext(req, {})
      );

      dataInscription.reservation = dataInscription.reservation.toJSON();
      res.locals.dataInscription = dataInscription;
      console.log(">>>>>>>>>>>>>>>>>>>>>>>>>>>>RESERVATION CREADA", dataInscription.reservation);
    } else console.log(">>>>>>>>>>>>>>>>>>>>>>>>>>>>no hago nada");
    next();
  },

  activeReservationToEntity: async (req, res, next) => {
    const params = extractParamsFromRequest(req, res, {});
    let dataInscription = res.locals.dataInscription;
    let dataUser = res.locals.dataUser;
    if (!dataUser || !dataInscription || !dataInscription.event)
      return handleResultResponse(
        "Error createReservationToEntity, prepareDataInscription, ActiveReservationToEntity requerida",
        null,
        params,
        res,
        httpStatus.NOT_FOUND
      );

    //En caso de ser online no descontamos ningun aforo ya que no se controla de momento
    if (dataInscription.type === "online" || dataInscription.type === "online group") {
      console.log(">> No se aplica descuento de aforo");
      next();
      return;
    }

    //En caso de ser una inscripción normal o una reserva ya publicada no descontamos ningun aforo al evento
    if (!dataInscription.reservation || dataInscription.reservation.state === "publish") {
      // || (!dataInscription.reservationCode) || (dataInscription.reservationCode === "")) {
      console.log(">> No se aplica descuento de aforo ya que es una reserva publicada");
      next();
      return;
    }

    //Si es centro aliado
    if (dataUser.entityLevel === "aliado") {
      //Aseguramos que la reserva vaya con su evento
      dataInscription.reservation.Event = dataInscription.event;
      const reservationPublicada = await activeReservation(dataInscription.reservation);
      if (reservationPublicada === null)
        return handleResultResponse(
          "Error activeReservationToEntity requerida",
          null,
          params,
          res,
          httpStatus.NOT_FOUND
        );
      else dataInscription.reservation = reservationPublicada;
    }

    next();
  },

  activarReservation: async (req, res, next) => {
    const params = extractParamsFromRequest(req, res, {});
    const idResevation = params.params.id;
    if (!idResevation)
      return handleResultResponse("Error id de reservation necesario", null, params, res, httpStatus.NOT_FOUND);

    try {
      let result = await activeReservationById(idResevation);
      return handleResultResponse(result, null, params, res, httpStatus.OK);
    } catch (error) {
      console.log(
        "********************************************************************************************",
        error
      );
      //return handleResultResponse("Error al buscar las reservas", null, params, res, httpStatus.NOT_FOUND);
      return handleErrorResponse("activarReservation", "methodName", error.stack, res);
    }
  },

  deleteReservationById: async (req, res, next) => {
    const params = extractParamsFromRequest(req, res, {});
    const idResevation = params.params.id;
    if (!idResevation)
      return handleResultResponse("Error id de reservation necesario", null, params, res, httpStatus.NOT_FOUND);

    const eventReservation = await eventReservationService._getReservaById(idResevation);
    if (!eventReservation)
      return handleResultResponse("Error reserva no existente", null, params, res, httpStatus.NOT_FOUND);

    try {
      //Antes de borrar una reserva debemos borrar todas las inscripciones asociadas.
      eventInscriptionService._deleteInscriptionsByReservation(eventReservation.id);
      if (eventReservation.state === "publish") {
        const cantidad = -1 * eventReservation.assistants;
        eventService._updateAforoOfEventReservation(eventReservation, cantidad);
      }

      let result = eventReservationService._deleteReservation(eventReservation.id);
      return handleResultResponse(result, null, params, res, httpStatus.OK);
    } catch (error) {
      return handleResultResponse("Error al eliminar la reserva", null, params, res, httpStatus.NOT_FOUND);
    }
  },

  /**** Modifica una reserva, si está publicada, actualiza la diferenecia de los asistentes, en el caso de ser modificado, en el aforo del evento (assitants).
   */
  checkAssitantsUpdate: async (req, res, next) => {
    const params = extractParamsFromRequest(req, res, {});
    const idResevation = params.params.id;
    const NewReservarionAssistants = req.body.assistants;

    if (!idResevation)
      return handleResultResponse("Error id de reservation necesario", null, params, res, httpStatus.NOT_FOUND);

    const eventReservation = await eventReservationService._getReservaById(idResevation); //
    if (!eventReservation)
      return handleResultResponse("Error reserva no existente", null, params, res, httpStatus.NOT_FOUND);

    try {
      if (eventReservation.state === "publish" && eventReservation.assistants != NewReservarionAssistants) {
        if (NewReservarionAssistants < eventReservation.confirmed) {
          return handleResultResponse(
            "Error el número de asistentes no puede ser menor que el de confirmados",
            null,
            params,
            res,
            httpStatus.NOT_FOUND
          );
        }

        const cantidad = NewReservarionAssistants - eventReservation.assistants;
        await eventService._updateAforoOfEventReservation(eventReservation, cantidad);
      }

      next();
    } catch (error) {
      //console.log('checkAssitantsUpdate >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>', error.stack);
      return handleErrorResponse("controllerName", "methodName", error.stack, res);
    }
  },

  ///////////////////////////////////////////////////////////////////
  //Esta función se llama desde APP y desde WEB
  //Inscripción con CODIGO DE RESERVA, SE MODIFICA EL CONFIRMED DE LA RESERVA, YA QUE SE DESCONTARA DEL AFORO DE LA RESERVA
  // en caso de online, funciona igual ya que descontará la inscripción de la persona del aforo quedando la inscripción online asociada a la reserva
  ///////////////////////////////////////////////////////////////////
  createInscriptionReservation: async (req, res, next) => {
    console.log(">>>>>>>>>>>>>>>>>>>>  createInscriptionReservation (event_reservations.controller)");
    const params = extractParamsFromRequest(req, res, {});

    let dataInscription = res.locals.dataInscription;
    if (!dataInscription || !dataInscription.event || !dataInscription.reservation)
      return handleResultResponse(
        "Error prepareDataInscription, recuperateReservationByCode o createReservationToEntity requerida",
        null,
        params,
        res,
        httpStatus.NOT_FOUND
      );

    let dataUser = res.locals.dataUser;
    if (!dataUser)
      return handleResultResponse("Error getOrCreateUser requerida", null, params, res, httpStatus.NOT_FOUND);

    try {
      //CON CODIGO DE RESERVA SE MODIFICA EL CONFIRMED DE LA RESERVA, YA QUE SE DESCONTARA DEL AFORO DE LA RESERVA
      dataInscription.inscriptionsWithReservationCount =
        await eventInscriptionService._getCountInscriptionsWithReservation(dataInscription.reservation.id);
      ++dataInscription.inscriptionsWithReservationCount;

      /*console.log(
        "me inscribo por reserva>>>>>>>>>>>>>>>>>>>>>>>>>>><< con asistentes: ",
        dataInscription
      );
      console.log(dataInscription.reservation.sold_out);
      console.log(dataInscription.inscriptionsWithReservationCount);
*/
      //COMPROBAMOS SI ES VALIDO O HAY QUE APUNTARLE A LA LISTA DE ESPERA DE LA RESERVA
      if (
        dataInscription.reservation.sold_out == 0 &&
        dataInscription.reservation.assistants >= dataInscription.inscriptionsWithReservationCount
      ) {
        dataInscription.validated = false;
        //Es la inscripción automática del tutor o alguien que tiene el código y eso no puede ser
        if (
          dataInscription.type === "online" ||
          dataInscription.type === "online group" ||
          dataInscription.reservation.state === "publish"
        )
          dataInscription.validated = true;

        console.log(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>", dataInscription.type);
        //Actualizamos aforo de la lista de espera de la reserva y creamos inscripcion en la lista de espera de la reserva
        if (
          await eventReservationService._updateConfirmedReservation(
            dataInscription.reservation.id,
            dataInscription.inscriptionsWithReservationCount
          )
        )
          dataInscription.inscription = await eventInscriptionService._createInscription(
            dataInscription.event.id,
            dataUser.id,
            dataInscription.type,
            dataInscription.validated,
            dataInscription.source,
            dataInscription.reservation.id,
            null
          );
        else
          return handleResultResponse(
            "No se ha podido actualizar el aforo de la reserva",
            null,
            params,
            res,
            httpStatus.NOT_FOUND
          );

        //Ponemos la reserva en SOLD_OUT para que no se pueda apuntar nadie más
        if (dataInscription.reservation.assistants == dataInscription.inscriptionsWithReservationCount)
          await eventReservationService._updateSoldOutReservation(dataInscription.reservation.id, true);
      }
      // APUNTARSE A LISTA DE ESPERA SI SE PUEDE
      else {
        if (dataInscription.reservation.allow_overflow === true) {
          dataInscription.validated = false;
          dataInscription.inscriptionsWithReservationCount =
            await eventInscriptionService._getCountInscriptionsWithReservation(
              dataInscription.reservation.overflow_reservationId
            );
          ++dataInscription.inscriptionsWithReservationCount;

          //                            if (dataInscription.reservation.assistants >= dataInscription.inscriptionsWithReservationCount) {
          //Actualizamos aforo de la reserva y creamos inscripcion
          if (
            await eventReservationService._updateConfirmedReservation(
              dataInscription.reservation.overflow_reservationId,
              dataInscription.inscriptionsWithReservationCount
            )
          )
            dataInscription.inscription = await eventInscriptionService._createInscription(
              dataInscription.event.id,
              dataUser.userResult.user.id,
              dataInscription.type,
              dataInscription.validated,
              dataInscription.source,
              dataInscription.reservation.overflow_reservationId,
              null
            );
          else
            return handleResultResponse(
              "No se ha podido actualizar el aforo de la reserva",
              null,
              params,
              res,
              httpStatus.NOT_FOUND
            );
        } else
          return handleResultResponse(
            "Aforo completo de la reserva y no hay lista de espera",
            null,
            params,
            res,
            httpStatus.NOT_FOUND
          );
      }
      let Result = await dataInscription.inscription.toJSON();
      Result = {
        reservation: dataInscription.reservation,
        ...Result,
      };

      //    Incluimos correo en sendinblue
      try {
        //        marketingListService.addMarketingList(dataUser, dataInscription);
      } catch (error) {
        console.log("Se ha producido un error al añadir a SenINBlue>>>>>>>>>>>>>>>>><<", error);
      }

      //Mandamos correo con entrada o lista de espera
      try {
        mailService.sendEmailConfirm(dataUser, dataInscription);
      } catch (error) {
        console.log("Se ha producido un error al enviar mail>>>>>>>>>>>>>>>>><<", error);
      }

      //MAPEO SALIDA API4
      //Tratamos resultado, si hay que remover campos para API4 web
      if (res.locals.v4){
        const arrayFieldsremove = res.locals.v4.removeFields;
        arrayFieldsremove.forEach(campo => {
          if (campo in Result) {
              delete Result[campo];
          }
        });
      };

      return handleResultResponse(Result, null, params, res, httpStatus.CREATED);
    } catch (error) {
      return handleResultResponse("Error al crear la incripción online", null, params, res, httpStatus.NOT_FOUND);
    }
  },
};

module.exports = generateControllers(eventReservationService, extraControllers, controllerOptions);
