const Bank = require("../models/Bank");
const bdvService = require("./bdvService");
const banco100Service = require("./banco100Service");
const Transaction = require("../models/Transaction");
class BankService {
  static async processPayment(bankCode, paymentData) {
    const bank = await Bank.findByCode(bankCode);
    if (!bank) {
      throw new Error(`Banco no soportado: ${bankCode}`);
    }

    // Verificar si existe una transacción fallida reciente para reintentar
    const failedTransaction = await Transaction.findFailedTransactions(
      bank.id,
      paymentData.reference,
      24 // horas
    );

    if (failedTransaction) {
      console.log("🔄 Encontrada transacción fallida previa, reintentando...", {
        transactionId: failedTransaction.id,
        reference: paymentData.reference,
      });

      // Incrementar contador de reintentos
      await Transaction.incrementRetryCount(failedTransaction.id);
    }

    switch (bankCode) {
      case "0102": // Banco de Venezuela
        return await bdvService.processPaymentMovil(paymentData);
      // Agregar más casos para otros bancos
      case "0156": // 100% Banco
        return await banco100Service.validateTransaction(paymentData);
      default:
        throw new Error(`Servicio no implementado para el banco: ${bankCode}`);
    }
  }

  // Método específico para reintentos manuales
  static async retryPayment(transactionId) {
    try {
      const transaction = await Transaction.findById(transactionId);
      if (!transaction) {
        throw new Error("Transacción no encontrada");
      }

      if (transaction.status !== "failed") {
        throw new Error("Solo se pueden reintentar transacciones fallidas");
      }

      if (transaction.retry_count >= 3) {
        throw new Error("Límite de reintentos alcanzado");
      }

      // Reconstruir paymentData desde raw_request_data
      const paymentData = JSON.parse(transaction.raw_request_data);
      paymentData.reference = transaction.reference; // Mantener misma referencia

      // Incrementar contador de reintentos
      await Transaction.incrementRetryCount(transactionId);

      const bank = await Bank.findByCode(transaction.bank_code);
      let result;

      switch (transaction.bank_code) {
        case "0102":
          result = await bdvService.processPaymentMovil(paymentData);
          break;
        case "0156":
          result = await banco100Service.validateTransaction(paymentData);
          break;
        default:
          throw new Error("Banco no soportado");
      }

      return {
        ...result,
        isRetry: true,
        originalTransactionId: transactionId,
        retryCount: transaction.retry_count + 1,
      };
    } catch (error) {
      console.error("Error en retryPayment:", error);
      throw error;
    }
  }

  static async consultMovements(bankCode, consultData) {
    const bank = await Bank.findByCode(bankCode);
    if (!bank) {
      throw new Error(`Banco no soportado: ${bankCode}`);
    }

    switch (bankCode) {
      case "0102": // Banco de Venezuela
        return await bdvService.consultMovements(consultData);
      // Agregar más casos para otros bancos
      default:
        throw new Error(`Servicio no implementado para el banco: ${bankCode}`);
    }
  }

  // Nuevo método específico para 100% Banco
  static async validateTransaction100(bankCode, transactionData) {
    if (bankCode !== "0156") {
      throw new Error("Este método es exclusivo para 100% Banco");
    }
    return await banco100Service.validateTransaction(transactionData);
  }
}

module.exports = BankService;
