import express from "express";
import {
  auth,
  forgotPassword,
  login,
  register,
  preRegisterDomiciliation,
  resetPassword,
  sendRegisterToken,
  validateToken,
  webhook,
  editProfile,
  changePassword,
  unregister,
  changePasswordConfirmation,
  validateDocument,
  getUser,
  getAllUsers,
  updateProfile,
  getUserById,
  editUser,
  getAccounts,
  getDocuments,
  downloadDocument,
  updateProfiles,
  subscribePush,
  unsubscribePush,
  deleteUser,
  getList,
  verifySession,
  getTermsAndConditions,
  changeStatus,
  createDiditSession,
  getFrequentQuestions,
  getProfile,
  editProfileConfirmation,
  testSms,
  updateFees,
  refreshToken,
  updateCountry,
  testClientUpdate,
  getClientStatistics,
  getNotificationsConfig,
  editNotificationsConfig,
} from "../controllers/userController";
import { authorizeModules, verifyToken } from "../middlewares/authJwt";
import {
  createAccountForUser,
  deleteAccountForUser,
} from "../controllers/accountController";

const routes = express.Router();

/**
 * @swagger
 * tags:
 *   name: Users
 *   description: Autenticación, registro y gestión de usuarios/clientes
 */

/**
 * @swagger
 * /users/login:
 *   post:
 *     operationId: userLogin
 *     tags: [Users]
 *     summary: Login de usuario
 *     requestBody:
 *       required: true
 *       content:
 *         application/json:
 *           schema:
 *             type: object
 *             required: [email, password]
 *             properties:
 *               email:
 *                 type: string
 *                 format: email
 *               password:
 *                 type: string
 *               rememberMe:
 *                 type: boolean
 *                 default: false
 *           example:
 *             email: "maria@ejemplo.com"
 *             password: "Secret123!"
 *             rememberMe: false
 *     responses:
 *       200:
 *         description: Login exitoso
 *         content:
 *           application/json:
 *             schema:
 *               type: object
 *               required: [success, message, data]
 *               properties:
 *                 success:
 *                   type: boolean
 *                   example: true
 *                 message:
 *                   type: string
 *                   example: "Login successful"
 *                 data:
 *                   type: object
 *                   properties:
 *                     id:
 *                       type: string
 *                     name:
 *                       type: string
 *                     lastname:
 *                       type: string
 *                     email:
 *                       type: string
 *                     level:
 *                       type: integer
 *                     points:
 *                       type: number
 *                     maxAmount:
 *                       type: number
 *                     availableAmount:
 *                       type: number
 *                     allowedFeeCount:
 *                       type: array
 *                       items:
 *                         type: integer
 *                     nextLevelPoints:
 *                       type: number
 *                     accessToken:
 *                       type: string
 *                     refreshToken:
 *                       type: string
 *             example:
 *               success: true
 *               message: "Login successful"
 *               data:
 *                 id: "697a3444cbaf4353acfa0132"
 *                 name: "María Alejandra"
 *                 lastname: "González"
 *                 email: "maria@ejemplo.com"
 *                 level: 1
 *                 points: 107.44
 *                 maxAmount: 100
 *                 availableAmount: 99.16
 *                 allowedFeeCount: [6]
 *                 accessToken: "eyJhbGciOiJIUzI1NiIs..."
 *                 refreshToken: "eyJhbGciOiJIUzI1NiIs..."
 *       400:
 *         description: Campos requeridos faltantes
 *         content:
 *           application/json:
 *             schema:
 *               type: object
 *               properties:
 *                 success:
 *                   type: boolean
 *                   example: false
 *                 message:
 *                   type: string
 *                   example: "Correo y contraseña son requeridos."
 *                 code:
 *                   type: string
 *                   example: "field_missing"
 *       401:
 *         description: Credenciales inválidas o usuario no activo
 *         content:
 *           application/json:
 *             schema:
 *               type: object
 *               properties:
 *                 success:
 *                   type: boolean
 *                   example: false
 *                 message:
 *                   type: string
 *                 code:
 *                   type: string
 *                   enum: [user_not_found, user_not_verified, invalid_password, user_pending, user_inactive]
 *             examples:
 *               user_not_found:
 *                 summary: Correo no registrado
 *                 value:
 *                   success: false
 *                   message: "El correo ingresado no esta registrado en Pasta."
 *                   code: "user_not_found"
 *               invalid_password:
 *                 summary: Contraseña incorrecta
 *                 value:
 *                   success: false
 *                   message: "La contraseña ingresada es incorrecta."
 *                   code: "invalid_password"
 *               user_pending:
 *                 summary: Usuario pendiente de aprobación
 *                 value:
 *                   success: false
 *                   message: "El estatus del usuario esta pendiente por aprobación"
 *                   code: "user_pending"
 */
routes.route("/login").post(login);

/**
 * @swagger
 * /users/register:
 *   post:
 *     operationId: userRegister
 *     tags: [Users]
 *     summary: Registrar usuario
 *     requestBody:
 *       required: true
 *       content:
 *         application/json:
 *           schema:
 *             type: object
 *             required: [email, password, name, lastname, document, phone]
 *             properties:
 *               name:
 *                 type: string
 *                 description: Nombres
 *                 example: "María Alejandra"
 *               lastname:
 *                 type: string
 *                 description: Apellidos
 *                 example: "González Rodríguez"
 *               document:
 *                 type: string
 *                 description: Número de documento
 *                 example: "12345678"
 *               birthDate:
 *                 type: string
 *                 format: date
 *                 description: Fecha de nacimiento
 *                 example: "1990-05-15"
 *               gender:
 *                 type: string
 *                 description: Género (M/F)
 *                 example: "F"
 *               maritalStatus:
 *                 type: string
 *                 description: Estado civil
 *                 example: "married"
 *               selfEmployed:
 *                 type: boolean
 *                 description: Si es autoempleado
 *                 example: false
 *               enterprise:
 *                 type: object
 *                 description: Datos de empresa
 *                 properties:
 *                   name:
 *                     type: string
 *                     description: Nombre de empresa
 *                   address:
 *                     type: string
 *                     description: Dirección de empresa
 *                   phone:
 *                     type: string
 *                     description: Teléfono de empresa
 *                   position:
 *                     type: string
 *                     description: Posición laboral
 *               occupation:
 *                 type: string
 *                 description: Ocupación
 *                 example: "Ingeniera"
 *               dependents:
 *                 type: integer
 *                 description: Dependientes (seleccionador)
 *                 example: 2
 *               seniority:
 *                 type: integer
 *                 description: Antigüedad de empleo (seleccionador)
 *                 example: 2
 *               income:
 *                 type: integer
 *                 description: Ingresos (seleccionador)
 *                 example: 3
 *               otherIncome:
 *                 type: integer
 *                 description: Otros ingresos (seleccionador)
 *                 example: 0
 *               education:
 *                 type: string
 *                 description: Nivel educativo
 *                 example: "bachelor"
 *               phone:
 *                 type: object
 *                 description: Datos de teléfono
 *                 properties:
 *                   countryCode:
 *                     type: string
 *                     description: Código de país
 *                     example: "58"
 *                   areaCode:
 *                     type: string
 *                     description: Código de área
 *                     example: "212"
 *                   number:
 *                     type: string
 *                     description: Número de teléfono
 *                     example: "5551234"
 *               email:
 *                 type: string
 *                 example: "maria.gonzalez@ejemplo.com"
 *               password:
 *                 type: string
 *                 example: "Secret123!"
 *               sessionId:
 *                 type: string
 *                 description: ID de sesión
 *                 example: "a1b2c3d4-e5f6-7890-abcd-ef1234567890"
 *               account:
 *                 type: object
 *                 description: Datos de cuenta bancaria
 *                 properties:
 *                   type:
 *                     type: string
 *                     description: Tipo de cuenta (checking/savings)
 *                     example: "checking"
 *                   code:
 *                     type: string
 *                     description: Código de banco
 *                     example: "0102"
 *                   number:
 *                     type: string
 *                     description: Número de cuenta
 *                     example: "01020123456789012345"
 *               token:
 *                 type: string
 *                 description: Token de verificación
 *                 example: "4567"
 *               pep:
 *                 type: boolean
 *                 description: Si el cliente conoce un PEP
 *                 example: false
 *               pepInfo:
 *                 type: object
 *                 description: Datos del PEP si aplican
 *                 properties:
 *                   relationship:
 *                     type: string
 *                     description: Relación con el PEP
 *                   entity:
 *                     type: string
 *                     description: Entidad donde trabaja el PEP
 *                   name:
 *                     type: string
 *                     description: Nombre del PEP
 *                   occupation:
 *                     type: string
 *                     description: Ocupación del PEP
 *                   identification:
 *                     type: string
 *                     description: Número de documento del PEP
 *               country:
 *                 type: integer
 *                 description: País
 *                 example: 721
 *               state:
 *                 type: integer
 *                 description: Estado
 *                 example: 3014
 *               municipality:
 *                 type: integer
 *                 description: Municipio
 *                 example: 3015
 *               parish:
 *                 type: integer
 *                 description: Parroquia
 *                 example: 3027
 *               street:
 *                 type: string
 *                 description: Calle
 *                 example: "Av Principal"
 *               housingType:
 *                 type: string
 *                 description: Tipo de vivienda
 *                 example: "Casa"
 *               housingName:
 *                 type: string
 *                 description: Nombre de vivienda
 *                 example: "Residencia Norte"
 *     responses:
 *       200:
 *         description: Usuario registrado (activo o pendiente)
 *         content:
 *           application/json:
 *             schema:
 *               type: object
 *               required: [success, message, data]
 *               properties:
 *                 success:
 *                   type: boolean
 *                   example: true
 *                 message:
 *                   type: string
 *                 data:
 *                   type: object
 *                   properties:
 *                     id:
 *                       type: string
 *                     status:
 *                       type: string
 *                     name:
 *                       type: string
 *                     lastname:
 *                       type: string
 *                     email:
 *                       type: string
 *                     isVerified:
 *                       type: boolean
 *                     accessToken:
 *                       type: string
 *                       nullable: true
 *                     refreshToken:
 *                       type: string
 *                       nullable: true
 *             example:
 *               success: true
 *               message: "Registro exitoso"
 *               data:
 *                 id: "697a3444cbaf4353acfa0132"
 *                 status: "active"
 *                 name: "María Alejandra"
 *                 lastname: "González"
 *                 email: "maria@ejemplo.com"
 *                 isVerified: true
 *                 accessToken: "eyJhbGciOiJIUzI1NiIs..."
 *                 refreshToken: "eyJhbGciOiJIUzI1NiIs..."
 *       400:
 *         description: Error de validación o requisitos no cumplidos
 *         content:
 *           application/json:
 *             schema:
 *               type: object
 *               properties:
 *                 success:
 *                   type: boolean
 *                   example: false
 *                 message:
 *                   type: string
 *                 code:
 *                   type: string
 *                   enum: [agile_check_result, subscription_required]
 *             examples:
 *               subscription_required:
 *                 summary: Pre-suscripción requerida
 *                 value:
 *                   success: false
 *                   message: "No existe una pre-suscripción válida. Debe completar el proceso de domiciliación antes de registrarse."
 *                   code: "subscription_required"
 *               agile_check_result:
 *                 summary: Resultado de verificación Agile no aprobado
 *                 value:
 *                   success: false
 *                   message: "Verificación no aprobada"
 *                   code: "agile_check_result"
 *       500:
 *         description: Error interno (sessionId, token, account requeridos o error de verificación)
 *         content:
 *           application/json:
 *             schema:
 *               type: object
 *               properties:
 *                 success:
 *                   type: boolean
 *                   example: false
 *                 message:
 *                   type: string
 *                 code:
 *                   type: string
 *                   enum: [field_missing, verification_error, invalid_email_token]
 *             examples:
 *               verification_error:
 *                 summary: Error en verificación del usuario
 *                 value:
 *                   success: false
 *                   message: "Se produjo un error verificando el usuario"
 *                   code: "verification_error"
 *               invalid_email_token:
 *                 summary: Token de correo inválido
 *                 value:
 *                   success: false
 *                   message: "Token de correo no válido"
 *                   code: "invalid_email_token"
 *               field_missing:
 *                 summary: Campos requeridos faltantes
 *                 value:
 *                   success: false
 *                   message: "sessionId, token o account son requeridos"
 *                   code: "field_missing"
 */
routes.route("/register").post(register);

/**
 * @swagger
 * /users/forgot-password:
 *   post:
 *     operationId: userForgotPassword
 *     tags: [Users]
 *     summary: Solicitar recuperación de contraseña
 *     requestBody:
 *       required: true
 *       content:
 *         application/json:
 *           schema:
 *             type: object
 *             required: [email]
 *             properties:
 *               email:
 *                 type: string
 *                 format: email
 *           example:
 *             email: "maria@ejemplo.com"
 *     responses:
 *       200:
 *         description: Correo con token enviado
 *         content:
 *           application/json:
 *             schema:
 *               type: object
 *               required: [success, message, data]
 *               properties:
 *                 success:
 *                   type: boolean
 *                   example: true
 *                 message:
 *                   type: string
 *                   example: "success"
 *                 data:
 *                   type: object
 *                   properties:
 *                     userId:
 *                       type: string
 *             example:
 *               success: true
 *               message: "success"
 *               data:
 *                 userId: "697a3444cbaf4353acfa0132"
 *       400:
 *         description: Correo requerido
 *         content:
 *           application/json:
 *             schema:
 *               type: object
 *               properties:
 *                 success:
 *                   type: boolean
 *                   example: false
 *                 message:
 *                   type: string
 *                   example: "Correo es requerido"
 *                 code:
 *                   type: string
 *                   example: "field_missing"
 *       401:
 *         description: Correo no encontrado
 *         content:
 *           application/json:
 *             schema:
 *               type: object
 *               properties:
 *                 success:
 *                   type: boolean
 *                   example: false
 *                 message:
 *                   type: string
 *                   example: "Correo no encontrado en sistema"
 *                 code:
 *                   type: string
 *                   example: "user_not_found"
 */
routes.route("/forgot-password").post(forgotPassword);

/**
 * @swagger
 * /users/reset-password:
 *   post:
 *     operationId: userResetPassword
 *     tags: [Users]
 *     summary: Restablecer contraseña con token
 *     requestBody:
 *       required: true
 *       content:
 *         application/json:
 *           schema:
 *             type: object
 *             required: [userId, token, password]
 *             properties:
 *               userId:
 *                 type: string
 *                 description: ID del usuario
 *               token:
 *                 type: string
 *                 description: Token recibido por correo
 *               password:
 *                 type: string
 *                 description: Nueva contraseña
 *           example:
 *             userId: "697a3444cbaf4353acfa0132"
 *             token: "123456"
 *             password: "Secret123!"
 *     responses:
 *       200:
 *         description: Contraseña actualizada
 *         content:
 *           application/json:
 *             schema:
 *               type: object
 *               properties:
 *                 success:
 *                   type: boolean
 *                   example: true
 *                 message:
 *                   type: string
 *                   example: "Reset password successful"
 *             example:
 *               success: true
 *               message: "Reset password successful"
 *       400:
 *         description: Token o password requerido
 *         content:
 *           application/json:
 *             schema:
 *               type: object
 *               properties:
 *                 success:
 *                   type: boolean
 *                   example: false
 *                 message:
 *                   type: string
 *                 code:
 *                   type: string
 *                   example: "field_missing"
 *       401:
 *         description: Token inválido
 *         content:
 *           application/json:
 *             schema:
 *               type: object
 *               properties:
 *                 success:
 *                   type: boolean
 *                   example: false
 *                 message:
 *                   type: string
 *                   example: "Invalid token"
 *                 code:
 *                   type: string
 *                   example: "invalid_token"
 */
routes.route("/reset-password").post(resetPassword);

/**
 * @swagger
 * /users/validate-document:
 *   post:
 *     operationId: userValidateDocument
 *     tags: [Users]
 *     summary: Validar documento de identidad
 *     requestBody:
 *       required: true
 *       content:
 *         application/json:
 *           schema:
 *             type: object
 *             required: [document]
 *             properties:
 *               document:
 *                 type: string
 *                 description: Número de documento (solo dígitos)
 *           example:
 *             document: "12345679"
 *     responses:
 *       200:
 *         description: Documento válido para registro
 *         content:
 *           application/json:
 *             schema:
 *               type: object
 *               properties:
 *                 success:
 *                   type: boolean
 *                   example: true
 *                 message:
 *                   type: string
 *                   example: "Documento válido para registro"
 *             example:
 *               success: true
 *               message: "Documento válido para registro"
 *       400:
 *         description: Documento faltante o ya registrado
 *         content:
 *           application/json:
 *             schema:
 *               type: object
 *               properties:
 *                 success:
 *                   type: boolean
 *                   example: false
 *                 message:
 *                   type: string
 *                 code:
 *                   type: string
 *                   example: "field_missing"
 *             examples:
 *               field_missing:
 *                 summary: Documento requerido
 *                 value:
 *                   success: false
 *                   message: "Falta el documento"
 *                   code: "field_missing"
 *               document_exists:
 *                 summary: Documento ya registrado
 *                 value:
 *                   success: false
 *                   message: "Documento ya esta registrado"
 */
routes.route("/validate-document").post(validateDocument);

/**
 * @swagger
 * /users/pre-register-domiciliation:
 *   post:
 *     operationId: userPreRegisterDomiciliation
 *     tags: [Users]
 *     summary: Pre-registro de domiciliación
 *     requestBody:
 *       required: true
 *       content:
 *         application/json:
 *           schema:
 *             type: object
 *             required: [name, identification, bankCode, accountNumber]
 *             properties:
 *               name:
 *                 type: string
 *                 example: "María González"
 *               identification:
 *                 type: string
 *                 example: "14567890"
 *               identificationType:
 *                 type: string
 *                 default: "V"
 *                 example: "V"
 *               bankCode:
 *                 type: string
 *                 example: "0102"
 *               accountNumber:
 *                 type: string
 *                 example: "01020123456789012345"
 *           example:
 *             name: "María González"
 *             identification: "14567890"
 *             identificationType: "V"
 *             bankCode: "0102"
 *             accountNumber: "01020123456789012345"
 *     responses:
 *       200:
 *         description: Pre-registro procesado correctamente
 *         content:
 *           application/json:
 *             schema:
 *               type: object
 *               properties:
 *                 success:
 *                   type: boolean
 *                   example: true
 *                 message:
 *                   type: string
 *             example:
 *               success: true
 *               message: "Pre-registro exitoso"
 *       400:
 *         description: Campos faltantes o error de SyPago
 *         content:
 *           application/json:
 *             schema:
 *               type: object
 *               properties:
 *                 success:
 *                   type: boolean
 *                   example: false
 *                 message:
 *                   type: string
 *                 code:
 *                   type: string
 *                   example: "field_missing"
 */
routes.route("/pre-register-domiciliation").post(preRegisterDomiciliation);

/**
 * @swagger
 * /users/send-register-token:
 *   post:
 *     operationId: userSendRegisterToken
 *     tags: [Users]
 *     summary: Enviar token de registro por correo
 *     requestBody:
 *       required: true
 *       content:
 *         application/json:
 *           schema:
 *             type: object
 *             required: [email]
 *             properties:
 *               email:
 *                 type: string
 *                 format: email
 *               phone:
 *                 type: string
 *           example:
 *             email: "usuario@ejemplo.com"
 *     responses:
 *       200:
 *         description: Token enviado al correo
 *         content:
 *           application/json:
 *             schema:
 *               type: object
 *               properties:
 *                 success:
 *                   type: boolean
 *                   example: true
 *                 message:
 *                   type: string
 *                   example: "Token enviado"
 *             example:
 *               success: true
 *               message: "Token enviado"
 *       400:
 *         description: Correo requerido o ya registrado
 *         content:
 *           application/json:
 *             schema:
 *               type: object
 *               properties:
 *                 success:
 *                   type: boolean
 *                   example: false
 *                 message:
 *                   type: string
 *                 code:
 *                   type: string
 *                   enum: [field_missing, user_exists]
 *             examples:
 *               field_missing:
 *                 summary: Correo requerido
 *                 value:
 *                   message: "Correo y teléfono son requeridos"
 *               user_exists:
 *                 summary: Correo ya registrado
 *                 value:
 *                   success: false
 *                   message: "El correo ingresado ya esta registrado en Pasta."
 *                   code: "user_exists"
 */
routes.route("/send-register-token").post(sendRegisterToken);

/**
 * @swagger
 * /users/validate-token:
 *   post:
 *     operationId: userValidateToken
 *     tags: [Users]
 *     summary: Validar token de registro
 *     requestBody:
 *       required: true
 *       content:
 *         application/json:
 *           schema:
 *             type: object
 *             required: [email, token]
 *             properties:
 *               email:
 *                 type: string
 *                 format: email
 *               token:
 *                 type: string
 *                 description: Token recibido por correo
 *           example:
 *             email: "usuario@dominio.com"
 *             token: "789012"
 *     responses:
 *       200:
 *         description: Token válido
 *         content:
 *           application/json:
 *             schema:
 *               type: object
 *               properties:
 *                 success:
 *                   type: boolean
 *                   example: true
 *                 message:
 *                   type: string
 *                   example: "Token válido"
 *             example:
 *               success: true
 *               message: "Token válido"
 *       400:
 *         description: Token no válido
 *         content:
 *           application/json:
 *             schema:
 *               type: object
 *               properties:
 *                 success:
 *                   type: boolean
 *                   example: false
 *                 message:
 *                   type: string
 *                   example: "Token no válido"
 */
routes.route("/validate-token").post(validateToken);

/**
 * @swagger
 * /users/terms-and-conditions:
 *   get:
 *     operationId: getTermsAndConditions
 *     tags: [Users]
 *     summary: Obtener términos y condiciones
 *     responses:
 *       200:
 *         description: Términos y condiciones en HTML
 *         content:
 *           application/json:
 *             schema:
 *               type: object
 *               required: [success, message, data]
 *               properties:
 *                 success:
 *                   type: boolean
 *                   example: true
 *                 message:
 *                   type: string
 *                   example: "Terminos y condiciones descargados correctamente"
 *                 data:
 *                   type: string
 *                   description: Contenido HTML de términos y condiciones
 *             example:
 *               success: true
 *               message: "Terminos y condiciones descargados correctamente"
 *               data: "<!DOCTYPE html><html>...</html>"
 */
routes.route("/terms-and-conditions").get(getTermsAndConditions);

/**
 * @swagger
 * /users/frequent-questions:
 *   get:
 *     operationId: getFrequentQuestions
 *     tags: [Users]
 *     summary: Obtener preguntas frecuentes
 *     responses:
 *       200:
 *         description: Lista de preguntas frecuentes
 *         content:
 *           application/json:
 *             schema:
 *               type: object
 *               required: [success, message, data]
 *               properties:
 *                 success:
 *                   type: boolean
 *                   example: true
 *                 message:
 *                   type: string
 *                   example: "Frequent questions retrieved successfully"
 *                 data:
 *                   type: array
 *                   items:
 *                     type: object
 *                     properties:
 *                       question:
 *                         type: string
 *                       answer:
 *                         type: string
 *             example:
 *               success: true
 *               message: "Frequent questions retrieved successfully"
 *               data:
 *                 - question: "¿Cómo puedo solicitar un préstamo?"
 *                   answer: "Puedes solicitar desde la app..."
 *                 - question: "¿Cuál es el monto máximo?"
 *                   answer: "El monto depende de tu nivel..."
 */
routes.route("/frequent-questions").get(getFrequentQuestions);

/**
 * @swagger
 * /users/webhook:
 *   post:
 *     operationId: userWebhook
 *     tags: [Users]
 *     summary: Webhook (integraciones externas)
 *     requestBody:
 *       content:
 *         application/json:
 *           schema:
 *             type: object
 *     responses:
 *       200:
 *         description: Webhook procesado
 */
routes.route("/webhook").post(webhook);

if (process.env.NODE_ENV === "development") {
  routes.route("/:userId").delete(deleteUser);
  routes.route("/list").get(getList);
}

routes.use(verifyToken);

/**
 * @swagger
 * /users:
 *   get:
 *     operationId: getCurrentUser
 *     tags: [Users]
 *     summary: Obtener usuario actual
 *     security:
 *       - bearerAuth: []
 *     responses:
 *       200:
 *         description: Datos del usuario
 *         content:
 *           application/json:
 *             schema:
 *               type: object
 *               properties:
 *                 success:
 *                   type: boolean
 *                   example: true
 *                 message:
 *                   type: string
 *                   example: "User retrieved successfully"
 *                 data:
 *                   type: object
 *                   properties:
 *                     _id:
 *                       type: string
 *                       example: "697a3444cbaf4353acfa0132"
 *                     document:
 *                       type: string
 *                       example: "14567890"
 *                     identificationType:
 *                       type: string
 *                       example: "V"
 *                     name:
 *                       type: string
 *                       example: "María Alejandra"
 *                     lastname:
 *                       type: string
 *                       example: "González"
 *                     email:
 *                       type: string
 *                       example: "maria@ejemplo.com"
 *                     level:
 *                       type: integer
 *                       example: 1
 *                     levelName:
 *                       type: string
 *                       example: "Basic"
 *                     maxAmount:
 *                       type: number
 *                       example: 100
 *                     points:
 *                       type: number
 *                       example: 107.44
 *                     allowedFeeCount:
 *                       type: array
 *                       items:
 *                         type: integer
 *                       example: [6]
 *                     nextLevelPoints:
 *                       type: number
 *                       example: 250
 *                     nextLevelName:
 *                       type: string
 *                       example: "Silver"
 *                     availableAmount:
 *                       type: number
 *                       example: 99.16
 *       401:
 *         $ref: "#/components/responses/Unauthorized"
 */
routes.route("/").get(getUser);

/**
 * @swagger
 * /users/refresh-token:
 *   post:
 *     operationId: userRefreshToken
 *     tags: [Users]
 *     summary: Refrescar token JWT
 *     security:
 *       - bearerAuth: []
 *     requestBody:
 *       required: true
 *       content:
 *         application/json:
 *           schema:
 *             type: object
 *             required: [refreshToken]
 *             properties:
 *               refreshToken:
 *                 type: string
 *                 description: Token de refresco actual
 *           example:
 *             refreshToken: "eyJhbGciOiJIUzI1NiIs..."
 *     responses:
 *       200:
 *         description: Tokens actualizados
 *         content:
 *           application/json:
 *             schema:
 *               type: object
 *               required: [success, message, data]
 *               properties:
 *                 success:
 *                   type: boolean
 *                   example: true
 *                 message:
 *                   type: string
 *                   example: "Refresh token successful"
 *                 data:
 *                   type: object
 *                   properties:
 *                     accessToken:
 *                       type: string
 *                     refreshToken:
 *                       type: string
 *             example:
 *               success: true
 *               message: "Refresh token successful"
 *               data:
 *                 accessToken: "eyJhbGciOiJIUzI1NiIs..."
 *                 refreshToken: "eyJhbGciOiJIUzI1NiIs..."
 *       400:
 *         description: Refresh token requerido
 *         content:
 *           application/json:
 *             schema:
 *               type: object
 *               properties:
 *                 message:
 *                   type: string
 *                   example: "Refresh token is required"
 *       401:
 *         description: Token inválido o expirado
 *         content:
 *           application/json:
 *             schema:
 *               type: object
 *               properties:
 *                 message:
 *                   type: string
 *                   example: "Invalid or expired refresh token"
 */
routes.route("/refresh-token").post(refreshToken);

/**
 * @swagger
 * /users/profile:
 *   get:
 *     operationId: getUserProfile
 *     tags: [Users]
 *     summary: Obtener perfil del usuario
 *     security:
 *       - bearerAuth: []
 *     responses:
 *       200:
 *         description: Perfil del usuario
 *         content:
 *           application/json:
 *             schema:
 *               type: object
 *               properties:
 *                 success:
 *                   type: boolean
 *                   example: true
 *                 message:
 *                   type: string
 *                   example: "User profile retrieved successfully"
 *                 data:
 *                   type: object
 *                   properties:
 *                     _id:
 *                       type: string
 *                       example: "697a3444cbaf4353acfa0132"
 *                     document:
 *                       type: string
 *                       example: "14567890"
 *                     identificationType:
 *                       type: string
 *                       example: "V"
 *                     name:
 *                       type: string
 *                       example: "María Alejandra"
 *                     lastname:
 *                       type: string
 *                       example: "González"
 *                     gender:
 *                       type: string
 *                       example: "F"
 *                     birthDate:
 *                       type: string
 *                       format: date-time
 *                       example: "1990-05-15T00:00:00.000Z"
 *                     email:
 *                       type: string
 *                       example: "maria@ejemplo.com"
 *                     phone:
 *                       type: object
 *                       properties:
 *                         countryCode:
 *                           type: string
 *                           example: "+58"
 *                         areaCode:
 *                           type: string
 *                           example: "212"
 *                         number:
 *                           type: string
 *                           example: "5551234"
 *                     notificationsConfig:
 *                       type: object
 *                       properties:
 *                         email:
 *                           type: boolean
 *                         sms:
 *                           type: boolean
 *                         push:
 *                           type: boolean
 *                         promotions:
 *                           type: boolean
 *                         _id:
 *                           type: string
 *                     image:
 *                       type: string
 *                       example: "697a3444cbaf4353acfa0132_1769616456647.jpg"
 *                     profileImagePath:
 *                       type: string
 *                       example: "https://apipasta.legendsoft.com/cdn/users/697a3444cbaf4353acfa0132_1769616456647.jpg"
 *                     country:
 *                       type: string
 *                       example: "721"
 *                     state:
 *                       type: string
 *                       example: "3014"
 *                     municipality:
 *                       type: string
 *                       example: "3015"
 *                     parish:
 *                       type: string
 *                       example: "3030"
 *                     street:
 *                       type: string
 *                       example: "Av Principal"
 *                     housingType:
 *                       type: string
 *                       example: "Casa"
 *                     housingName:
 *                       type: string
 *                       example: "Residencia Norte"
 *                     zipCode:
 *                       type: string
 *                       example: "1010"
 *       401:
 *         $ref: "#/components/responses/Unauthorized"
 */
routes.route("/profile").get(getProfile);

/**
 * @swagger
 * /users/notifications-config:
 *   get:
 *     operationId: getUserNotificationsConfig
 *     tags: [Users]
 *     summary: Obtener configuración de notificaciones
 *     security:
 *       - bearerAuth: []
 *     responses:
 *       200:
 *         description: Configuración de notificaciones
 *         content:
 *           application/json:
 *             schema:
 *               type: object
 *               properties:
 *                 success:
 *                   type: boolean
 *                   example: true
 *                 message:
 *                   type: string
 *                   example: "User notifications config retrieved successfully"
 *                 data:
 *                   type: object
 *                   properties:
 *                     email:
 *                       type: boolean
 *                       example: true
 *                     sms:
 *                       type: boolean
 *                       example: true
 *                     push:
 *                       type: boolean
 *                       example: true
 *                     promotions:
 *                       type: boolean
 *                       example: true
 *                     _id:
 *                       type: string
 *                       example: "697a3444cbaf4353acfa0131"
 *       401:
 *         $ref: "#/components/responses/Unauthorized"
 *   post:
 *     operationId: updateUserNotificationsConfig
 *     tags: [Users]
 *     summary: Editar configuración de notificaciones
 *     security:
 *       - bearerAuth: []
 *     requestBody:
 *       required: true
 *       content:
 *         application/json:
 *           schema:
 *             type: object
 *             required:
 *               - type
 *               - enabled
 *             properties:
 *               type:
 *                 type: string
 *                 enum: [email, sms, push, promotions]
 *                 description: Tipo de canal de notificación
 *               enabled:
 *                 type: boolean
 *                 description: Si el canal está habilitado o no
 *             example:
 *               type: "email"
 *               enabled: true
 *     responses:
 *       200:
 *         description: Configuración actualizada
 *         content:
 *           application/json:
 *             schema:
 *               type: object
 *               properties:
 *                 success:
 *                   type: boolean
 *                   example: true
 *                 message:
 *                   type: string
 *                   example: "User notifications config updated successfully"
 *                 data:
 *                   type: object
 *                   properties:
 *                     email:
 *                       type: boolean
 *                     sms:
 *                       type: boolean
 *                     push:
 *                       type: boolean
 *                     promotions:
 *                       type: boolean
 *       400:
 *         description: type o enabled requeridos
 *         content:
 *           application/json:
 *             schema:
 *               type: object
 *               properties:
 *                 success:
 *                   type: boolean
 *                   example: false
 *                 message:
 *                   type: string
 *                 code:
 *                   type: string
 *                   example: "field_missing"
 *       401:
 *         $ref: "#/components/responses/Unauthorized"
 */
routes.route("/notifications-config").get(getNotificationsConfig);
routes.route("/notifications-config").post(editNotificationsConfig);

/**
 * @swagger
 * /users/edit-profile:
 *   post:
 *     operationId: userEditProfile
 *     tags: [Users]
 *     summary: Editar perfil (envía token por correo)
 *     security:
 *       - bearerAuth: []
 *     requestBody:
 *       required: true
 *       content:
 *         application/json:
 *           schema:
 *             type: object
 *             properties:
 *               name:
 *                 type: string
 *               lastname:
 *                 type: string
 *               birthDate:
 *                 type: string
 *                 format: date
 *               gender:
 *                 type: string
 *                 enum: [M, F]
 *               email:
 *                 type: string
 *                 format: email
 *               phone:
 *                 type: object
 *                 properties:
 *                   countryCode:
 *                     type: string
 *                   areaCode:
 *                     type: string
 *                   number:
 *                     type: string
 *               address:
 *                 type: object
 *                 properties:
 *                   country:
 *                     type: string
 *                   state:
 *                     type: string
 *                   municipality:
 *                     type: string
 *                   parish:
 *                     type: string
 *                   street:
 *                     type: string
 *                   housingType:
 *                     type: string
 *                   housingName:
 *                     type: string
 *                   zipCode:
 *                     type: string
 *           example:
 *             name: "María Alejandra"
 *             lastname: "González"
 *             email: "maria@ejemplo.com"
 *     responses:
 *       200:
 *         description: Token enviado al correo para confirmar
 *         content:
 *           application/json:
 *             schema:
 *               type: object
 *               properties:
 *                 success:
 *                   type: boolean
 *                   example: true
 *                 message:
 *                   type: string
 *                   example: "Token enviado al correo"
 *       400:
 *         description: Error de validación
 *         content:
 *           application/json:
 *             schema:
 *               type: object
 *               properties:
 *                 success:
 *                   type: boolean
 *                   example: false
 *                 message:
 *                   type: string
 *       401:
 *         $ref: "#/components/responses/Unauthorized"
 */
routes.route("/edit-profile").post(editProfile);

/**
 * @swagger
 * /users/edit-profile-confirmation:
 *   post:
 *     operationId: userEditProfileConfirmation
 *     tags: [Users]
 *     summary: Confirmar edición de perfil
 *     security:
 *       - bearerAuth: []
 *     requestBody:
 *       content:
 *         application/json:
 *           schema:
 *             type: object
 *             required:
 *               - address
 *               - phone
 *               - email
 *               - token
 *             properties:
 *               address:
 *                 type: string
 *                 example: "Caracas"
 *               phone:
 *                 type: object
 *                 required:
 *                   - countryCode
 *                   - areaCode
 *                   - number
 *                 properties:
 *                   countryCode:
 *                     type: string
 *                     example: "58"
 *                   areaCode:
 *                     type: string
 *                     example: "414"
 *                   number:
 *                     type: string
 *                     example: "1234567"
 *               email:
 *                 type: string
 *                 format: email
 *                 example: "user@gmail.com"
 *               token:
 *                 type: string
 *                 example: "0926"
 *     responses:
 *       200:
 *         description: Edición confirmada
 *         content:
 *           application/json:
 *             schema:
 *               type: object
 *               properties:
 *                 success:
 *                   type: boolean
 *                   example: true
 *                 message:
 *                   type: string
 *                   example: "Profile updated successfully"
 *       400:
 *         description: Token inválido o campos requeridos
 *         content:
 *           application/json:
 *             schema:
 *               type: object
 *               properties:
 *                 success:
 *                   type: boolean
 *                   example: false
 *                 message:
 *                   type: string
 *       401:
 *         $ref: "#/components/responses/Unauthorized"
 */
routes.route("/edit-profile-confirmation").post(editProfileConfirmation);

/**
 * @swagger
 * /users/change-password:
 *   post:
 *     operationId: userChangePassword
 *     tags: [Users]
 *     summary: Cambiar contraseña (envía token por correo)
 *     security:
 *       - bearerAuth: []
 *     requestBody:
 *       required: true
 *       content:
 *         application/json:
 *           schema:
 *             type: object
 *             required: [oldPassword]
 *             properties:
 *               oldPassword:
 *                 type: string
 *                 description: Contraseña actual
 *           example:
 *             oldPassword: "Secret123!"
 *     responses:
 *       200:
 *         description: Token enviado al correo para confirmar
 *         content:
 *           application/json:
 *             schema:
 *               type: object
 *               properties:
 *                 success:
 *                   type: boolean
 *                   example: true
 *                 message:
 *                   type: string
 *                   example: "Token enviado al correo"
 *       400:
 *         description: Contraseña incorrecta o requerida
 *         content:
 *           application/json:
 *             schema:
 *               type: object
 *               properties:
 *                 success:
 *                   type: boolean
 *                   example: false
 *                 message:
 *                   type: string
 *       401:
 *         $ref: "#/components/responses/Unauthorized"
 */
routes.route("/change-password").post(changePassword);

/**
 * @swagger
 * /users/change-password-confirmation:
 *   post:
 *     operationId: userChangePasswordConfirmation
 *     tags: [Users]
 *     summary: Confirmar cambio de contraseña con token
 *     security:
 *       - bearerAuth: []
 *     requestBody:
 *       required: true
 *       content:
 *         application/json:
 *           schema:
 *             type: object
 *             required: [token, newPassword]
 *             properties:
 *               token:
 *                 type: string
 *                 description: Token recibido por correo
 *               newPassword:
 *                 type: string
 *                 description: Nueva contraseña
 *           example:
 *             token: "5960"
 *             newPassword: "Secret123!"
 *     responses:
 *       200:
 *         description: Contraseña actualizada
 *         content:
 *           application/json:
 *             schema:
 *               type: object
 *               properties:
 *                 success:
 *                   type: boolean
 *                   example: true
 *                 message:
 *                   type: string
 *                   example: "Password updated successfully"
 *       400:
 *         description: Token inválido o password requerido
 *         content:
 *           application/json:
 *             schema:
 *               type: object
 *               properties:
 *                 success:
 *                   type: boolean
 *                   example: false
 *                 message:
 *                   type: string
 *       401:
 *         $ref: "#/components/responses/Unauthorized"
 */
routes.route("/change-password-confirmation").post(changePasswordConfirmation);

/**
 * @swagger
 * /users/unregister:
 *   post:
 *     operationId: userUnregister
 *     tags: [Users]
 *     summary: Darse de baja
 *     security:
 *       - bearerAuth: []
 *     requestBody:
 *       content:
 *         application/json:
 *           schema:
 *             type: object
 *             properties:
 *               motive:
 *                 type: string
 *                 description: Motivo de baja (opcional)
 *           example:
 *             motive: "Ya no uso el servicio"
 *     responses:
 *       200:
 *         description: Usuario dado de baja
 *         content:
 *           application/json:
 *             schema:
 *               type: object
 *               properties:
 *                 success:
 *                   type: boolean
 *                   example: true
 *                 message:
 *                   type: string
 *                   example: "Usuario dado de baja"
 *       400:
 *         description: Usuario con pagos pendientes
 *         content:
 *           application/json:
 *             schema:
 *               type: object
 *               properties:
 *                 success:
 *                   type: boolean
 *                   example: false
 *                 message:
 *                   type: string
 *                   example: "No puedes darte de baja con pagos pendientes"
 *                 code:
 *                   type: string
 *                   example: "user_has_pending_payments"
 *       401:
 *         $ref: "#/components/responses/Unauthorized"
 */
routes.route("/unregister").post(unregister);

/**
 * @swagger
 * /users/subscribe-push:
 *   post:
 *     operationId: userSubscribePush
 *     tags: [Users]
 *     summary: Suscribir notificaciones push
 *     security:
 *       - bearerAuth: []
 *     requestBody:
 *       required: true
 *       content:
 *         application/json:
 *           schema:
 *             type: object
 *             required: [token]
 *             properties:
 *               token:
 *                 type: string
 *                 description: Token FCM/APNs del dispositivo
 *           example:
 *             token: "fcm_token_abc123..."
 *     responses:
 *       200:
 *         description: Suscripción registrada
 *         content:
 *           application/json:
 *             schema:
 *               type: object
 *               properties:
 *                 success:
 *                   type: boolean
 *                   example: true
 *                 message:
 *                   type: string
 *                   example: "Push subscription registered"
 *       400:
 *         description: Token requerido
 *         content:
 *           application/json:
 *             schema:
 *               type: object
 *               properties:
 *                 success:
 *                   type: boolean
 *                   example: false
 *                 message:
 *                   type: string
 *       401:
 *         $ref: "#/components/responses/Unauthorized"
 */
routes.route("/subscribe-push").post(subscribePush);

/**
 * @swagger
 * /users/unsubscribe-push:
 *   post:
 *     operationId: userUnsubscribePush
 *     tags: [Users]
 *     summary: Desuscribir notificaciones push
 *     security:
 *       - bearerAuth: []
 *     requestBody:
 *       required: true
 *       content:
 *         application/json:
 *           schema:
 *             type: object
 *             required: [token]
 *             properties:
 *               token:
 *                 type: string
 *                 description: Token FCM/APNs a eliminar
 *           example:
 *             token: "fcm_token_abc123..."
 *     responses:
 *       200:
 *         description: Desuscripción registrada
 *         content:
 *           application/json:
 *             schema:
 *               type: object
 *               properties:
 *                 success:
 *                   type: boolean
 *                   example: true
 *                 message:
 *                   type: string
 *                   example: "Push subscription removed"
 *       400:
 *         description: Token requerido
 *         content:
 *           application/json:
 *             schema:
 *               type: object
 *               properties:
 *                 success:
 *                   type: boolean
 *                   example: false
 *                 message:
 *                   type: string
 *       401:
 *         $ref: "#/components/responses/Unauthorized"
 */
routes.route("/unsubscribe-push").post(unsubscribePush);

routes.use(authorizeModules("clients"));

/**
 * @swagger
 * /users/statistics:
 *   get:
 *     operationId: getUserStatistics
 *     tags: [Users]
 *     summary: Estadísticas de clientes
 *     security:
 *       - bearerAuth: []
 *     responses:
 *       200:
 *         description: Estadísticas obtenidas
 *         content:
 *           application/json:
 *             schema:
 *               type: object
 *               required: [success, message, data]
 *               properties:
 *                 success:
 *                   type: boolean
 *                   example: true
 *                 message:
 *                   type: string
 *                   example: "Estadísticas de clientes obtenidas correctamente"
 *                 data:
 *                   type: object
 *                   properties:
 *                     total:
 *                       type: integer
 *                       example: 150
 *                     vigentes:
 *                       type: integer
 *                       example: 80
 *                     vencidos:
 *                       type: integer
 *                       example: 30
 *                     morosos:
 *                       type: integer
 *                       example: 25
 *                     inactivos:
 *                       type: integer
 *                       example: 15
 *             example:
 *               success: true
 *               message: "Estadísticas de clientes obtenidas correctamente"
 *               data:
 *                 total: 150
 *                 vigentes: 80
 *                 vencidos: 30
 *                 morosos: 25
 *                 inactivos: 15
 *       401:
 *         $ref: "#/components/responses/Unauthorized"
 *       403:
 *         $ref: "#/components/responses/Forbidden"
 */
routes.route("/statistics").get(getClientStatistics);

/**
 * @swagger
 * /users/get-all:
 *   get:
 *     operationId: getAllUsers
 *     tags: [Users]
 *     summary: Listar todos los usuarios
 *     security:
 *       - bearerAuth: []
 *     parameters:
 *       - in: query
 *         name: state
 *         required: false
 *         schema:
 *           type: string
 *           enum: [vigente, vencido, moroso, inactivo]
 *         description: Filtrar por estado de pago (vigente, vencido, moroso, inactivo)
 *         example: vigente
 *     responses:
 *       200:
 *         description: Lista de usuarios
 *         content:
 *           application/json:
 *             schema:
 *               type: object
 *               required: [success, message, data]
 *               properties:
 *                 success:
 *                   type: boolean
 *                   example: true
 *                 message:
 *                   type: string
 *                   example: "Users retrieved successfully"
 *                 data:
 *                   type: array
 *                   items:
 *                     type: object
 *                     properties:
 *                       _id:
 *                         type: string
 *                       name:
 *                         type: string
 *                       lastname:
 *                         type: string
 *                       email:
 *                         type: string
 *                       document:
 *                         type: string
 *                       status:
 *                         type: string
 *                       statusName:
 *                         type: string
 *                       identificationType:
 *                         type: string
 *                       image:
 *                         type: string
 *                       maxAmount:
 *                         type: number
 *                       creditoDisponible:
 *                         type: number
 *                       creditoUsado:
 *                         type: number
 *       400:
 *         description: state inválido
 *         content:
 *           application/json:
 *             schema:
 *               type: object
 *               properties:
 *                 success:
 *                   type: boolean
 *                   example: false
 *                 message:
 *                   type: string
 *                   example: "state must be one of: vigente, vencido, moroso, inactivo or null"
 *       401:
 *         $ref: "#/components/responses/Unauthorized"
 *       403:
 *         $ref: "#/components/responses/Forbidden"
 */
routes.route("/get-all").get(getAllUsers);

/**
 * @swagger
 * /users/{userId}:
 *   get:
 *     operationId: getUserById
 *     tags: [Users]
 *     summary: Obtener usuario por ID
 *     security:
 *       - bearerAuth: []
 *     parameters:
 *       - in: path
 *         name: userId
 *         required: true
 *         schema:
 *           type: string
 *     responses:
 *       200:
 *         description: Usuario obtenido
 *         content:
 *           application/json:
 *             schema:
 *               type: object
 *               properties:
 *                 success:
 *                   type: boolean
 *                   example: true
 *                 message:
 *                   type: string
 *                   example: "User retrieved successfully"
 *                 data:
 *                   type: object
 *                   properties:
 *                     _id:
 *                       type: string
 *                     document:
 *                       type: string
 *                     identificationType:
 *                       type: string
 *                     name:
 *                       type: string
 *                     lastname:
 *                       type: string
 *                     email:
 *                       type: string
 *                     level:
 *                       type: integer
 *                     levelName:
 *                       type: string
 *                     maxAmount:
 *                       type: number
 *                     points:
 *                       type: number
 *                     allowedFeeCount:
 *                       type: array
 *                       items:
 *                         type: integer
 *                     nextLevelPoints:
 *                       type: number
 *                     nextLevelName:
 *                       type: string
 *                     availableAmount:
 *                       type: number
 *       401:
 *         $ref: "#/components/responses/Unauthorized"
 *       403:
 *         $ref: "#/components/responses/Forbidden"
 *       404:
 *         description: Usuario no encontrado
 *         content:
 *           application/json:
 *             schema:
 *               type: object
 *               properties:
 *                 success:
 *                   type: boolean
 *                   example: false
 *                 message:
 *                   type: string
 *                   example: "User not found"
 *                 code:
 *                   type: string
 *                   example: "user_not_found"
 *   patch:
 *     operationId: updateUser
 *     tags: [Users]
 *     summary: Editar usuario
 *     security:
 *       - bearerAuth: []
 *     parameters:
 *       - in: path
 *         name: userId
 *         required: true
 *         schema:
 *           type: string
 *     requestBody:
 *       content:
 *         application/json:
 *           schema:
 *             type: object
 *             properties:
 *               name:
 *                 type: string
 *               lastname:
 *                 type: string
 *               maxAmount:
 *                 type: number
 *               level:
 *                 type: integer
 *           example:
 *             name: "María Alejandra"
 *             lastname: "González"
 *             maxAmount: 150
 *     responses:
 *       200:
 *         description: Usuario actualizado
 *         content:
 *           application/json:
 *             schema:
 *               type: object
 *               properties:
 *                 success:
 *                   type: boolean
 *                   example: true
 *                 message:
 *                   type: string
 *                   example: "User updated successfully"
 *       401:
 *         $ref: "#/components/responses/Unauthorized"
 *       403:
 *         $ref: "#/components/responses/Forbidden"
 *       404:
 *         description: Usuario no encontrado
 *         content:
 *           application/json:
 *             schema:
 *               type: object
 *               properties:
 *                 success:
 *                   type: boolean
 *                   example: false
 *                 message:
 *                   type: string
 *                 code:
 *                   type: string
 *                   example: "user_not_found"
 */
routes.route("/:userId").get(getUserById).patch(editUser);

/**
 * @swagger
 * /users/{userId}/accounts:
 *   get:
 *     operationId: getUserAccounts
 *     tags: [Users]
 *     summary: Listar cuentas del usuario
 *     security:
 *       - bearerAuth: []
 *     parameters:
 *       - in: path
 *         name: userId
 *         required: true
 *         schema:
 *           type: string
 *     responses:
 *       200:
 *         description: Cuentas del usuario
 *         content:
 *           application/json:
 *             schema:
 *               type: object
 *               properties:
 *                 success:
 *                   type: boolean
 *                   example: true
 *                 message:
 *                   type: string
 *                 data:
 *                   type: array
 *                   items:
 *                     type: object
 *                     properties:
 *                       _id:
 *                         type: string
 *                       bank:
 *                         type: string
 *                       type:
 *                         type: string
 *                         enum: [checking, savings]
 *                       number:
 *                         type: string
 *       401:
 *         $ref: "#/components/responses/Unauthorized"
 *       403:
 *         $ref: "#/components/responses/Forbidden"
 *   post:
 *     operationId: createUserAccount
 *     tags: [Users]
 *     summary: Crear cuenta para usuario
 *     security:
 *       - bearerAuth: []
 *     parameters:
 *       - in: path
 *         name: userId
 *         required: true
 *         schema:
 *           type: string
 *     requestBody:
 *       required: true
 *       content:
 *         application/json:
 *           schema:
 *             type: object
 *             required: [bank, type, number]
 *             properties:
 *               bank:
 *                 type: string
 *                 description: ID del banco
 *               type:
 *                 type: string
 *                 enum: [checking, savings]
 *               number:
 *                 type: string
 *                 description: Número de cuenta
 *           example:
 *             bank: "697a3444cbaf4353acfa0131"
 *             type: "checking"
 *             number: "01020123456789012345"
 *     responses:
 *       201:
 *         description: Cuenta creada
 *         content:
 *           application/json:
 *             schema:
 *               type: object
 *               properties:
 *                 success:
 *                   type: boolean
 *                   example: true
 *                 message:
 *                   type: string
 *                   example: "Account created successfully"
 *       400:
 *         description: bank, type o number requeridos
 *         content:
 *           application/json:
 *             schema:
 *               type: object
 *               properties:
 *                 success:
 *                   type: boolean
 *                   example: false
 *                 message:
 *                   type: string
 *                   example: "Bank, type and number are required"
 *                 code:
 *                   type: string
 *                   example: "field_missing"
 *       401:
 *         $ref: "#/components/responses/Unauthorized"
 *       403:
 *         $ref: "#/components/responses/Forbidden"
 *       500:
 *         description: Error al crear cuenta (banco no encontrado)
 */
routes.route("/:userId/accounts").get(getAccounts).post(createAccountForUser);

/**
 * @swagger
 * /users/{userId}/accounts/{id}:
 *   delete:
 *     operationId: deleteUserAccount
 *     tags: [Users]
 *     summary: Eliminar cuenta del usuario
 *     security:
 *       - bearerAuth: []
 *     parameters:
 *       - in: path
 *         name: userId
 *         required: true
 *         schema:
 *           type: string
 *       - in: path
 *         name: id
 *         required: true
 *         schema:
 *           type: string
 *         description: ID de la cuenta
 *     responses:
 *       200:
 *         description: Cuenta eliminada
 *         content:
 *           application/json:
 *             schema:
 *               type: object
 *               properties:
 *                 success:
 *                   type: boolean
 *                   example: true
 *                 message:
 *                   type: string
 *                   example: "Account deleted successfully"
 *       400:
 *         description: ID de cuenta requerido
 *         content:
 *           application/json:
 *             schema:
 *               type: object
 *               properties:
 *                 success:
 *                   type: boolean
 *                   example: false
 *                 message:
 *                   type: string
 *                   example: "Account id is required"
 *                 code:
 *                   type: string
 *                   example: "parameter_missing"
 *       401:
 *         $ref: "#/components/responses/Unauthorized"
 *       403:
 *         $ref: "#/components/responses/Forbidden"
 *       404:
 *         description: Cuenta no encontrada
 *         content:
 *           application/json:
 *             schema:
 *               type: object
 *               properties:
 *                 success:
 *                   type: boolean
 *                   example: false
 *                 message:
 *                   type: string
 *                   example: "Account not found"
 *                 code:
 *                   type: string
 *                   example: "account_not_found"
 */
routes.route("/:userId/accounts/:id").delete(deleteAccountForUser);

/**
 * @swagger
 * /users/{userId}/documents:
 *   get:
 *     operationId: getUserDocuments
 *     tags: [Users]
 *     summary: Listar documentos del usuario
 *     security:
 *       - bearerAuth: []
 *     parameters:
 *       - in: path
 *         name: userId
 *         required: true
 *         schema:
 *           type: string
 *         description: ID del usuario
 *     responses:
 *       200:
 *         description: Lista de documentos/imágenes del usuario
 *         content:
 *           application/json:
 *             schema:
 *               type: object
 *               required: [success, message, data]
 *               properties:
 *                 success:
 *                   type: boolean
 *                   example: true
 *                 message:
 *                   type: string
 *                   example: "Documents retrieved successfully"
 *                 data:
 *                   type: array
 *                   items:
 *                     type: object
 *                     properties:
 *                       documentType:
 *                         type: string
 *                         description: Tipo de documento
 *                         example: "1"
 *                       image:
 *                         type: string
 *                         description: Nombre del archivo de imagen
 *                         example: "697a3444cbaf4353acfa0132_1769616456647.jpg"
 *             example:
 *               success: true
 *               message: "Documents retrieved successfully"
 *               data:
 *                 - documentType: "1"
 *                   image: "697a3444cbaf4353acfa0132_1769616456647.jpg"
 *       401:
 *         $ref: "#/components/responses/Unauthorized"
 *       403:
 *         $ref: "#/components/responses/Forbidden"
 */
routes.route("/:userId/documents").get(getDocuments);

/**
 * @swagger
 * /users/{userId}/documents/{image}:
 *   get:
 *     operationId: getUserDocument
 *     tags: [Users]
 *     summary: Descargar documento
 *     security:
 *       - bearerAuth: []
 *     parameters:
 *       - in: path
 *         name: userId
 *         required: true
 *         schema:
 *           type: string
 *         description: ID del usuario
 *       - in: path
 *         name: image
 *         required: true
 *         schema:
 *           type: string
 *         description: Nombre del archivo de imagen (ej. 697a3444cbaf4353acfa0132_1769616456647.jpg)
 *         example: "697a3444cbaf4353acfa0132_1769616456647.jpg"
 *     responses:
 *       200:
 *         description: Archivo del documento (descarga binaria)
 *         content:
 *           application/octet-stream:
 *             schema:
 *               type: string
 *               format: binary
 *       401:
 *         $ref: "#/components/responses/Unauthorized"
 *       403:
 *         $ref: "#/components/responses/Forbidden"
 *       404:
 *         description: Usuario o documento no encontrado
 *         content:
 *           application/json:
 *             schema:
 *               type: object
 *               properties:
 *                 success:
 *                   type: boolean
 *                   example: false
 *                 message:
 *                   type: string
 *                 code:
 *                   type: string
 *                   enum: [user_not_found, document_not_found]
 *             examples:
 *               user_not_found:
 *                 summary: Usuario no encontrado
 *                 value:
 *                   success: false
 *                   message: "User not found"
 *                   code: "user_not_found"
 *               document_not_found:
 *                 summary: Documento no encontrado
 *                 value:
 *                   success: false
 *                   message: "Document not found"
 *                   code: "document_not_found"
 */
routes.route("/:userId/documents/:image").get(downloadDocument);

/**
 * @swagger
 * /users/{userId}/status:
 *   patch:
 *     operationId: updateUserStatus
 *     tags: [Users]
 *     summary: Cambiar estatus del usuario
 *     security:
 *       - bearerAuth: []
 *     parameters:
 *       - in: path
 *         name: userId
 *         required: true
 *         schema:
 *           type: string
 *     requestBody:
 *       required: true
 *       content:
 *         application/json:
 *           schema:
 *             type: object
 *             required: [status]
 *             properties:
 *               status:
 *                 type: string
 *                 description: Nuevo estatus (active, pending, inactive, etc.)
 *           example:
 *             status: "active"
 *     responses:
 *       200:
 *         description: Estatus actualizado
 *         content:
 *           application/json:
 *             schema:
 *               type: object
 *               properties:
 *                 success:
 *                   type: boolean
 *                   example: true
 *                 message:
 *                   type: string
 *                   example: "User changed successfully"
 *       401:
 *         $ref: "#/components/responses/Unauthorized"
 *       403:
 *         $ref: "#/components/responses/Forbidden"
 *       404:
 *         description: Usuario no encontrado
 *         content:
 *           application/json:
 *             schema:
 *               type: object
 *               properties:
 *                 success:
 *                   type: boolean
 *                   example: false
 *                 message:
 *                   type: string
 *                   example: "User not found"
 *                 code:
 *                   type: string
 *                   example: "user_not_found"
 */
routes.route("/:userId/status").patch(changeStatus);

export default routes;
