const axios = require("axios");
const Bank = require("../models/Bank");
const Transaction = require("../models/Transaction");

class BDVService {
  static async getConfig() {
    const bank = await Bank.findByCode("0102");
    const config = await Bank.getConfig(bank.id);
    if (!config || !config.api_key) {
      throw new Error("Configuración no encontrada para Banco de Venezuela");
    }

    return config;
  }

  static getBaseUrl() {
    return process.env.MOCK_MODE === "true"
      ? "http://localhost:3001"
      : "https://bdvconciliacionqa.banvenez.com:444";
  }

  static async processPaymentMovil(paymentData) {
    try {
      const config = await this.getConfig();

      // Validar datos de entrada
      this.validatePaymentData(paymentData);

      // PRIMERO: Verificar si ya existe una transacción con esta referencia
      const bank = await Bank.findByCode("0102");
      const existingCheck = await Transaction.checkExistingTransaction(
        paymentData.reference,
        bank.id
      );

      // Si ya existe y está completada, retornar inmediatamente
      if (existingCheck.exists && existingCheck.status === "completed") {
        console.log("✅ Transacción ya completada anteriormente:", {
          reference: paymentData.reference,
          transactionId: existingCheck.id,
          amount: existingCheck.amount,
        });

        return {
          success: true,
          alreadyProcessed: true,
          data: {
            code: 2000,
            message: "Este pago ya fue procesado exitosamente anteriormente",
            data: {
              status: "2000",
              amount: existingCheck.amount,
              reason: "Pago ya verificado y completado",
            },
            status: 200,
          },
          transactionId: existingCheck.id,
          message: "Este pago ya fue procesado y verificado anteriormente",
        };
      }

      // Si existe pero está fallida, permitir reintento
      if (existingCheck.exists && existingCheck.status === "failed") {
        console.log("🔄 Reintentando transacción fallida:", {
          reference: paymentData.reference,
          previousError: existingCheck.responseMessage,
        });
      }

      const requestPayload = {
        cedulaPagador: paymentData.payer_identification,
        telefonoPagador: paymentData.payer_phone,
        telefonoDestino: paymentData.beneficiary_phone,
        referencia: paymentData.reference,
        fechaPago: paymentData.payment_date,
        importe: paymentData.amount.toString(),
        bancoOrigen: paymentData.bank_origin,
        reqCed: paymentData.validate_identification || false,
      };

      console.log("📤 Enviando pago a BDV:", {
        reference: paymentData.reference,
        amount: paymentData.amount,
        bank: paymentData.bank_origin,
        isRetry: existingCheck.exists,
      });

      const transactionData = {
        reference: paymentData.reference,
        bank_id: bank.id,
        transaction_type: "pago_movil",
        amount: paymentData.amount,
        currency: "VES",
        payer_identification: paymentData.payer_identification || null,
        payer_phone: paymentData.payer_phone || null,
        beneficiary_phone: paymentData.beneficiary_phone || null,
        beneficiary_identification:
          paymentData.beneficiary_identification || null,
        bank_origin: paymentData.bank_origin || null,
        payment_date: paymentData.payment_date || null,
        raw_request_data: requestPayload,
        bank_transaction_id: `BDV_${paymentData.reference}_${Date.now()}`,
        status: existingCheck.exists ? "retrying" : "pending",
      };

      // Validar datos antes de crear la transacción
      await Transaction.validateTransactionData(transactionData);

      // Crear o obtener transacción
      const createResult = await Transaction.create(transactionData);
      const transactionId = createResult.transactionId;

      console.log("📝 Estado de transacción:", {
        transactionId,
        existing: createResult.existing,
        status: createResult.status,
      });

      // Si la transacción ya existía y estaba completada, no llamar al banco
      if (createResult.existing && createResult.status === "completed") {
        return {
          success: true,
          alreadyProcessed: true,
          data: {
            code: 2000,
            message: "Este pago ya fue verificado y procesado anteriormente",
            data: {
              status: "2000",
              amount: paymentData.amount,
              reason: "Pago ya completado",
            },
            status: 200,
          },
          transactionId,
          message: "Este pago ya fue procesado exitosamente anteriormente",
        };
      }

      // USAR MOCK EN DESARROLLO
      const baseUrl = this.getBaseUrl();

      const response = await axios.post(
        `${baseUrl}/getMovement/v2`,
        requestPayload,
        {
          headers: {
            "X-API-Key": config.api_key,
            "Content-Type": "application/json",
          },
          timeout: 30000,
        }
      );

      console.log("📥 Respuesta de BDV:", {
        reference: paymentData.reference,
        code: response.data.code,
        success: response.data.code === 1000,
      });

      // Actualizar transacción con respuesta
      await Transaction.updateStatus(
        paymentData.reference,
        response.data.code === 1000 ? "completed" : "failed",
        response.data
      );

      return {
        success: response.data.code === 1000,
        alreadyProcessed: false, // NUEVO: Indica que es un pago nuevo
        data: response.data,
        transactionId,
        isRetry: existingCheck.exists,
        message:
          response.data.code === 1000
            ? "Pago procesado exitosamente"
            : "Error procesando el pago",
      };
    } catch (error) {
      console.error("❌ Error en BDV Service:", error.message);

      // Registrar error en la transacción
      if (paymentData.reference) {
        try {
          await Transaction.updateStatus(paymentData.reference, "failed", {
            code: "ERROR",
            message: error.message,
          });
        } catch (updateError) {
          console.error(
            "Error actualizando estado:",
            updateError.message
          );
        }
      }

      throw error;
    }
  }

  static validatePaymentData(paymentData) {
    const required = [
      "bank_code",
      "payer_identification",
      "payer_phone",
      "beneficiary_phone",
      "reference",
      "payment_date",
      "amount",
      "bank_origin",
    ];

    const missing = required.filter((field) => !paymentData[field]);

    if (missing.length > 0) {
      throw new Error(
        `Datos de pago incompletos. Faltan: ${missing.join(", ")}`
      );
    }

    if (typeof paymentData.amount !== "number" || paymentData.amount <= 0) {
      throw new Error("El monto debe ser un número positivo");
    }

    if (!paymentData.reference || paymentData.reference.length < 5) {
      throw new Error("La referencia debe tener al menos 5 caracteres");
    }
  }

  static async consultMovements(consultData) {
    try {
      const config = await this.getConfig();

      const requestPayload = {
        cuenta: consultData.account,
        fechaIni: consultData.start_date,
        fechaFin: consultData.end_date,
        tipoMoneda: consultData.currency || "VES",
        nroMovimiento: consultData.movement_number || "",
      };

      const baseUrl = this.getBaseUrl();

      console.log("📊 Consultando movimientos BDV:", {
        account: consultData.account,
        dates: `${consultData.start_date} - ${consultData.end_date}`,
      });

      const response = await axios.post(
        `${baseUrl}/apis/bdv/consulta/movimientos/v2`,
        requestPayload,
        {
          headers: {
            "X-API-Key": config.api_key,
            "Content-Type": "application/json",
          },
          timeout: 30000,
        }
      );

      return {
        success: response.data.code === "1000",
        data: response.data,
      };
    } catch (error) {
      console.error("❌ Error consultando movimientos BDV:", error.message);
      throw error;
    }
  }
}

module.exports = BDVService;
