/**
 * BinancePayService
 * Handles Binance Pay cryptocurrency payments (USDT, BTC, etc.)
 * Features: Crypto payment links, automated verification
 */

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

class BinancePayService extends PaymentServiceInterface {
  constructor() {
    super();
    this.apiUrl = process.env.BINANCE_API_URL || 'https://bpay.binanceapi.com';
    this.apiKey = process.env.BINANCE_API_KEY;
    this.secretKey = process.env.BINANCE_SECRET_KEY;
  }

  /**
   * Generate signature for Binance Pay API requests
   */
  generateSignature(payload, timestamp, nonce) {
    const signStr = timestamp + '\n' + nonce + '\n' + JSON.stringify(payload) + '\n';
    return crypto
      .createHmac('sha512', this.secretKey)
      .update(signStr)
      .digest('hex')
      .toUpperCase();
  }

  /**
   * Initialize payment - Create order
   */
  async initializePayment(amount, reference, metadata = {}) {
    try {
      const timestamp = Date.now();
      const nonce = crypto.randomBytes(16).toString('hex');

      const payload = {
        env: {
          terminalType: 'WEB'
        },
        merchantTradeNo: reference,
        orderAmount: amount,
        currency: 'NGN',
        goods: {
          goodsType: '01', // Virtual goods
          goodsCategory: 'Z000', // Others
          referenceGoodsId: 'WAKA_DEPOSIT',
          goodsName: 'WakaTraffic Deposit',
          goodsDetail: `Deposit ₦${amount} to WakaTraffic account`
        },
        shipping: {
          shippingName: metadata.customer_name || metadata.username || 'WakaTraffic User',
          shippingEmail: metadata.customer_email || metadata.email || ''
        },
        buyer: {
          buyerName: {
            firstName: metadata.first_name || 'WakaTraffic',
            lastName: metadata.last_name || 'User'
          },
          buyerEmail: metadata.customer_email || metadata.email || ''
        },
        returnUrl: metadata.returnUrl || `${process.env.APP_URL}/deposits/success`,
        cancelUrl: metadata.cancelUrl || `${process.env.APP_URL}/deposits/cancelled`
      };

      const signature = this.generateSignature(payload, timestamp, nonce);

      const response = await axios.post(
        `${this.apiUrl}/binancepay/openapi/v2/order`,
        payload,
        {
          headers: {
            'Content-Type': 'application/json',
            'BinancePay-Timestamp': timestamp,
            'BinancePay-Nonce': nonce,
            'BinancePay-Certificate-SN': this.apiKey,
            'BinancePay-Signature': signature
          }
        }
      );

      if (response.data && response.data.status === 'SUCCESS') {
        const data = response.data.data;

        return {
          success: true,
          data: {
            payment_url: data.checkoutUrl || data.universalUrl,
            qr_code: data.qrcodeLink,
            qr_content: data.qrContent,
            reference: reference,
            prepay_id: data.prepayId,
            expires_at: new Date(data.expireTime).toISOString()
          },
          message: 'Crypto payment link generated successfully'
        };
      }

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

  /**
   * Verify payment
   */
  async verifyPayment(reference) {
    try {
      const timestamp = Date.now();
      const nonce = crypto.randomBytes(16).toString('hex');

      const payload = {
        merchantTradeNo: reference
      };

      const signature = this.generateSignature(payload, timestamp, nonce);

      const response = await axios.post(
        `${this.apiUrl}/binancepay/openapi/v2/order/query`,
        payload,
        {
          headers: {
            'Content-Type': 'application/json',
            'BinancePay-Timestamp': timestamp,
            'BinancePay-Nonce': nonce,
            'BinancePay-Certificate-SN': this.apiKey,
            'BinancePay-Signature': signature
          }
        }
      );

      if (response.data && response.data.status === 'SUCCESS') {
        const data = response.data.data;

        if (data.status === 'PAID') {
          return {
            success: true,
            data: {
              status: 'completed',
              amount: parseFloat(data.orderAmount),
              crypto_amount: parseFloat(data.transactionAmount || 0),
              crypto_currency: data.cryptocurrency,
              reference: reference,
              transaction_id: data.transactionId,
              payment_time: new Date(data.paymentTime).toISOString()
            },
            message: 'Payment completed successfully'
          };
        } else {
          return {
            success: false,
            data: {
              status: data.status?.toLowerCase() || 'pending',
              reference: reference
            },
            message: `Payment status: ${data.status}`
          };
        }
      }

      return {
        success: false,
        message: 'Failed to verify payment'
      };
    } catch (error) {
      console.error('Binance Pay 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 Binance Pay
   */
  async handleWebhook(payload, headers = {}) {
    try {
      if (payload.bizStatus === 'PAY_SUCCESS') {
        return {
          success: true,
          data: {
            reference: payload.merchantTradeNo,
            amount: parseFloat(payload.orderAmount),
            crypto_amount: parseFloat(payload.transactionAmount),
            crypto_currency: payload.cryptocurrency,
            status: 'completed',
            transaction_id: payload.transactionId
          }
        };
      }

      return {
        success: false,
        data: {
          status: payload.bizStatus?.toLowerCase() || 'failed',
          reference: payload.merchantTradeNo
        }
      };
    } catch (error) {
      console.error('Binance Pay webhook error:', error.message);
      return { success: false, message: error.message };
    }
  }

  /**
   * Verify webhook signature
   */
  verifyWebhookSignature(payload, signature) {
    try {
      const timestamp = signature.timestamp;
      const nonce = signature.nonce;

      const data = typeof payload === 'string' ? JSON.parse(payload) : payload;
      const computedSignature = this.generateSignature(data, timestamp, nonce);

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

  /**
   * Get service configuration
   */
  getConfig() {
    return {
      name: 'Crypto (USDT)',
      code: 'binance',
      type: 'crypto',
      isAutomated: true,
      requiresProof: false,
      processingTime: 5 // 5 minutes average for crypto confirmations
    };
  }
}

module.exports = BinancePayService;
