const routes = require("express").Router();

const { isAdministratorUser, isLoggedUser, isOptionalUser } = require("../../middlewares/accessValidator");
const SchemaValidator = require("../../middlewares/schemaValidator");

const { cacheSuccesses } = require("../../middlewares/cache");
const PaginateMiddleware = require("../../middlewares/paginate");
const FieldMiddleware = require("../../middlewares/fields");
const SortMiddleware = require("../../middlewares/sort");

const authController = require("../auth/auth.controller");
const eventController = require("./event.controller");
const eventInscriptionController = require("./events_inscriptions.controller");
const eventReservationController = require("./events_reservations.controller");
const eventQuestionController = require("./events_questions.controller");
const eventValidation = require("./event.validations");

const generalInvalidFields = [
  "userId",
  "createdAt",
  "updatedAt",
  "assistants",
  "confirmed",
  "allow_multiple",
  "overflow_eventId",
  "state",
  "confirmed",
  "multiple_limit",
  "marketing_list",
];

routes.get(
  "/events",
  isOptionalUser,
  FieldMiddleware.middleware({
    invalidFields: generalInvalidFields,
  }),
  PaginateMiddleware.middleware(),
  SortMiddleware.middleware({ default: "-init_date" }),
  (req, res, next) => {
    if (!req.body.locationId)
      return eventController.find({
        scopes: ["defaultScope", "includeVenue", "includeMultimedias", "includeDetails"],
      })(req, res, next);
    else
      return eventController.find({
        scopes: [
          "defaultScope",
          "includeVenue",
          "includeMultimediaAvatar",
          "includeDetails",
          { method: ["onlyOfLocation", req.body.locationId] },
        ],
      })(req, res, next);
  }
);

routes.get(
  "/events/cities",
  isOptionalUser,
  cacheSuccesses("24 hours"),
  eventController.find({
    scopes: ["CitiesOfEvents"],
  })
);

// Esta ruta se dejará de usar a favor de "/events/next_by_country"
routes.get(
  "/events/next",
  isOptionalUser,
  FieldMiddleware.middleware({
    invalidFields: generalInvalidFields,
  }),
  PaginateMiddleware.middleware(),
  SortMiddleware.middleware({ default: "init_available_date" }),
  (req, res, next) => {
    const isLogged = req.user && req.user.id;
    const scopes = ["defaultScope", "next", "includeVenue", "includeMultimedias"];
    if (isLogged) {
      scopes.push({ method: ["includeInscription", req.user.id] });
    }
    return eventController.find({ scopes })(req, res, next);
  }
);

// Sustituye a "/events/next" a partir de la versión de la APP 1.4.4
routes.get(
  "/events/next_by_country",
  isOptionalUser,
  FieldMiddleware.middleware({
    invalidFields: generalInvalidFields,
  }),
  PaginateMiddleware.middleware(),
  SortMiddleware.middleware({ default: "init_available_date" }),
  (req, res, next) => {
    const isLogged = req.user && req.user.id;
    const scopes = ["defaultScope", "next", "includeVenue", "includeMultimedias"];
    if (isLogged) {
      scopes.push({ method: ["includeInscription", req.user.id] });
    }
    return eventController.findNextEventsByCountry({ scopes })(req, res, next);
  }
);

routes.get(
  "/events/past",
  isOptionalUser,
  cacheSuccesses("1 minute"),
  FieldMiddleware.middleware({
    invalidFields: generalInvalidFields,
  }),
  PaginateMiddleware.middleware(),
  SortMiddleware.middleware({ default: "-init_date" }),
  eventController.find({
    scopes: ["defaultScope", "past", "includeVenue", "includeMultimedias", "includeDetails"],
  })
);

routes.get(
  "/events/yesterday",
  isOptionalUser,
  FieldMiddleware.middleware({
    invalidFields: generalInvalidFields,
  }),
  PaginateMiddleware.middleware(),
  SortMiddleware.middleware({ default: "-init_date" }),
  eventController.find({
    scopes: ["defaultScope", "yesterday", "includeVenue", "includeMultimedias", "includeDetails"],
  })
);

routes.get(
  "/events/today",
  isOptionalUser,
  FieldMiddleware.middleware({
    invalidFields: generalInvalidFields,
  }),
  PaginateMiddleware.middleware(),
  SortMiddleware.middleware({ default: "-init_date" }),
  eventController.find({
    scopes: ["defaultScope", "today", "includeVenue", "includeMultimedias", "includeDetails"],
  })
);

/*routes.get('/events/today',
    isLoggedUser,
    FieldMiddleware.middleware({
        invalidFields: generalInvalidFields
    }),
    PaginateMiddleware.middleware(),
    SortMiddleware.middleware({ default: "-init_date" }),

    (req, res, next) => {
        eventController.find({
            scopes: ['defaultScope', 'next', 'includeVenue', 'includeMultimedias', { method: ['includeInscription', req.user.id] }],
            })(req, res, next)
        .then (function (events) {
            console.log('>>>> ', events); //.stateCode = 'current_event';
            return events;
        });

    } 
);*/

routes.get(
  "/events/tomorrow",
  isOptionalUser,
  FieldMiddleware.middleware({
    invalidFields: generalInvalidFields,
  }),
  PaginateMiddleware.middleware(),
  SortMiddleware.middleware({ default: "-init_date" }),
  eventController.find({
    scopes: ["defaultScope", "tomorrow", "includeVenue", "includeMultimedias", "includeDetails"],
  })
);

routes.get(
  "/events/current",
  isOptionalUser,
  FieldMiddleware.middleware({
    invalidFields: generalInvalidFields,
  }),
  PaginateMiddleware.middleware(),
  SortMiddleware.middleware({ default: "-init_date" }),
  eventController.find({
    scopes: ["defaultScope", "current", "includeVenue", "includeMultimedias", "includeDetails"],
  })
);

// Eventos destacados
routes.get(
  "/events/featured",
  isOptionalUser,
  cacheSuccesses("1 minute"),
  FieldMiddleware.middleware({
    invalidFields: generalInvalidFields,
  }),
  PaginateMiddleware.middleware(),
  SortMiddleware.middleware({ default: "-init_date" }),
  eventController.find({
    scopes: ["defaultScope", "includeVenue", "includeMultimediaAvatar", "featured"],
  })
);

routes.get(
  "/events/:id",
  isOptionalUser,
  FieldMiddleware.middleware({
    invalidFields: generalInvalidFields,
  }),
  (req, res, next) => {
    const isLogged = req.user && req.user.id;
    const scopes = ["defaultScope", "includeVenue", "includeMultimedias", "includeDetails", "includeComments"];
    if (isLogged) {
      scopes.push({ method: ["includeInscription", req.user.id] });
    }

    return eventController.findOne({ scopes })(req, res, next);
  }
);

// Comentarios

routes.get(
  "/events/:id/comments",
  isOptionalUser,
  (req, res, next) => {
    req.params.association = "Comments";
    next();
  },
  eventController.find
);

// Multimedias
routes.get(
  "/events/:id/multimedias",
  isOptionalUser,
  (req, res, next) => {
    req.params.association = "Multimedias";
    next();
  },
  eventController.find
);

// Comprobar capacidad del grupo
routes.get("/events/:id/check_capacity", isOptionalUser, eventController.checkCapacity);

// Inscripciones
// Esto da las inscripciones de un usuario
routes.get("/events/:id/inscriptions", isLoggedUser, eventController.getInscriptions);

// Esto da todas las inscripciones de un usuario
routes.get(
  "/me/inscriptions/count",
  isLoggedUser,
  /*(req, res, next) => {
        req.apicacheGroup = req.user.id;
        next();
    },
    cacheSuccesses('1 hour'),*/
  eventController.getInscriptionsOfNextEventsCount
);

// Esto da todas las inscripciones de un usuario
routes.get(
  "/me/inscriptions",
  isLoggedUser,
  /*(req, res, next) => {
        req.apicacheGroup = req.user.id;
        next();
    },
    cacheSuccesses('1 hour'),*/
  eventController.getInscriptions
);

routes.get(
  "/me/inscriptions/:id/mail",
  isLoggedUser,
  //cacheSuccesses('1 hour'),
  eventController.sendMailTicket
);

// Esto da la inscripción de un usuario
routes.get(
  "/me/inscriptions/:id",
  isLoggedUser,
  /*(req, res, next) => {
        req.apicacheGroup = req.user.id;
        next();
    },
    cacheSuccesses('1 hour'),*/
  eventInscriptionController.getInscription
);

// Hacer una inscripción
routes.post(
  "/events/:id/inscriptions",
  isLoggedUser,
  SchemaValidator(eventValidation.InscriptionInputType, true),
  //Prepara los datos de la inscripción tipo ....
  eventInscriptionController.prepareDataInscription,
  //Recupera la reservation si viene
  eventReservationController.recuperateReservationByCode,
  //Recupera a registra el usuario que se va a inscribir
  authController.getOrCreateUser,
  //Comprobamos si tiene ya una incripción, en tal caso, comprobamos el código de reserva sea el de la inscripcion hecha,
  //si no es así es el caso de un usuario que se reinscribe con otro código de reserva
  eventInscriptionController.checkInscriptionByUser,
  //Si es un usuario tutor y solicita un group_size se crea la reserva
  eventReservationController.createReservationToEntity,
  eventReservationController.activeReservationToEntity,

  (req, res, next) => {
    if (res.locals.dataInscription.reservation) {
      console.log(">>>>>>>Incripcion con reserva");
      eventReservationController.createInscriptionReservation(req, res, next);
    } else {
      console.log(">>>>>>>Incripcion sin reserva");
      eventInscriptionController.createInscription(req, res, next);
    }
    //next();
  }
  //  eventInscriptionController.createInscriptionMarketingList
);

// Hacer una pregunta
routes.post(
  "/events/:eventId/questions",
  isLoggedUser,
  SchemaValidator(eventValidation.EventQuestionInputType, true),
  eventQuestionController.create()
);

// Borrar una inscripción
routes.delete(
  "/inscriptions/:id",
  isLoggedUser,
  //SchemaValidator(eventValidation.InscriptionInputType, true),
  eventInscriptionController.deleteInscription
);

// Imagen del código QR de una inscripción
routes.get("/inscriptions/:id/qrimage", eventController.getQRCodeImage);

// Comprobar el código de invitación
routes.get(
  "/events/:id/reservations/:encodedInvitationCode",
  isLoggedUser,
  //eventController.findComments
  eventReservationController.checkReservationCode
);

//WEB

//Eventos con inscripciones abiertas para la web
routes.get(
  "/web/events",
  //    isLoggedUser,
  FieldMiddleware.middleware({
    validFields: ["id", "name"],
  }),
  //    PaginateMiddleware.middleware(),
  //    SortMiddleware.middleware({ default: "init_available_date" }),
  eventController.find({
    scopes: ["defaultScope", "withOpenInscriptions"],
  })

);

// Hacer una inscripción por la web
routes.post(
  "/web/events/:id/inscriptions",
  SchemaValidator(eventValidation.webInscriptionInputType, true),
  //Prepara los datos de la inscripción tipo ....
  eventInscriptionController.prepareDataInscription,
  //Recupera la reservation si viene
  eventReservationController.recuperateReservationByCode,
  //Recupera a registra el usuario que se va a inscribir
  authController.getOrCreateUser,
  //Comprobamos si tiene ya una incripción, en tal caso, comprobamos el código de reserva sea el de la inscripcion hecha,
  //si no es así es el caso de un usuario que se reinscribe con otro código de reserva
  eventInscriptionController.checkInscriptionByUser,
  //Al ser via web siempre será inscripción con codigo de reserva
  (req, res, next) => {
    eventReservationController.createInscriptionReservation(req, res, next);
  }
);

// Comprobar si estoy inscrito al congreso por la web
routes.get("/web/events/:id/inscriptions/:email", eventInscriptionController.checkInscriptionByMail);

/*
routes.get('/tickets/:id/',
    isLoggedUser,
    eventController.findComments
);
*/

//routes.get('/venues', isLoggedUser, SortMiddleware.middleware({ default: "name" }), venueController.find);
//routes.get('/venues/:id', isLoggedUser, venueController.findOne);

//routes.post('/entity/', SchemaValidator(VenueValidation.VenueInputType, true), venueController.create);
//routes.put('/venues/:id', isAdministratorUser, venueController.update);
//routes.delete('/venues/:id', isAdministratorUser, venueController.delete);

/********************************************************************************************************
 *  ADMINISTRACIÓN
 *********************************************************************************************************
 */
// Inscripciones
// Esto da las inscripciones de un evento
routes.get("/admin/events/:id/inscriptions/online", isAdministratorUser, eventController.getInscriptionsOnline);
routes.get("/admin/events/:id/inscriptions", isAdministratorUser, eventController.getInscriptions);

// Todos los ponentes
routes.get(
  "/admin/events",
  isAdministratorUser,
  PaginateMiddleware.middleware(),
  SortMiddleware.middleware({ default: "-init_date" }),
  (req, res, next) => {
    if (!req.body.city)
      return eventController.find({
        scopes: ["defaultScope", "includeVenue", "includeMultimedias", "includeDetails"],
      })(req, res, next);
    else
      return eventController.find({
        scopes: [
          "defaultScope",
          "includeVenue",
          "includeMultimedias",
          "includeDetails",
          { method: ["onlyOfCity", req.body.city] },
        ],
      })(req, res, next);
  }
);

routes.get(
  "/admin/events/next",
  isAdministratorUser,
  PaginateMiddleware.middleware(),
  SortMiddleware.middleware({ default: "init_available_date" }),
  eventController.find({
    scopes: ["defaultScope", "next", "includeVenue", "includeMultimedias", "includeDetails"],
  })
);

routes.get(
  "/admin/events/past",
  isAdministratorUser,
  PaginateMiddleware.middleware(),
  SortMiddleware.middleware({ default: "-init_date" }),
  eventController.find({
    scopes: ["defaultScope", "past", "includeVenue", "includeMultimedias", "includeDetails"],
  })
);

routes.get(
  "/admin/events/current",
  isAdministratorUser,
  PaginateMiddleware.middleware(),
  SortMiddleware.middleware({ default: "-init_date" }),
  eventController.find({
    scopes: ["defaultScope", "current", "includeVenue", "includeMultimedias", "includeDetails"],
  })
);

routes.get("/admin/events/:id", isAdministratorUser, (req, res, next) => {
  return eventController.findOne({
    scopes: ["defaultScope", "includeVenue", "includeMultimedias", "includeOverflowEvent", "includeDetails"],
  })(req, res, next);
});

routes.get("/admin/events/:id/partners", isAdministratorUser, eventController.findPartners);

routes.get("/admin/events/:id/colleges", isAdministratorUser, eventController.findColleges);

routes.get(
  "/admin/events/:id/reservations/excel",
  isAdministratorUser,
  eventReservationController.getReservationsExcel
);

routes.get(
  "/admin/events/:id/syncMarketingList",
  //isAdministratorUser,
  eventController.syncronizeMarketingList
);

routes.get(
  "/admin/events/:id/reservations/:typeOrId/excel",
  isAdministratorUser,
  eventReservationController.getReservationsExcel
);

routes.get("/admin/events/:id/inscriptions/excel", isAdministratorUser, eventController.getInscripcionsExcel);

routes.get(
  "/admin/events/:id/reservations/:type/mail",
  isAdministratorUser,
  eventReservationController.sendMailReservationsEvent
);

routes.get(
  "/admin/events/:id/entity/:entityId/reservations/mail",
  isAdministratorUser,
  eventReservationController.sendMailReservationsEvent
);

routes.get(
  "/admin/events/:eventId/partners/:entityId/reservations",
  isAdministratorUser,
  eventReservationController.find()
);

routes.get(
  "/admin/events/:eventId/questions",
  isAdministratorUser,
  //    PaginateMiddleware.middleware(),
  SortMiddleware.middleware({ default: "-createdAt" }),
  eventQuestionController.find({
    scopes: ["includeUser", "includeSpeaker"],
  })
);

routes.get(
  "/admin/reservations/:id",
  isAdministratorUser,
  //SchemaValidator(eventValidation.ReservationInputType, true),
  (req, res, next) => {
    return eventReservationController.findOne({
      scopes: ["includeEvent", "includeInscriptions"],
    })(req, res, next);
  }
);

routes.get(
  "/admin/inscriptions/:id/mail",
  isAdministratorUser,
  //cacheSuccesses('1 hour'),
  eventController.sendMailTicket
);

routes.get("/admin/reservations/:id/mail", isAdministratorUser, eventReservationController.sendMailReservation);

routes.post(
  "/admin/reservations",
  isAdministratorUser,
  //SchemaValidator(eventValidation.ReservationInputType, true),
  eventReservationController.create()
);

routes.put(
  "/admin/reservations/:id",
  isAdministratorUser,
  //SchemaValidator(eventValidation.ReservationInputType, true),
  eventReservationController.checkAssitantsUpdate,
  eventReservationController.update()
);

routes.put(
  "/admin/reservations/:id/activate",
  //  isAdministratorUser,
  //SchemaValidator(eventValidation.ReservationInputType, true),
  eventReservationController.activarReservation
);

//Valida una inscripción
routes.put(
  "/admin/inscriptions/:id",
  isAdministratorUser,
  //SchemaValidator(eventValidation.ReservationInputType, true),
  eventController.validateInscription
);

// Borrar reserva
routes.delete("/admin/reservations/:id", isAdministratorUser, eventReservationController.deleteReservationById);

/********************************************************************************************************
 *  LIVE
 *********************************************************************************************************
 */
routes.get(
  "/live/events/:id",
  FieldMiddleware.middleware({
    invalidFields: generalInvalidFields,
  }),
  (req, res, next) => {
    return eventController.findOne({
      scopes: ["defaultScope", "includeVenue", "includeMultimedias", "includeDetails"],
    })(req, res, next);
  }
);

routes.get(
  "/live/events/:eventId/speakers/:speakerId/questions",
  SortMiddleware.middleware({ default: "-createdAt" }),
  eventQuestionController.find({
    scopes: ["includeUser", "includeSpeaker"],
  })
);

routes.put("/live/questions/:id", eventQuestionController.update());

module.exports = routes;
