import { Router } from "express";
import {
  createAccount,
  deleteAccount,
  getAccount,
  getAccounts,
  getBanks,
  updateAccount,
  getAccountUnmasked,
} from "../controllers/accountController";
import { verifyToken, authorizeRoles } from "../middlewares/authJwt";

const routes = Router();

/**
 * @swagger
 * tags:
 *   name: Accounts
 *   description: Cuentas bancarias del usuario
 */

/**
 * @swagger
 * /accounts/banks:
 *   get:
 *     operationId: getBanks
 *     tags: [Accounts]
 *     summary: Listar bancos disponibles
 *     description: Obtiene el listado de bancos para asociar cuentas
 *     responses:
 *       200:
 *         description: Lista de bancos obtenida correctamente
 *         content:
 *           application/json:
 *             schema:
 *               type: object
 *               required: [success, message, data]
 *               properties:
 *                 success:
 *                   type: boolean
 *                   example: true
 *                 message:
 *                   type: string
 *                   example: Banks retrieved successfully
 *                 data:
 *                   type: array
 *                   items:
 *                     type: object
 *                     properties:
 *                       _id:
 *                         type: string
 *                         description: ID del banco
 *                       code:
 *                         type: string
 *                         description: Código del banco
 *                       name:
 *                         type: string
 *                         description: Nombre del banco
 *             examples:
 *               conBancos:
 *                 summary: Lista con bancos
 *                 value:
 *                   success: true
 *                   message: Banks retrieved successfully
 *                   data:
 *                     - _id: "507f1f77bcf86cd799439011"
 *                       code: "0102"
 *                       name: Banco de Venezuela
 *                     - _id: "507f1f77bcf86cd799439012"
 *                       code: "0104"
 *                       name: Banco Venezolano de Crédito
 *               listaVacia:
 *                 summary: Lista vacía (sin bancos en el sistema)
 *                 value:
 *                   success: true
 *                   message: Banks retrieved successfully
 *                   data: []
 *       400:
 *         description: Error al obtener los bancos (ej. fallo de conexión a BD)
 *         content:
 *           application/json:
 *             schema:
 *               type: object
 *               required: [success, message, code]
 *               properties:
 *                 success:
 *                   type: boolean
 *                   example: false
 *                 message:
 *                   type: string
 *                   example: Error
 *                 code:
 *                   type: string
 *                   example: error
 *                 error:
 *                   description: Detalle del error (MongoNetworkError, MongoServerSelectionError, etc.)
 *             example:
 *               success: false
 *               message: Error
 *               code: error
 *               error:
 *                 name: MongoNetworkError
 *                 message: connection refused
 */
routes.route("/banks").get(getBanks);

routes.use(verifyToken, authorizeRoles("user"));

/**
 * @swagger
 * /accounts/create:
 *   post:
 *     operationId: createAccount
 *     tags: [Accounts]
 *     summary: Crear cuenta
 *     security:
 *       - bearerAuth: []
 *     requestBody:
 *       required: true
 *       content:
 *         application/json:
 *           schema:
 *             type: object
 *             required: [bankCode, type, number]
 *             properties:
 *               bankCode:
 *                 type: string
 *                 description: Código del banco (debe existir en el sistema)
 *               type:
 *                 type: string
 *                 description: Tipo de cuenta
 *               number:
 *                 type: string
 *                 description: Número de cuenta
 *     responses:
 *       201:
 *         description: Cuenta creada correctamente
 *         content:
 *           application/json:
 *             schema:
 *               type: object
 *               required: [success, message]
 *               properties:
 *                 success:
 *                   type: boolean
 *                   example: true
 *                 message:
 *                   type: string
 *                   example: Account created successfully
 *             example:
 *               success: true
 *               message: Account created successfully
 *       400:
 *         description: Campos requeridos faltantes
 *         content:
 *           application/json:
 *             schema:
 *               type: object
 *               required: [success, message, code]
 *               properties:
 *                 success:
 *                   type: boolean
 *                   example: false
 *                 message:
 *                   type: string
 *                   example: Bank code, type and number are required
 *                 code:
 *                   type: string
 *                   example: field_missing
 *             example:
 *               success: false
 *               message: Bank code, type and number are required
 *               code: field_missing
 *       401:
 *         $ref: "#/components/responses/Unauthorized"
 *       500:
 *         description: Error al crear la cuenta (ej. banco no encontrado, error de BD)
 *         content:
 *           application/json:
 *             schema:
 *               type: object
 *               required: [success, message]
 *               properties:
 *                 success:
 *                   type: boolean
 *                   example: false
 *                 message:
 *                   type: string
 *                   example: Error creating account
 *                 error:
 *                   description: Detalle del error
 *             example:
 *               success: false
 *               message: Error creating account
 *               error:
 *                 message: Bank not found
 */
routes.post("/create", createAccount);

/**
 * @swagger
 * /accounts:
 *   get:
 *     tags: [Accounts]
 *     summary: Listar cuentas del usuario
 *     security:
 *       - bearerAuth: []
 *     responses:
 *       200:
 *         description: Cuentas obtenidas correctamente
 *         content:
 *           application/json:
 *             schema:
 *               type: object
 *               required: [success, message, data]
 *               properties:
 *                 success:
 *                   type: boolean
 *                   example: true
 *                 message:
 *                   type: string
 *                 data:
 *                   type: array
 *                   items:
 *                     type: object
 *                     properties:
 *                       id:
 *                         type: string
 *                         description: ID de la cuenta
 *                       type:
 *                         type: string
 *                         description: Tipo de cuenta
 *                       number:
 *                         type: string
 *                         description: Número enmascarado (primeros 4 y últimos 4 visibles)
 *                       bankCode:
 *                         type: string
 *                         description: Código del banco
 *                       bankName:
 *                         type: string
 *                         description: Nombre del banco
 *             examples:
 *               conCuentas:
 *                 summary: Lista con cuentas
 *                 value:
 *                   success: true
 *                   message: Accounts retrieved successfully
 *                   data:
 *                     - id: "507f1f77bcf86cd799439011"
 *                       type: "ahorro"
 *                       number: "0102****1234"
 *                       bankCode: "0102"
 *                       bankName: "Banco de Venezuela"
 *               listaVacia:
 *                 summary: Lista vacía (sin cuentas)
 *                 value:
 *                   success: true
 *                   message: No accounts found
 *                   data: []
 *       401:
 *         $ref: "#/components/responses/Unauthorized"
 */
routes.get("/", getAccounts);

/**
 * @swagger
 * /accounts/{id}:
 *   get:
 *     operationId: getAccount
 *     tags: [Accounts]
 *     summary: Obtener cuenta por ID
 *     security:
 *       - bearerAuth: []
 *     parameters:
 *       - in: path
 *         name: id
 *         required: true
 *         schema:
 *           type: string
 *     responses:
 *       200:
 *         description: Cuenta obtenida correctamente
 *         content:
 *           application/json:
 *             schema:
 *               type: object
 *               required: [success, message, data]
 *               properties:
 *                 success:
 *                   type: boolean
 *                   example: true
 *                 message:
 *                   type: string
 *                   example: Account retrieved successfully
 *                 data:
 *                   type: object
 *                   properties:
 *                     id:
 *                       type: string
 *                     type:
 *                       type: string
 *                     number:
 *                       type: string
 *                       description: Número enmascarado
 *                     bankCode:
 *                       type: string
 *                     bankName:
 *                       type: string
 *             example:
 *               success: true
 *               message: Account retrieved successfully
 *               data:
 *                 id: "507f1f77bcf86cd799439011"
 *                 type: "ahorro"
 *                 number: "0102****1234"
 *                 bankCode: "0102"
 *                 bankName: "Banco de Venezuela"
 *       400:
 *         description: ID de cuenta faltante
 *         content:
 *           application/json:
 *             schema:
 *               type: object
 *               properties:
 *                 success:
 *                   type: boolean
 *                   example: false
 *                 message:
 *                   type: string
 *                   example: Account id is required
 *                 code:
 *                   type: string
 *                   example: field_missing
 *       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
 *       401:
 *         $ref: "#/components/responses/Unauthorized"
 *   put:
 *     operationId: updateAccount
 *     tags: [Accounts]
 *     summary: Actualizar cuenta
 *     security:
 *       - bearerAuth: []
 *     parameters:
 *       - in: path
 *         name: id
 *         required: true
 *         schema:
 *           type: string
 *     requestBody:
 *       required: true
 *       content:
 *         application/json:
 *           schema:
 *             type: object
 *             required: [type, number, bankCode]
 *             properties:
 *               type:
 *                 type: string
 *                 description: Tipo de cuenta
 *               number:
 *                 type: string
 *                 description: Número de cuenta
 *               bankCode:
 *                 type: string
 *                 description: Código del banco (debe existir)
 *     responses:
 *       200:
 *         description: Cuenta actualizada correctamente
 *         content:
 *           application/json:
 *             schema:
 *               type: object
 *               properties:
 *                 success:
 *                   type: boolean
 *                   example: true
 *                 message:
 *                   type: string
 *                   example: Account updated successfully
 *             example:
 *               success: true
 *               message: Account updated successfully
 *       400:
 *         description: Error de validación
 *         content:
 *           application/json:
 *             schema:
 *               type: object
 *               properties:
 *                 success:
 *                   type: boolean
 *                   example: false
 *                 message:
 *                   type: string
 *                 code:
 *                   type: string
 *             examples:
 *               parameter_missing:
 *                 summary: ID faltante
 *                 value:
 *                   success: false
 *                   message: Account id is required
 *                   code: parameter_missing
 *               field_missing:
 *                 summary: Campos requeridos faltantes
 *                 value:
 *                   success: false
 *                   message: Type, number and bankCode are required
 *                   code: field_missing
 *               invalid_bank_code:
 *                 summary: Código de banco inválido
 *                 value:
 *                   success: false
 *                   message: Bank code not valid
 *                   code: invalid_bank_code
 *       401:
 *         $ref: "#/components/responses/Unauthorized"
 *   delete:
 *     operationId: deleteAccount
 *     tags: [Accounts]
 *     summary: Eliminar cuenta
 *     security:
 *       - bearerAuth: []
 *     parameters:
 *       - in: path
 *         name: id
 *         required: true
 *         schema:
 *           type: string
 *     responses:
 *       200:
 *         description: Cuenta eliminada correctamente
 *         content:
 *           application/json:
 *             schema:
 *               type: object
 *               properties:
 *                 success:
 *                   type: boolean
 *                   example: true
 *                 message:
 *                   type: string
 *                   example: Account deleted successfully
 *             example:
 *               success: true
 *               message: Account deleted successfully
 *       400:
 *         description: ID de cuenta faltante
 *         content:
 *           application/json:
 *             schema:
 *               type: object
 *               properties:
 *                 success:
 *                   type: boolean
 *                   example: false
 *                 message:
 *                   type: string
 *                   example: Account id is required
 *       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
 *       401:
 *         $ref: "#/components/responses/Unauthorized"
 */
routes.route("/:id").get(getAccount).put(updateAccount).delete(deleteAccount);

/**
 * @swagger
 * /accounts/{id}/unmasked:
 *   get:
 *     operationId: getAccountUnmasked
 *     tags: [Accounts]
 *     summary: Obtener cuenta sin enmascarar (número completo)
 *     security:
 *       - bearerAuth: []
 *     parameters:
 *       - in: path
 *         name: id
 *         required: true
 *         schema:
 *           type: string
 *     responses:
 *       200:
 *         description: Cuenta con número completo
 *         content:
 *           application/json:
 *             schema:
 *               type: object
 *               required: [success, message, data]
 *               properties:
 *                 success:
 *                   type: boolean
 *                   example: true
 *                 message:
 *                   type: string
 *                   example: Account retrieved successfully
 *                 data:
 *                   type: object
 *                   properties:
 *                     id:
 *                       type: string
 *                     type:
 *                       type: string
 *                     number:
 *                       type: string
 *                       description: Número completo (sin enmascarar)
 *                     bankCode:
 *                       type: string
 *                     bankName:
 *                       type: string
 *             example:
 *               success: true
 *               message: Account retrieved successfully
 *               data:
 *                 id: "507f1f77bcf86cd799439011"
 *                 type: "ahorro"
 *                 number: "0102123456781234"
 *                 bankCode: "0102"
 *                 bankName: "Banco de Venezuela"
 *       400:
 *         description: ID de cuenta faltante
 *         content:
 *           application/json:
 *             schema:
 *               type: object
 *               properties:
 *                 success:
 *                   type: boolean
 *                   example: false
 *                 message:
 *                   type: string
 *                   example: Account id is required
 *                 code:
 *                   type: string
 *                   example: field_missing
 *       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
 *       401:
 *         $ref: "#/components/responses/Unauthorized"
 */
routes.route("/:id/unmasked").get(getAccountUnmasked);

export default routes;
