/**
 * MoniepointService
 * Handles Moniepoint virtual account/reserved account payments
 * Features: Reserved account generation, instant verification
 */

const axios = require('axios');
const crypto = require('crypto');
const PaymentServiceInterface = require('./PaymentServiceInterface');

class MoniepointService extends PaymentServiceInterface {
  constructor() {
    super();
    this.apiUrl = process.env.MONIEPOINT_API_URL || 'https://api.moniepoint.com/v1';
    this.apiKey = process.env.MONIEPOINT_API_KEY;
    this.secretKey = process.env.MONIEPOINT_SECRET_KEY;
    this.contractCode = process.env.MONIEPOINT_CONTRACT_CODE;
  }

  /**
   * Initialize payment - Create reserved account
   */
  async initializePayment(amount, reference, metadata = {}) {
    try {
      const returnUrl = metadata.returnUrl || `${process.env.APP_URL}/deposits/success`;

      const response = await axios.post(
        `${this.apiUrl}/merchant/bank-transfer/init`,
        {
          amount: amount,
          customerName: metadata.customer_name || metadata.username || 'WakaTraffic User',
          customerEmail: metadata.customer_email || metadata.email || '',
          paymentReference: reference,
          paymentDescription: 'WakaTraffic Deposit',
          currencyCode: 'NGN',
          contractCode: this.contractCode,
          redirectUrl: returnUrl,
          paymentMethods: ['ACCOUNT_TRANSFER']
        },
        {
          headers: {
            'Authorization': `Bearer ${this.apiKey}`,
            'Content-Type': 'application/json'
          }
        }
      );

      if (response.data && response.data.responseBody) {
        const data = response.data.responseBody;

        return {
          success: true,
          data: {
            account_number: data.accountNumber,
            account_name: data.accountName,
            bank_name: data.bankName,
            bank_code: data.bankCode,
            amount: amount,
            reference: reference,
            expires_at: data.expiresAt
          },
          message: 'Transfer details generated successfully'
        };
      }

      return {
        success: false,
        message: response.data?.responseMessage || 'Failed to initialize payment'
      };
    } catch (error) {
      console.error('Moniepoint init error:', error.message);
      return {
        success: false,
        message: `Initialization failed: ${error.message}`
      };
    }
  }

  /**
   * Verify payment
   */
  async verifyPayment(reference) {
    try {
      const response = await axios.get(
        `${this.apiUrl}/merchant/transactions/query`,
        {
          params: { paymentReference: reference },
          headers: {
            'Authorization': `Bearer ${this.apiKey}`
          }
        }
      );

      if (response.data && response.data.responseBody) {
        const data = response.data.responseBody;

        if (data.paymentStatus === 'PAID') {
          return {
            success: true,
            data: {
              status: 'completed',
              amount: parseFloat(data.amountPaid),
              reference: reference,
              transaction_id: data.transactionReference,
              payment_time: data.paidOn
            },
            message: 'Payment completed successfully'
          };
        } else {
          return {
            success: false,
            data: {
              status: data.paymentStatus?.toLowerCase() || 'pending',
              reference: reference
            },
            message: `Payment status: ${data.paymentStatus}`
          };
        }
      }

      return {
        success: false,
        message: 'Failed to verify payment'
      };
    } catch (error) {
      console.error('Moniepoint verify error:', error.message);
      return {
        success: false,
        message: `Verification failed: ${error.message}`
      };
    }
  }

  /**
   * Get payment status
   */
  async getPaymentStatus(reference) {
    const verification = await this.verifyPayment(reference);

    if (verification.success) {
      return 'completed';
    } else if (verification.data && verification.data.status) {
      return verification.data.status;
    }

    return 'pending';
  }

  /**
   * Handle webhook from Moniepoint
   */
  async handleWebhook(payload, headers = {}) {
    try {
      if (payload.eventType === 'SUCCESSFUL_TRANSACTION') {
        return {
          success: true,
          data: {
            reference: payload.eventData.paymentReference,
            amount: parseFloat(payload.eventData.amountPaid),
            status: 'completed',
            transaction_id: payload.eventData.transactionReference
          }
        };
      }

      return {
        success: false,
        message: 'Unhandled webhook event type'
      };
    } catch (error) {
      console.error('Moniepoint webhook error:', error.message);
      return { success: false, message: error.message };
    }
  }

  /**
   * Verify webhook signature
   */
  verifyWebhookSignature(payload, signature) {
    try {
      const computedSignature = crypto
        .createHmac('sha512', this.secretKey)
        .update(payload)
        .digest('hex');

      return crypto.timingSafeEqual(
        Buffer.from(computedSignature),
        Buffer.from(signature)
      );
    } catch (error) {
      console.error('Moniepoint signature verification error:', error.message);
      return false;
    }
  }

  /**
   * Get service configuration
   */
  getConfig() {
    return {
      name: 'Moniepoint',
      code: 'moniepoint',
      type: 'virtual_account',
      isAutomated: true,
      requiresProof: false,
      processingTime: 0 // Instant
    };
  }
}

module.exports = MoniepointService;
