/**
 * MonoVerificationService
 * Handles automated bank transfer verification using Mono API
 * Features: Real-time transaction monitoring, automated verification
 * Note: This is a background service, not directly user-facing
 */

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

class MonoVerificationService extends PaymentServiceInterface {
  constructor(pool) {
    super();
    this.pool = pool; // Database connection pool
    this.apiUrl = process.env.MONO_API_URL || 'https://api.withmono.com/v1';
    this.secretKey = process.env.MONO_SECRET_KEY;
    this.accountId = process.env.MONO_ACCOUNT_ID; // Your connected business account
  }

  /**
   * Initialize - Not applicable (background service)
   */
  async initializePayment(amount, reference, metadata = {}) {
    return {
      success: false,
      message: 'Mono is a verification service only, not a payment method'
    };
  }

  /**
   * Verify payment using Mono transaction lookup
   */
  async verifyPayment(reference) {
    try {
      // Check recent transactions for matching amount and reference
      const transactions = await this.getRecentTransactions();

      if (!transactions || !transactions.data) {
        return {
          success: false,
          message: 'Failed to fetch transactions from Mono'
        };
      }

      // Find matching transaction
      const match = transactions.data.find(tx => {
        return (
          tx.narration?.includes(reference) ||
          tx.reference?.includes(reference)
        );
      });

      if (match) {
        return {
          success: true,
          data: {
            status: 'completed',
            amount: parseFloat(match.amount),
            reference: reference,
            transaction_id: match._id,
            payment_account: match.meta?.sender_name || 'Unknown',
            verified_at: match.date
          },
          message: 'Payment verified successfully'
        };
      }

      return {
        success: false,
        message: 'Transaction not found in recent transfers'
      };
    } catch (error) {
      console.error('Mono verify error:', error.message);
      return {
        success: false,
        message: `Verification failed: ${error.message}`
      };
    }
  }

  /**
   * Get recent transactions from connected account
   */
  async getRecentTransactions(limit = 50) {
    try {
      const response = await axios.get(
        `${this.apiUrl}/accounts/${this.accountId}/transactions`,
        {
          params: {
            type: 'credit', // Only incoming transfers
            limit: limit
          },
          headers: {
            'Authorization': `Bearer ${this.secretKey}`,
            'mono-sec-key': this.secretKey
          }
        }
      );

      if (response.data) {
        return response.data;
      }

      return null;
    } catch (error) {
      console.error('Mono transactions error:', error.message);
      return null;
    }
  }

  /**
   * Auto-verify pending deposits (cron job)
   */
  async autoVerifyPendingDeposits() {
    try {
      if (!this.pool) {
        throw new Error('Database connection not available');
      }

      // Get pending/processing deposits from last 24 hours
      const [deposits] = await this.pool.execute(
        `SELECT id, reference, amount, user_id
         FROM deposits
         WHERE status IN ('pending', 'processing', 'verifying')
         AND payment_method_id IN (
           SELECT id FROM payment_methods WHERE code IN ('bank_transfer', 'ussd')
         )
         AND created_at >= DATE_SUB(NOW(), INTERVAL 24 HOUR)
         ORDER BY created_at DESC
         LIMIT 100`
      );

      if (deposits.length === 0) {
        return {
          success: true,
          verified: 0,
          message: 'No pending deposits to verify'
        };
      }

      // Get recent transactions from Mono
      const transactions = await this.getRecentTransactions(100);

      if (!transactions || !transactions.data) {
        return {
          success: false,
          message: 'Failed to fetch transactions from Mono'
        };
      }

      let verifiedCount = 0;

      // Match deposits with transactions
      for (const deposit of deposits) {
        const match = transactions.data.find(tx => {
          const amountMatch = Math.abs(parseFloat(tx.amount) - parseFloat(deposit.amount)) < 1; // ₦1 tolerance
          const referenceMatch = tx.narration?.includes(deposit.reference) ||
                                 tx.reference?.includes(deposit.reference);
          return amountMatch && referenceMatch;
        });

        if (match) {
          // Update deposit as completed
          await this.pool.execute(
            `UPDATE deposits
             SET status = 'completed',
                 transaction_id = ?,
                 payment_account = ?,
                 verified_at = NOW(),
                 completed_at = NOW(),
                 payment_details = ?
             WHERE id = ?`,
            [
              match._id,
              match.meta?.sender_name || 'Unknown',
              JSON.stringify({
                mono_transaction_id: match._id,
                sender_bank: match.meta?.sender_bank,
                sender_account: match.meta?.sender_account,
                date: match.date
              }),
              deposit.id
            ]
          );

          // TODO: Credit user wallet
          verifiedCount++;

          console.log(`✅ Auto-verified deposit ${deposit.reference} via Mono`);
        }
      }

      return {
        success: true,
        verified: verifiedCount,
        message: `Auto-verified ${verifiedCount} out of ${deposits.length} pending deposits`
      };
    } catch (error) {
      console.error('Auto-verify error:', error.message);
      return {
        success: false,
        message: `Auto-verification failed: ${error.message}`
      };
    }
  }

  /**
   * Get payment status
   */
  async getPaymentStatus(reference) {
    const verification = await this.verifyPayment(reference);
    return verification.success ? 'completed' : 'pending';
  }

  /**
   * Handle webhook from Mono
   */
  async handleWebhook(payload, headers = {}) {
    try {
      // Mono webhook for new transactions
      if (payload.event === 'mono.events.account_credit') {
        const transaction = payload.data;

        // Find matching pending deposit
        if (!this.pool) {
          return { success: false, message: 'Database not available' };
        }

        const [deposits] = await this.pool.execute(
          `SELECT id, reference, amount, user_id
           FROM deposits
           WHERE status IN ('pending', 'processing', 'verifying')
           AND (
             ? LIKE CONCAT('%', reference, '%') OR
             reference LIKE CONCAT('%', ?, '%')
           )
           AND ABS(amount - ?) < 1
           LIMIT 1`,
          [
            transaction.narration || '',
            transaction.reference || '',
            parseFloat(transaction.amount)
          ]
        );

        if (deposits.length > 0) {
          const deposit = deposits[0];

          // Update as completed
          await this.pool.execute(
            `UPDATE deposits
             SET status = 'completed',
                 transaction_id = ?,
                 payment_account = ?,
                 verified_at = NOW(),
                 completed_at = NOW()
             WHERE id = ?`,
            [
              transaction._id,
              transaction.meta?.sender_name || 'Unknown',
              deposit.id
            ]
          );

          // TODO: Credit user wallet

          return {
            success: true,
            data: {
              deposit_id: deposit.id,
              reference: deposit.reference,
              amount: deposit.amount
            },
            message: 'Deposit auto-verified via webhook'
          };
        }

        return {
          success: false,
          message: 'No matching deposit found for this transaction'
        };
      }

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

  /**
   * Verify webhook signature
   */
  verifyWebhookSignature(payload, signature) {
    const crypto = require('crypto');

    try {
      const computedSignature = crypto
        .createHmac('sha256', this.secretKey)
        .update(payload)
        .digest('hex');

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

  /**
   * Get service configuration
   */
  getConfig() {
    return {
      name: 'Mono Verification',
      code: 'mono',
      type: 'api',
      isAutomated: true,
      requiresProof: false,
      processingTime: 0, // Instant
      isHidden: true // Not shown to users
    };
  }
}

module.exports = MonoVerificationService;
