import { Router } from "express";
import {
  confirmOperation,
  requestOperation,
  getCompletedOperations,
  getActiveOperations,
  getOperationDetails,
  getOperationPaymentsWithTotal,
  // getAccountChargeLink, // Banesco - ya no integrado
  payDebt,
  payDebtConfirmation,
  checkLatePayments,
  getAllOperations,
  getOperationDetailsById,
  getOperationPayments,
  getAllPayments,
  getPaymentDetailsById,
  requestSypagoOtp,
  getInstallmentSimulation,
  getTreasuryData,
  getMovements,
  getTasaFinanciera,
} from "../controllers/operationController";
import { authorizeModules, verifyToken } from "../middlewares/authJwt";

const router = Router();

/**
 * @swagger
 * tags:
 *   name: Operations
 *   description: Operaciones de crédito, pagos y consultas
 */

/**
 * @swagger
 * components:
 *   schemas:
 *     RequestOperationBody:
 *       type: object
 *       required: [currency, amount, feeCount, account]
 *       properties:
 *         currency:
 *           type: string
 *           enum: [USD, VEF]
 *         amount:
 *           type: number
 *         feeCount:
 *           type: integer
 *         isThirdParty:
 *           type: boolean
 *         account:
 *           type: string
 *         beneficiary:
 *           type: object
 *           properties:
 *             identificationType:
 *               type: string
 *             identificationNumber:
 *               type: string
 *             phone:
 *               type: string
 *             bankCode:
 *               type: string
 *     PayDebtBody:
 *       type: object
 *       required: [payments]
 *       properties:
 *         payments:
 *           type: array
 *           items:
 *             type: string
 *     PayDebtConfirmationBody:
 *       type: object
 *       required: [id, paymentType]
 *       properties:
 *         id:
 *           type: string
 *         paymentType:
 *           type: string
 *           enum: [mobile, transfer, debit]
 *         phone:
 *           type: string
 *         date:
 *           type: string
 *           format: date-time
 *         reference:
 *           type: string
 *         bankCode:
 *           type: string
 *         otp:
 *           type: string
 *         device:
 *           type: object
 *           properties:
 *             type:
 *               type: string
 *             description:
 *               type: string
 *             ipAddress:
 *               type: string
 *     RequestOtpBody:
 *       type: object
 *       required: [id, phone, bankCode, identificationType, identificationNumber]
 *       properties:
 *         id:
 *           type: string
 *         phone:
 *           type: string
 *         bankCode:
 *           type: string
 *         identificationType:
 *           type: string
 *           enum: [V, E, J, P]
 *         identificationNumber:
 *           type: string
 *           minLength: 5
 *           maxLength: 15
 */

/**
 * @swagger
 * /operation/check-late-payments:
 *   post:
 *     operationId: checkLatePayments
 *     tags: [Operations]
 *     summary: Actualizar pagos vencidos
 *     description: Marca cuotas vencidas como overdue y actualiza puntos de usuarios (cron/job)
 *     responses:
 *       200:
 *         description: Pagos vencidos actualizados correctamente
 *         content:
 *           application/json:
 *             schema:
 *               type: object
 *               required: [success, message, data]
 *               properties:
 *                 success:
 *                   type: boolean
 *                   example: true
 *                 message:
 *                   type: string
 *                   example: "Pagos vencidos actualizados correctamente"
 *                 data:
 *                   type: object
 *                   properties:
 *                     latePayments:
 *                       type: array
 *                       items:
 *                         type: object
 *                         properties:
 *                           id:
 *                             type: string
 *                           operation:
 *                             type: string
 *                           amount:
 *                             type: number
 *                           status:
 *                             type: string
 *                           statusName:
 *                             type: string
 *                           date:
 *                             type: string
 *                             format: date-time
 *             example:
 *               success: true
 *               message: "Pagos vencidos actualizados correctamente"
 *               data:
 *                 latePayments:
 *                   - id: "69864ab103d5a2078dc4a857"
 *                     operation: "6941b9cf429b137e4d5795bb"
 *                     amount: 19.17
 *                     status: "overdue"
 *                     statusName: "Vencido"
 *                     date: "2026-03-01T04:00:00.000Z"
 */
router.post("/check-late-payments", checkLatePayments);

/**
 * @swagger
 * /operation/simulate:
 *   get:
 *     operationId: simulateOperation
 *     tags: [Operations]
 *     summary: Simular cuotas de crédito
 *     description: Obtiene la simulación de cuotas según monto y número de cuotas
 *     parameters:
 *       - in: query
 *         name: amountUsd
 *         required: true
 *         schema:
 *           type: number
 *         description: Monto en USD a simular
 *         example: 100
 *       - in: query
 *         name: feeCount
 *         required: true
 *         schema:
 *           type: integer
 *         description: Número de cuotas
 *         example: 6
 *     responses:
 *       200:
 *         description: Simulación obtenida correctamente
 *         content:
 *           application/json:
 *             schema:
 *               type: object
 *               required: [success, data, message]
 *               properties:
 *                 success:
 *                   type: boolean
 *                   example: true
 *                 data:
 *                   type: array
 *                   items:
 *                     type: object
 *                     properties:
 *                       date:
 *                         type: string
 *                         format: date-time
 *                       amountUsd:
 *                         type: number
 *                 message:
 *                   type: string
 *                   example: "Plan de cuotas simulado"
 *             example:
 *               success: true
 *               data:
 *                 - date: "2026-03-20T04:00:00.000Z"
 *                   amountUsd: 19.17
 *                 - date: "2026-04-20T04:00:00.000Z"
 *                   amountUsd: 19.17
 *                 - date: "2026-05-20T04:00:00.000Z"
 *                   amountUsd: 19.17
 *               message: "Plan de cuotas simulado"
 *       400:
 *         description: Parámetros requeridos faltantes
 *         content:
 *           application/json:
 *             schema:
 *               type: object
 *               properties:
 *                 success:
 *                   type: boolean
 *                   example: false
 *                 message:
 *                   type: string
 */
router.get("/simulate", getInstallmentSimulation);

/**
 * @swagger
 * /operation/annual-interest-rate:
 *   get:
 *     operationId: getAnnualInterestRate
 *     tags: [Operations]
 *     summary: Obtener tasa de interés anual
 *     description: Devuelve la tasa financiera anual configurada
 *     responses:
 *       200:
 *         description: Tasa obtenida correctamente
 *         content:
 *           application/json:
 *             schema:
 *               type: object
 *               required: [success, data, message]
 *               properties:
 *                 success:
 *                   type: boolean
 *                   example: true
 *                 data:
 *                   type: number
 *                   description: Tasa anual en porcentaje
 *                 message:
 *                   type: string
 *                   example: "Tasa anual obtenida exitosamente"
 *             example:
 *               success: true
 *               data: 60
 *               message: "Tasa anual obtenida exitosamente"
 *       404:
 *         description: Tasa no encontrada
 *         content:
 *           application/json:
 *             schema:
 *               type: object
 *               properties:
 *                 success:
 *                   type: boolean
 *                   example: false
 *                 message:
 *                   type: string
 *                   example: "No se encontró la tasa anual de interés"
 *                 code:
 *                   type: string
 *                   example: "not_found"
 *       500:
 *         description: Error al obtener la tasa
 *         content:
 *           application/json:
 *             schema:
 *               type: object
 *               properties:
 *                 success:
 *                   type: boolean
 *                   example: false
 *                 message:
 *                   type: string
 *                   example: "Error al obtener la tasa financiera"
 *                 code:
 *                   type: string
 *                   example: "internal_error"
 */
router.get("/annual-interest-rate", getTasaFinanciera);

router.use(verifyToken);

/**
 * @swagger
 * /operation/completed:
 *   get:
 *     operationId: getCompletedOperations
 *     tags: [Operations]
 *     summary: Listar operaciones finalizadas del usuario
 *     security:
 *       - bearerAuth: []
 *     parameters:
 *       - in: query
 *         name: page
 *         schema:
 *           type: integer
 *           default: 1
 *       - in: query
 *         name: limit
 *         schema:
 *           type: integer
 *           default: 10
 *     responses:
 *       200:
 *         description: Operaciones finalizadas obtenidas correctamente
 *         content:
 *           application/json:
 *             schema:
 *               type: object
 *               required: [success, message, data, totalCount]
 *               properties:
 *                 success:
 *                   type: boolean
 *                   example: true
 *                 message:
 *                   type: string
 *                   example: "Operaciones finalizadas"
 *                 data:
 *                   type: array
 *                   items:
 *                     type: object
 *                     properties:
 *                       id:
 *                         type: string
 *                       reference:
 *                         type: string
 *                       createdAt:
 *                         type: string
 *                         format: date-time
 *                       amount:
 *                         type: number
 *                       status:
 *                         type: string
 *                       statusName:
 *                         type: string
 *                         example: "Finalizado"
 *                       iconUrl:
 *                         type: string
 *                 totalCount:
 *                   type: integer
 *             example:
 *               success: true
 *               message: "Operaciones finalizadas"
 *               data:
 *                 - id: "6941b9cf429b137e4d5795bb"
 *                   reference: "02939145"
 *                   createdAt: "2026-02-02T20:34:34.435Z"
 *                   amount: 100
 *                   status: "completed"
 *                   statusName: "Finalizado"
 *                   iconUrl: "https://apipasta.legendsoft.com/public/icons/sticks-white.png"
 *               totalCount: 5
 *       401:
 *         $ref: "#/components/responses/Unauthorized"
 *       403:
 *         $ref: "#/components/responses/Forbidden"
 */
router.get("/completed", getCompletedOperations);

/**
 * @swagger
 * /operation/active:
 *   get:
 *     operationId: getActiveOperations
 *     tags: [Operations]
 *     summary: Listar operaciones activas del usuario (pendientes o aprobadas)
 *     security:
 *       - bearerAuth: []
 *     parameters:
 *       - in: query
 *         name: page
 *         schema:
 *           type: integer
 *           default: 1
 *       - in: query
 *         name: limit
 *         schema:
 *           type: integer
 *           default: 10
 *     responses:
 *       200:
 *         description: Operaciones activas obtenidas correctamente
 *         content:
 *           application/json:
 *             schema:
 *               type: object
 *               required: [success, message, data, totalCount]
 *               properties:
 *                 success:
 *                   type: boolean
 *                   example: true
 *                 message:
 *                   type: string
 *                   example: "Operaciones activas"
 *                 data:
 *                   type: array
 *                   items:
 *                     type: object
 *                     properties:
 *                       id:
 *                         type: string
 *                       reference:
 *                         type: string
 *                       createdAt:
 *                         type: string
 *                         format: date-time
 *                       amount:
 *                         type: number
 *                       status:
 *                         type: string
 *                       statusName:
 *                         type: string
 *                       iconUrl:
 *                         type: string
 *                 totalCount:
 *                   type: integer
 *             example:
 *               success: true
 *               message: "Operaciones activas"
 *               data:
 *                 - id: "6941b9cf429b137e4d5795bb"
 *                   reference: "02939145"
 *                   createdAt: "2026-02-02T20:34:34.435Z"
 *                   amount: 100
 *                   status: "approved"
 *                   statusName: "Aprobado"
 *                   iconUrl: "https://apipasta.legendsoft.com/public/icons/sticks-white.png"
 *               totalCount: 2
 *       401:
 *         $ref: "#/components/responses/Unauthorized"
 *       403:
 *         $ref: "#/components/responses/Forbidden"
 */
router.get("/active", getActiveOperations);

/**
 * @swagger
 * /operation/request:
 *   post:
 *     operationId: requestOperation
 *     tags: [Operations]
 *     summary: Solicitar operación de crédito
 *     security:
 *       - bearerAuth: []
 *     requestBody:
 *       required: true
 *       content:
 *         application/json:
 *           schema:
 *             $ref: '#/components/schemas/RequestOperationBody'
 *           example:
 *             currency: "USD"
 *             amount: 100
 *             feeCount: 6
 *             account: "665e3e2f2a9bd8c4b2c11111"
 *             isThirdParty: false
 *     responses:
 *       201:
 *         description: Operación creada exitosamente
 *         content:
 *           application/json:
 *             schema:
 *               type: object
 *               required: [success, message, data]
 *               properties:
 *                 success:
 *                   type: boolean
 *                 message:
 *                   type: string
 *                 data:
 *                   type: object
 *                   properties:
 *                     id:
 *                       type: string
 *                     currency:
 *                       type: string
 *                     amountVef:
 *                       type: number
 *                     rate:
 *                       type: number
 *                     amountUsd:
 *                       type: number
 *                     feeCount:
 *                       type: integer
 *                     isThirdParty:
 *                       type: boolean
 *                     beneficiary:
 *                       type: object
 *                       nullable: true
 *                     account:
 *                       type: object
 *                       properties:
 *                         bankCode:
 *                           type: string
 *                         identificationType:
 *                           type: string
 *                         identificationNumber:
 *                           type: string
 *                         number:
 *                           type: string
 *                     paymentPlan:
 *                       type: array
 *                       items:
 *                         type: object
 *                         properties:
 *                           date:
 *                             type: string
 *                             format: date-time
 *                           amount:
 *                             type: number
 *             example:
 *               success: true
 *               message: "Operation created successfully"
 *               data:
 *                 id: "6941b9cf429b137e4d5795bb"
 *                 currency: "USD"
 *                 amountVef: 37000
 *                 rate: 370
 *                 amountUsd: 100
 *                 feeCount: 6
 *                 isThirdParty: false
 *                 account:
 *                   bankCode: "0608"
 *                   identificationType: "V"
 *                   identificationNumber: "12345678"
 *                   number: "01020123456789012345"
 *                 paymentPlan:
 *                   - date: "2026-03-20T04:00:00.000Z"
 *                     amount: 19.17
 *                   - date: "2026-04-20T04:00:00.000Z"
 *                     amount: 19.17
 *       400:
 *         description: |
 *           Error de validación o requisitos no cumplidos. Códigos posibles:
 *           - **field_missing**: Campo requerido faltante o error de validación Joi
 *           - **not_active**: Sistema de crédito no está activo
 *           - **not_found**: Cliente, cuenta, o configuración min-score no encontrada
 *           - **not_met_requirements**: Score insuficiente para solicitar crédito
 *           - **max_amount_exceeded**: Monto excede el máximo permitido (individual o con deuda pendiente)
 *           - **fee_count_invalid**: Número de cuotas no permitido para el usuario
 *           - **error**: Error en simulación de crédito (LA Sistemas)
 *         content:
 *           application/json:
 *             schema:
 *               type: object
 *               required: [success, message, code]
 *               properties:
 *                 success:
 *                   type: boolean
 *                   example: false
 *                 message:
 *                   type: string
 *                 code:
 *                   type: string
 *                   enum:
 *                     - field_missing
 *                     - not_active
 *                     - not_found
 *                     - not_met_requirements
 *                     - max_amount_exceeded
 *                     - fee_count_invalid
 *                     - error
 *             examples:
 *               field_missing:
 *                 summary: Campo requerido faltante
 *                 value:
 *                   success: false
 *                   message: "Error de validación: \"currency\" is required"
 *                   code: "field_missing"
 *               not_active:
 *                 summary: Sistema no activo
 *                 value:
 *                   success: false
 *                   message: "El sistema de generación de operaciones de crédito no está activo en este momento. Por favor, intente mas tarde"
 *                   code: "not_active"
 *               not_found:
 *                 summary: Cliente, cuenta o configuración no encontrada
 *                 value:
 *                   success: false
 *                   message: "No se encontró información del cliente"
 *                   code: "not_found"
 *               not_found_account:
 *                 summary: Cuenta escogida no encontrada
 *                 value:
 *                   success: false
 *                   message: "Cuenta escogida no encontrada"
 *                   code: "not_found"
 *               not_met_requirements:
 *                 summary: Score insuficiente
 *                 value:
 *                   success: false
 *                   message: "Usted no cumple con los requisitos mínimos para la solicitud de crédito"
 *                   code: "not_met_requirements"
 *               max_amount_exceeded:
 *                 summary: Monto excede máximo permitido
 *                 value:
 *                   success: false
 *                   message: "La cantidad solicitada excede el máximo permitido para el usuario"
 *                   code: "max_amount_exceeded"
 *               fee_count_invalid:
 *                 summary: Número de cuotas inválido
 *                 value:
 *                   success: false
 *                   message: "El número de cuotas es inválido"
 *                   code: "fee_count_invalid"
 *               error:
 *                 summary: Error en simulación
 *                 value:
 *                   success: false
 *                   message: "Error al simular crédito en el sistema externo"
 *                   code: "error"
 *       401:
 *         $ref: "#/components/responses/Unauthorized"
 *       403:
 *         $ref: "#/components/responses/Forbidden"
 */
router.post("/request", requestOperation);

/**
 * @swagger
 * /operation/confirm:
 *   post:
 *     operationId: confirmOperation
 *     tags: [Operations]
 *     summary: Confirmar operación
 *     security:
 *       - bearerAuth: []
 *     requestBody:
 *       required: true
 *       content:
 *         application/json:
 *           schema:
 *             type: object
 *             required: [operationId]
 *             properties:
 *               operationId:
 *                 type: string
 *                 example: "6941b9cf429b137e4d5795bb"
 *               comment:
 *                 type: string
 *                 example: "comentario"
 *               deviceType:
 *                 type: string
 *                 example: "Celular"
 *               deviceDescription:
 *                 type: string
 *                 example: "Samsung Galaxy S22"
 *               ipAddress:
 *                 type: string
 *                 example: "0.0.0.1"
 *     responses:
 *       200:
 *         description: Operación confirmada
 *         content:
 *           application/json:
 *             schema:
 *               type: object
 *               required: [success, message]
 *               properties:
 *                 success:
 *                   type: boolean
 *                 message:
 *                   type: string
 *             example:
 *               success: true
 *               message: "Operación confirmada"
 *       400:
 *         description: |
 *           Error de validación o en proceso de confirmación. Códigos posibles:
 *           - **field_missing**: Campo operationId requerido faltante
 *           - **invalid_status**: Operación no está en estado void (ya confirmada o rechazada)
 *           - **error**: Error en Sypago (generar transacción, obtener resultado, o transacción rechazada)
 *         content:
 *           application/json:
 *             schema:
 *               type: object
 *               required: [success, message, code]
 *               properties:
 *                 success:
 *                   type: boolean
 *                   example: false
 *                 message:
 *                   type: string
 *                 code:
 *                   type: string
 *                   enum: [field_missing, invalid_status, error]
 *                 error:
 *                   type: string
 *                   description: Detalle adicional (opcional)
 *             examples:
 *               field_missing:
 *                 summary: Campo requerido faltante
 *                 value:
 *                   success: false
 *                   message: "Campo 'operationId' es requerido"
 *                   code: "field_missing"
 *               invalid_status:
 *                 summary: Estado de operación inválido
 *                 value:
 *                   success: false
 *                   message: "La operación tiene estatus no válido"
 *                   code: "invalid_status"
 *               error_transaction:
 *                 summary: Error al generar transacción Sypago
 *                 value:
 *                   success: false
 *                   message: "Error al generar la transacción"
 *                   code: "error"
 *                   error: "Mensaje de Sypago"
 *               error_rejected:
 *                 summary: Transacción rechazada
 *                 value:
 *                   success: false
 *                   message: "La transacción no está aprobada - Código rechazado"
 *                   code: "error"
 *                   error: "Descripción del estado"
 *       404:
 *         description: Operación no encontrada
 *         content:
 *           application/json:
 *             schema:
 *               type: object
 *               properties:
 *                 success:
 *                   type: boolean
 *                   example: false
 *                 message:
 *                   type: string
 *                   example: "No se encontró la operación"
 *                 code:
 *                   type: string
 *                   example: "not_found"
 *       401:
 *         $ref: "#/components/responses/Unauthorized"
 *       403:
 *         $ref: "#/components/responses/Forbidden"
 */
router.post("/confirm", confirmOperation);

/**
 * @swagger
 * /operation/details/{operationId}:
 *   get:
 *     operationId: getOperationDetails
 *     tags: [Operations]
 *     summary: Detalles de una operación
 *     security:
 *       - bearerAuth: []
 *     parameters:
 *       - in: path
 *         name: operationId
 *         required: true
 *         schema:
 *           type: string
 *     responses:
 *       200:
 *         description: Detalles de la operación
 *         content:
 *           application/json:
 *             schema:
 *               type: object
 *               properties:
 *                 success:
 *                   type: boolean
 *                   example: true
 *                 message:
 *                   type: string
 *                   example: "Detalles de la operación"
 *                 data:
 *                   type: object
 *                   properties:
 *                     reference:
 *                       type: string
 *                       example: "02939145"
 *                     createdAt:
 *                       type: string
 *                       format: date-time
 *                       example: "2026-02-02T20:34:34.435Z"
 *                     amountUsd:
 *                       type: number
 *                       example: 1
 *                     amountVef:
 *                       type: number
 *                       example: 369.14
 *                     rate:
 *                       type: number
 *                       example: 370.25
 *                     feeCount:
 *                       type: number
 *                       example: 6
 *                     account:
 *                       type: string
 *                       example: "Bancamiga Banco Universal, C.A. 0608"
 *                     paymentPlan:
 *                       type: array
 *                       items:
 *                         type: object
 *                         properties:
 *                           date:
 *                             type: string
 *                             format: date-time
 *                           amount:
 *                             type: number
 *             example:
 *               success: true
 *               message: "Detalles de la operación"
 *               data:
 *                 reference: "02939145"
 *                 createdAt: "2026-02-02T20:34:34.435Z"
 *                 amountUsd: 100
 *                 amountVef: 37000
 *                 rate: 370
 *                 feeCount: 6
 *                 account: "Bancamiga Banco Universal, C.A. 0608"
 *                 paymentPlan:
 *                   - date: "2026-03-20T04:00:00.000Z"
 *                     amount: 19.17
 *                   - date: "2026-04-20T04:00:00.000Z"
 *                     amount: 19.17
 *       400:
 *         description: operationId requerido
 *       404:
 *         description: Operación no encontrada
 *       401:
 *         $ref: "#/components/responses/Unauthorized"
 *       403:
 *         $ref: "#/components/responses/Forbidden"
 */
router.get("/details/:operationId", getOperationDetails);

/**
 * @swagger
 * /operation/payments:
 *   get:
 *     operationId: getOperationPayments
 *     tags: [Operations]
 *     summary: Listar deudas del usuario y total pendiente
 *     security:
 *       - bearerAuth: []
 *     parameters:
 *       - in: query
 *         name: page
 *         schema:
 *           type: integer
 *           default: 1
 *         description: Número de página
 *       - in: query
 *         name: limit
 *         schema:
 *           type: integer
 *           default: 50
 *         description: Elementos por página
 *     responses:
 *       200:
 *         description: Listado de deudas y total pendiente
 *         content:
 *           application/json:
 *             schema:
 *               type: object
 *               properties:
 *                 success:
 *                   type: boolean
 *                   example: true
 *                 message:
 *                   type: string
 *                   example: "Listado de deudas del usuario y total pendiente"
 *                 data:
 *                   type: object
 *                   properties:
 *                     operationPayments:
 *                       type: array
 *                       items:
 *                         type: object
 *                         properties:
 *                           id:
 *                             type: string
 *                             example: "0126C21003721"
 *                           date:
 *                             type: string
 *                             format: date-time
 *                             example: "2026-03-08T04:00:00.000Z"
 *                           status:
 *                             type: string
 *                             example: "pending"
 *                           statusName:
 *                             type: string
 *                             example: "Pendiente"
 *                           amountUsd:
 *                             type: number
 *                             example: 0.19
 *                           iconUrl:
 *                             type: string
 *                             example: "https://apipasta.legendsoft.com/public/icons/sticks-white.png"
 *                           operationReference:
 *                             type: string
 *                             example: "22131598"
 *                           points:
 *                             type: number
 *                             example: 0.19
 *                     totalAmount:
 *                       type: number
 *                       description: Total pendiente en USD
 *             example:
 *               success: true
 *               message: "Listado de deudas del usuario y total pendiente"
 *               data:
 *                 operationPayments:
 *                   - id: "0126C21003721"
 *                     date: "2026-03-08T04:00:00.000Z"
 *                     status: "pending"
 *                     statusName: "Pendiente"
 *                     amountUsd: 0.19
 *                     operationReference: "22131598"
 *                     points: 0.19
 *                 totalAmount: 38.34
 *               totalCount: 15
 *       400:
 *         description: Error al consultar deuda (LA Sistemas)
 *         content:
 *           application/json:
 *             schema:
 *               type: object
 *               properties:
 *                 success:
 *                   type: boolean
 *                   example: false
 *                 message:
 *                   type: string
 *                 code:
 *                   type: string
 *                   example: "error"
 *       404:
 *         description: Usuario no encontrado
 *         content:
 *           application/json:
 *             schema:
 *               type: object
 *               properties:
 *                 success:
 *                   type: boolean
 *                   example: false
 *                 message:
 *                   type: string
 *                   example: "Usuario no encontrado"
 *                 code:
 *                   type: string
 *                   example: "not_found"
 *       401:
 *         $ref: "#/components/responses/Unauthorized"
 *       403:
 *         $ref: "#/components/responses/Forbidden"
 */
router.get("/payments", getOperationPaymentsWithTotal);

/**
 * @swagger
 * /operation/movements:
 *   get:
 *     operationId: getOperationMovements
 *     tags: [Operations]
 *     summary: Obtener movimientos (operaciones, pagos, membresías)
 *     security:
 *       - bearerAuth: []
 *     parameters:
 *       - in: query
 *         name: page
 *         schema:
 *           type: integer
 *           default: 1
 *         description: Número de página
 *       - in: query
 *         name: limit
 *         schema:
 *           type: integer
 *           default: 50
 *         description: Elementos por página
 *       - in: query
 *         name: type
 *         schema:
 *           type: string
 *           enum: [paid, liquidated]
 *         description: |
 *           Filtrar por tipo: "paid" solo pagos, "liquidated" solo operaciones/membresías
 *           Sin parámetro = todos los movimientos
 *     responses:
 *       200:
 *         description: Movimientos obtenidos correctamente
 *         content:
 *           application/json:
 *             schema:
 *               type: object
 *               properties:
 *                 success:
 *                   type: boolean
 *                   example: true
 *                 message:
 *                   type: string
 *                   example: "Movimientos obtenidos correctamente"
 *                 data:
 *                   type: array
 *                   items:
 *                     type: object
 *                     properties:
 *                       id:
 *                         type: string
 *                         example: "69864ab103d5a2078dc4a857"
 *                       createdAt:
 *                         type: string
 *                         format: date-time
 *                         example: "2026-02-06T20:10:25.198Z"
 *                       amountUsd:
 *                         type: number
 *                         example: 0.57
 *                       amountVef:
 *                         type: number
 *                         example: 217.23
 *                       amountVefBase:
 *                         type: number
 *                         example: 217.23
 *                       commission:
 *                         type: number
 *                         example: 0
 *                       reference:
 *                         type: string
 *                         example: "16872724"
 *                       movementType:
 *                         type: string
 *                         example: "payment"
 *                       description:
 *                         type: string
 *                         example: "Pago"
 *                       iconUrl:
 *                         type: string
 *                         nullable: true
 *                         example: null
 *                       status:
 *                         type: string
 *                         example: "received"
 *                 totalCount:
 *                   type: integer
 *                   description: Total de movimientos (sin paginar)
 *             example:
 *               success: true
 *               message: "Movimientos obtenidos correctamente"
 *               data:
 *                 - id: "69864ab103d5a2078dc4a857"
 *                   createdAt: "2026-02-06T20:10:25.198Z"
 *                   amountUsd: 0.57
 *                   amountVef: 217.23
 *                   amountVefBase: 217.23
 *                   commission: 0
 *                   reference: "16872724"
 *                   movementType: "payment"
 *                   description: "Pago"
 *                   iconUrl: null
 *                   status: "received"
 *               totalCount: 25
 *       401:
 *         $ref: "#/components/responses/Unauthorized"
 *       403:
 *         $ref: "#/components/responses/Forbidden"
 */
router.get("/movements", getMovements);

/**
 * @swagger
 * /operation/pay-debt:
 *   post:
 *     operationId: payDebt
 *     tags: [Operations]
 *     summary: Registrar pago de deuda
 *     security:
 *       - bearerAuth: []
 *     requestBody:
 *       required: true
 *       content:
 *         application/json:
 *           schema:
 *             $ref: '#/components/schemas/PayDebtBody'
 *           example:
 *             payments: ["0126C21003721", "0126C21003722"]
 *     responses:
 *       200:
 *         description: Operación creada en espera de confirmación
 *         content:
 *           application/json:
 *             schema:
 *               type: object
 *               required: [success, message, data]
 *               properties:
 *                 success:
 *                   type: boolean
 *                 message:
 *                   type: string
 *                 data:
 *                   type: object
 *                   properties:
 *                     id:
 *                       type: string
 *                     feeCount:
 *                       type: integer
 *                     amountUsd:
 *                       type: number
 *                     amountVef:
 *                       type: number
 *                     rate:
 *                       type: number
 *                     points:
 *                       type: number
 *             example:
 *               success: true
 *               message: "Operación creada en espera de confirmación"
 *               data:
 *                 id: "69864ab103d5a2078dc4a857"
 *                 feeCount: 2
 *                 amountUsd: 38.34
 *                 amountVef: 14185.58
 *                 rate: 370
 *                 points: 38.34
 *       400:
 *         description: |
 *           Error de validación o al procesar cuotas. Códigos posibles:
 *           - **field_missing**: Error de validación (payments requerido, array vacío, etc.)
 *           - **error**: Error al consultar deuda en LA Sistemas
 *           - **already_paid**: Una o más cuotas ya están pagadas
 *           - **not_found**: Cuota no encontrada en el sistema de deudas
 *         content:
 *           application/json:
 *             schema:
 *               type: object
 *               required: [success, message, code]
 *               properties:
 *                 success:
 *                   type: boolean
 *                   example: false
 *                 message:
 *                   type: string
 *                 code:
 *                   type: string
 *                   enum: [field_missing, error, already_paid, not_found]
 *             examples:
 *               field_missing:
 *                 summary: Validación fallida
 *                 value:
 *                   success: false
 *                   message: "Error de validación: El campo \"payments\" debe ser un array"
 *                   code: "field_missing"
 *               error:
 *                 summary: Error consultando deuda
 *                 value:
 *                   success: false
 *                   message: "Mensaje de error de LA Sistemas"
 *                   code: "error"
 *               already_paid:
 *                 summary: Cuota ya pagada
 *                 value:
 *                   success: false
 *                   message: "Cuota ya pagada"
 *                   code: "already_paid"
 *               not_found:
 *                 summary: Cuota no encontrada
 *                 value:
 *                   success: false
 *                   message: "Cuota no encontrada"
 *                   code: "not_found"
 *       401:
 *         $ref: "#/components/responses/Unauthorized"
 *       403:
 *         $ref: "#/components/responses/Forbidden"
 */
router.post("/pay-debt", payDebt);

/**
 * @swagger
 * /operation/pay-debt-confirmation:
 *   post:
 *     operationId: payDebtConfirmation
 *     tags: [Operations]
 *     summary: Confirmar pago de deuda
 *     security:
 *       - bearerAuth: []
 *     requestBody:
 *       required: true
 *       content:
 *         application/json:
 *           schema:
 *             $ref: '#/components/schemas/PayDebtConfirmationBody'
 *           example:
 *             id: "69864ab103d5a2078dc4a857"
 *             paymentType: "mobile"
 *             phone: "04141234567"
 *             reference: "16872724"
 *             otp: "123456"
 *     responses:
 *       200:
 *         description: Pago confirmado exitosamente
 *         content:
 *           application/json:
 *             schema:
 *               type: object
 *               required: [success, message, data]
 *               properties:
 *                 success:
 *                   type: boolean
 *                 message:
 *                   type: string
 *                 data:
 *                   type: object
 *                   properties:
 *                     newLevel:
 *                       type: object
 *                       description: Nuevo nivel si hubo actualización
 *             example:
 *               success: true
 *               message: "Operación confirmada"
 *               data:
 *                 newLevel:
 *                   level: "Oro"
 *                   points: 150
 *                   allowedFeeCount: 12
 *       400:
 *         description: |
 *           Error de validación o al procesar el pago. Códigos posibles:
 *           - **validation**: Error de validación Joi (id, paymentType, phone, reference, otp, etc.)
 *           - **error**: Error en pago móvil/transfer (Bancamiga) o al buscar referencia
 *           - **otp_error**: No se ha generado el código OTP (debit sin request-otp previo)
 *           - **payment_error**: Error al ejecutar débito OTP (Sypago)
 *         content:
 *           application/json:
 *             schema:
 *               type: object
 *               required: [success, message, code]
 *               properties:
 *                 success:
 *                   type: boolean
 *                   example: false
 *                 message:
 *                   type: string
 *                 code:
 *                   type: string
 *                   enum: [validation, error, otp_error, payment_error]
 *             examples:
 *               validation:
 *                 summary: Error de validación
 *                 value:
 *                   success: false
 *                   message: "Error de validación: El campo \"id\" es obligatorio"
 *                   code: "validation"
 *               error:
 *                 summary: Error en pago móvil/transfer
 *                 value:
 *                   success: false
 *                   message: "Referencia no encontrada o pago no verificado"
 *                   code: "error"
 *               otp_error:
 *                 summary: OTP no generado
 *                 value:
 *                   success: false
 *                   message: "No se ha generado el código de OTP"
 *                   code: "otp_error"
 *               payment_error:
 *                 summary: Error en débito OTP
 *                 value:
 *                   success: false
 *                   message: "Error al ejecutar el pago - Mensaje de Sypago"
 *                   code: "payment_error"
 *       404:
 *         description: Operación de pago no encontrada (id inválido o ya confirmada)
 *         content:
 *           application/json:
 *             schema:
 *               type: object
 *               properties:
 *                 success:
 *                   type: boolean
 *                   example: false
 *                 message:
 *                   type: string
 *                   example: "No se encontró la operación"
 *                 code:
 *                   type: string
 *                   example: "not_found"
 *       401:
 *         $ref: "#/components/responses/Unauthorized"
 *       403:
 *         $ref: "#/components/responses/Forbidden"
 */
router.post("/pay-debt-confirmation", payDebtConfirmation);

/**
 * @swagger
 * /operation/request-otp:
 *   post:
 *     operationId: requestOtp
 *     tags: [Operations]
 *     summary: Solicitar código OTP
 *     security:
 *       - bearerAuth: []
 *     requestBody:
 *       required: true
 *       content:
 *         application/json:
 *           schema:
 *             $ref: '#/components/schemas/RequestOtpBody'
 *           example:
 *             id: "69864ab103d5a2078dc4a857"
 *             phone: "04141234567"
 *             bankCode: "0102"
 *             identificationType: "V"
 *             identificationNumber: "12345678"
 *     responses:
 *       200:
 *         description: Código OTP enviado correctamente
 *         content:
 *           application/json:
 *             schema:
 *               type: object
 *               required: [success, message]
 *               properties:
 *                 success:
 *                   type: boolean
 *                 message:
 *                   type: string
 *             example:
 *               success: true
 *               message: "Código de OTP enviado correctamente"
 *       400:
 *         description: |
 *           Error de validación o al generar OTP. Códigos posibles:
 *           - **field_missing**: Error de validación (id, phone, bankCode, identificationType, identificationNumber requeridos)
 *           - **otp_error**: Error al generar OTP en Sypago (datos inválidos, banco no soportado, etc.)
 *         content:
 *           application/json:
 *             schema:
 *               type: object
 *               required: [success, message, code]
 *               properties:
 *                 success:
 *                   type: boolean
 *                   example: false
 *                 message:
 *                   type: string
 *                 code:
 *                   type: string
 *                   enum: [field_missing, otp_error]
 *             examples:
 *               field_missing:
 *                 summary: Validación fallida
 *                 value:
 *                   success: false
 *                   message: "Error de validación: El campo \"id\" es requerido"
 *                   code: "field_missing"
 *               otp_error:
 *                 summary: Error al generar OTP
 *                 value:
 *                   success: false
 *                   message: "Ha ocurrido un error al generar el código OTP, por favor verifica tus datos e intenta de nuevo"
 *                   code: "otp_error"
 *       404:
 *         description: Operación de pago no encontrada (id inválido o ya confirmada)
 *         content:
 *           application/json:
 *             schema:
 *               type: object
 *               properties:
 *                 success:
 *                   type: boolean
 *                   example: false
 *                 message:
 *                   type: string
 *                   example: "No se encontró la operación"
 *                 code:
 *                   type: string
 *                   example: "not_found"
 *       401:
 *         $ref: "#/components/responses/Unauthorized"
 *       403:
 *         $ref: "#/components/responses/Forbidden"
 */
router.post("/request-otp", requestSypagoOtp);
// router.get("/account-charge-link", getAccountChargeLink); // Banesco - ya no integrado

router.use(authorizeModules("operations"));

/**
 * @swagger
 * /operation/all:
 *   get:
 *     operationId: getAllOperations
 *     tags: [Operations]
 *     summary: Listar todas las operaciones (admin)
 *     security:
 *       - bearerAuth: []
 *     parameters:
 *       - in: query
 *         name: page
 *         schema:
 *           type: integer
 *           default: 1
 *       - in: query
 *         name: limit
 *         schema:
 *           type: integer
 *           default: 10
 *       - in: query
 *         name: globalFilter
 *         schema:
 *           type: string
 *         description: Buscar por nombre, email o monto
 *       - in: query
 *         name: startDate
 *         schema:
 *           type: string
 *           format: date
 *         description: Fecha inicio (YYYY-MM-DD) zona America/Caracas
 *       - in: query
 *         name: endDate
 *         schema:
 *           type: string
 *           format: date
 *         description: Fecha fin (YYYY-MM-DD) zona America/Caracas
 *     responses:
 *       200:
 *         description: Operaciones obtenidas correctamente
 *         content:
 *           application/json:
 *             schema:
 *               type: object
 *               required: [success, message, data, totalCount]
 *               properties:
 *                 success:
 *                   type: boolean
 *                   example: true
 *                 message:
 *                   type: string
 *                   example: "Operations retrieved successfully"
 *                 data:
 *                   type: array
 *                   items:
 *                     type: object
 *                     properties:
 *                       id:
 *                         type: string
 *                       reference:
 *                         type: string
 *                       createdAt:
 *                         type: string
 *                         format: date-time
 *                       amount:
 *                         type: number
 *                       status:
 *                         type: object
 *                         properties:
 *                           id:
 *                             type: string
 *                           name:
 *                             type: string
 *                       amountUsd:
 *                         type: number
 *                       clientName:
 *                         type: string
 *                       clientEmail:
 *                         type: string
 *                 totalCount:
 *                   type: integer
 *             example:
 *               success: true
 *               message: "Operations retrieved successfully"
 *               data:
 *                 - id: "6941b9cf429b137e4d5795bb"
 *                   reference: "02939145"
 *                   createdAt: "2026-02-02T20:34:34.435Z"
 *                   amount: 100
 *                   status:
 *                     id: "approved"
 *                     name: "Aprobado"
 *                   amountUsd: 100
 *                   clientName: "Juan Pérez"
 *                   clientEmail: "juan@example.com"
 *               totalCount: 42
 *       401:
 *         $ref: "#/components/responses/Unauthorized"
 *       403:
 *         $ref: "#/components/responses/Forbidden"
 */
router.get("/all", getAllOperations);

/**
 * @swagger
 * /operation/get/{operationId}:
 *   get:
 *     operationId: getOperation
 *     tags: [Operations]
 *     summary: Obtener detalle de operación por ID (admin)
 *     security:
 *       - bearerAuth: []
 *     parameters:
 *       - in: path
 *         name: operationId
 *         required: true
 *         schema:
 *           type: string
 *     responses:
 *       200:
 *         description: Detalles de la operación
 *         content:
 *           application/json:
 *             schema:
 *               type: object
 *               required: [success, message, data]
 *               properties:
 *                 success:
 *                   type: boolean
 *                   example: true
 *                 message:
 *                   type: string
 *                   example: "Detalles de la operación"
 *                 data:
 *                   type: object
 *                   properties:
 *                     reference:
 *                       type: string
 *                     amountUsd:
 *                       type: number
 *                     status:
 *                       type: string
 *                     clientName:
 *                       type: string
 *                     clientEmail:
 *                       type: string
 *                     paymentPlan:
 *                       type: array
 *             example:
 *               success: true
 *               message: "Detalles de la operación"
 *               data:
 *                 reference: "02939145"
 *                 amountUsd: 100
 *                 status: "approved"
 *                 clientName: "Juan Pérez"
 *                 clientEmail: "juan@example.com"
 *                 paymentPlan: []
 *       404:
 *         description: Operación o usuario no encontrado
 *       401:
 *         $ref: "#/components/responses/Unauthorized"
 *       403:
 *         $ref: "#/components/responses/Forbidden"
 */
router.get("/get/:operationId", getOperationDetailsById);

/**
 * @swagger
 * /operation/all-payments:
 *   get:
 *     operationId: getOperationPaymentsAdmin
 *     tags: [Operations]
 *     summary: Listar cuotas de operaciones (admin)
 *     security:
 *       - bearerAuth: []
 *     parameters:
 *       - in: query
 *         name: page
 *         schema:
 *           type: integer
 *           default: 1
 *       - in: query
 *         name: limit
 *         schema:
 *           type: integer
 *           default: 10
 *       - in: query
 *         name: globalFilter
 *         schema:
 *           type: string
 *         description: Buscar por nombre de cliente o monto
 *       - in: query
 *         name: startDate
 *         schema:
 *           type: string
 *           format: date
 *         description: Fecha inicio (YYYY-MM-DD)
 *       - in: query
 *         name: endDate
 *         schema:
 *           type: string
 *           format: date
 *         description: Fecha fin (YYYY-MM-DD)
 *       - in: query
 *         name: status
 *         schema:
 *           type: string
 *           enum: [pending, paid, overdue, inArrears]
 *         description: Filtrar por estado de cuota
 *     responses:
 *       200:
 *         description: Cuotas de operaciones obtenidas correctamente
 *         content:
 *           application/json:
 *             schema:
 *               type: object
 *               required: [success, message, data, totalCount]
 *               properties:
 *                 success:
 *                   type: boolean
 *                 message:
 *                   type: string
 *                 data:
 *                   type: object
 *                   properties:
 *                     userOperationPayments:
 *                       type: array
 *                     totalPendingAmountUsd:
 *                       type: number
 *                 totalCount:
 *                   type: integer
 *       401:
 *         $ref: "#/components/responses/Unauthorized"
 *       403:
 *         $ref: "#/components/responses/Forbidden"
 */
router.get("/all-payments", getOperationPayments);

/**
 * @swagger
 * /operation/payments-list:
 *   get:
 *     operationId: getPaymentsList
 *     tags: [Operations]
 *     summary: Listar todos los pagos (admin)
 *     security:
 *       - bearerAuth: []
 *     parameters:
 *       - in: query
 *         name: page
 *         schema:
 *           type: integer
 *           default: 1
 *       - in: query
 *         name: limit
 *         schema:
 *           type: integer
 *           default: 10
 *       - in: query
 *         name: globalFilter
 *         schema:
 *           type: string
 *         description: Buscar por nombre de cliente o monto
 *       - in: query
 *         name: startDate
 *         schema:
 *           type: string
 *           format: date
 *         description: Fecha inicio (YYYY-MM-DD)
 *       - in: query
 *         name: endDate
 *         schema:
 *           type: string
 *           format: date
 *         description: Fecha fin (YYYY-MM-DD)
 *     responses:
 *       200:
 *         description: Lista de pagos obtenida correctamente
 *         content:
 *           application/json:
 *             schema:
 *               type: object
 *               required: [success, message, data, totalCount]
 *               properties:
 *                 success:
 *                   type: boolean
 *                   example: true
 *                 message:
 *                   type: string
 *                   example: "Payments retrieved successfully"
 *                 data:
 *                   type: array
 *                   items:
 *                     type: object
 *                     properties:
 *                       id:
 *                         type: string
 *                       fecha:
 *                         type: string
 *                         format: date-time
 *                       monto:
 *                         type: number
 *                       cliente:
 *                         type: string
 *                       esDeTercero:
 *                         type: boolean
 *                       status:
 *                         type: string
 *                       statusName:
 *                         type: string
 *                 totalCount:
 *                   type: integer
 *             example:
 *               success: true
 *               message: "Payments retrieved successfully"
 *               data:
 *                 - id: "69864ab103d5a2078dc4a857"
 *                   fecha: "2026-02-06T20:10:25.198Z"
 *                   monto: 38.34
 *                   cliente: "Juan Pérez"
 *                   esDeTercero: false
 *                   status: "confirmed"
 *                   statusName: "Confirmado"
 *               totalCount: 15
 *       401:
 *         $ref: "#/components/responses/Unauthorized"
 *       403:
 *         $ref: "#/components/responses/Forbidden"
 */
router.get("/payments-list", getAllPayments);

/**
 * @swagger
 * /operation/payment/{paymentId}:
 *   get:
 *     operationId: getPayment
 *     tags: [Operations]
 *     summary: Obtener detalle de un pago (admin)
 *     security:
 *       - bearerAuth: []
 *     parameters:
 *       - in: path
 *         name: paymentId
 *         required: true
 *         schema:
 *           type: string
 *     responses:
 *       200:
 *         description: Detalle del pago obtenido correctamente
 *         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
 *                     amountUsd:
 *                       type: number
 *                     status:
 *                       type: string
 *                     user:
 *                       type: object
 *             example:
 *               success: true
 *               message: "Detalle del pago"
 *               data:
 *                 id: "69864ab103d5a2078dc4a857"
 *                 amountUsd: 38.34
 *                 status: "confirmed"
 *                 user:
 *                   name: "Juan"
 *                   lastname: "Pérez"
 *                   document: "12345678"
 *       404:
 *         description: Pago no encontrado
 *       401:
 *         $ref: "#/components/responses/Unauthorized"
 *       403:
 *         $ref: "#/components/responses/Forbidden"
 */
router.get("/payment/:paymentId", getPaymentDetailsById);

/**
 * @swagger
 * /operation/treasury:
 *   get:
 *     operationId: getTreasuryData
 *     tags: [Operations]
 *     summary: Obtener datos de tesorería (admin)
 *     security:
 *       - bearerAuth: []
 *     responses:
 *       200:
 *         description: Datos de tesorería obtenidos correctamente
 *         content:
 *           application/json:
 *             schema:
 *               type: object
 *               required: [success, message, data]
 *               properties:
 *                 success:
 *                   type: boolean
 *                   example: true
 *                 message:
 *                   type: string
 *                   example: "Datos de tesorería obtenidos correctamente"
 *                 data:
 *                   type: object
 *                   properties:
 *                     clientes:
 *                       type: object
 *                       properties:
 *                         activos:
 *                           type: object
 *                           properties:
 *                             cantidad:
 *                               type: integer
 *                         morosos:
 *                           type: object
 *                         vencidos:
 *                           type: object
 *                         inactivos:
 *                           type: object
 *                         enCola:
 *                           type: object
 *                     capital:
 *                       type: object
 *                       properties:
 *                         disponible:
 *                           type: object
 *                           properties:
 *                             usd:
 *                               type: number
 *                             vef:
 *                               type: number
 *                         vigente:
 *                           type: object
 *                         moroso:
 *                           type: object
 *                         vencido:
 *                           type: object
 *                     solicitudes:
 *                       type: object
 *                     caja:
 *                       type: object
 *                       properties:
 *                         saldoBs:
 *                           type: number
 *                         saldoUsd:
 *                           type: number
 *                     pasivo:
 *                       type: object
 *                     tasaCambio:
 *                       type: object
 *                       properties:
 *                         usd:
 *                           type: number
 *             example:
 *               success: true
 *               message: "Datos de tesorería obtenidos correctamente"
 *               data:
 *                 clientes:
 *                   activos:
 *                     cantidad: 150
 *                   morosos:
 *                     cantidad: 5
 *                   vencidos:
 *                     cantidad: 12
 *                   inactivos:
 *                     cantidad: 30
 *                   enCola:
 *                     cantidad: 8
 *                 capital:
 *                   disponible:
 *                     usd: 50000
 *                     vef: 18500000
 *                   vigente:
 *                     usd: 25000
 *                     vef: 9250000
 *                 caja:
 *                   saldoBs: 10000000
 *                   saldoUsd: 15000
 *                 tasaCambio:
 *                   usd: 370
 *       401:
 *         $ref: "#/components/responses/Unauthorized"
 *       403:
 *         $ref: "#/components/responses/Forbidden"
 */
router.get("/treasury", getTreasuryData);

export default router;
