/**
 * CryptomusService.js
 * Cryptomus Cryptocurrency Payment Gateway Integration for WakaTraffic
 * Supports: USDT, BTC, ETH, USDC, BNB, and 100+ cryptocurrencies
 */

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

class CryptomusService extends PaymentServiceInterface {
    constructor() {
        super(); // Call parent constructor

        this.merchantId = process.env.CRYPTOMUS_MERCHANT_ID;
        this.apiKey = process.env.CRYPTOMUS_API_KEY;
        this.paymentApiKey = process.env.CRYPTOMUS_PAYMENT_API_KEY;
        this.baseUrl = process.env.CRYPTOMUS_BASE_URL || 'https://api.cryptomus.com/v1';
        this.exchangeRate = parseFloat(process.env.CRYPTOMUS_EXCHANGE_RATE_NGN_USD) || 1600;
    }

    /**
     * Convert NGN to USD
     * @param {number} amountNGN - Amount in Nigerian Naira
     * @returns {number} Amount in USD
     */
    convertNGNtoUSD(amountNGN) {
        return parseFloat((amountNGN / this.exchangeRate).toFixed(2));
    }

    /**
     * Generate API signature for Cryptomus
     * @param {object} data - Request payload
     * @returns {string} MD5 signature
     */
    generateSignature(data) {
        const jsonString = JSON.stringify(data);
        const base64Data = Buffer.from(jsonString).toString('base64');
        const signature = crypto
            .createHash('md5')
            .update(base64Data + this.paymentApiKey)
            .digest('hex');

        return signature;
    }

    /**
     * Initialize cryptocurrency payment
     * @param {number} amountNGN - Amount in Nigerian Naira
     * @param {string} reference - Unique payment reference
     * @param {object} metadata - Customer info and additional data
     * @returns {Promise<object>} Payment initialization result
     */
    async initializePayment(amountNGN, reference, metadata = {}) {
        try {
            // Check if basic credentials exist
            if (!this.merchantId || !this.apiKey || !this.paymentApiKey) {
                console.warn('[Cryptomus] API credentials missing');
                return {
                    success: false,
                    message: 'Cryptomus payment gateway credentials are missing. Please configure CRYPTOMUS_MERCHANT_ID, CRYPTOMUS_API_KEY, and CRYPTOMUS_PAYMENT_API_KEY in environment variables.'
                };
            }

            // Warn about placeholder values but still attempt the call
            if (this.merchantId.includes('GET_FROM') || this.merchantId.includes('DASHBOARD')) {
                console.warn('[Cryptomus] Using placeholder merchant ID - API call will likely fail with 401');
            }

            console.log('[Cryptomus] Initializing payment:', {
                amountNGN,
                reference,
                merchantId: this.merchantId
            });

            // Convert NGN to USD
            const amountUSD = this.convertNGNtoUSD(amountNGN);

            const payload = {
                amount: amountUSD.toString(),
                currency: 'USD',
                order_id: reference,
                url_callback: `${process.env.APP_URL}/api/webhooks/cryptomus`,
                url_return: `${process.env.APP_URL}/deposits/success`,
                url_success: `${process.env.APP_URL}/deposits/success`,
                is_payment_multiple: false,
                lifetime: 3600, // 1 hour
                to_currency: metadata.crypto_currency || 'USDT', // Default to USDT
                subtract: 100, // Merchant pays fees
                accuracy_payment_percent: 5, // 5% payment tolerance
                additional_data: JSON.stringify({
                    user_id: metadata.user_id || null,
                    platform: 'WakaTraffic',
                    amount_ngn: amountNGN,
                    exchange_rate: this.exchangeRate,
                    timestamp: new Date().toISOString()
                })
            };

            const signature = this.generateSignature(payload);

            console.log('[Cryptomus] Request payload prepared:', {
                amountUSD,
                amountNGN,
                currency: payload.to_currency
            });

            const response = await axios.post(
                `${this.baseUrl}/payment`,
                payload,
                {
                    headers: {
                        'merchant': this.merchantId,
                        'sign': signature,
                        'Content-Type': 'application/json'
                    },
                    timeout: 30000
                }
            );

            if (response.data.state === 0 && response.data.result) {
                const result = response.data.result;

                console.log('[Cryptomus] Payment initialized successfully:', reference);

                return {
                    success: true,
                    data: {
                        payment_url: result.url,
                        reference,
                        payment_id: result.uuid,
                        amount_usd: amountUSD,
                        amount_ngn: amountNGN,
                        crypto_currency: payload.to_currency,
                        expires_at: new Date(Date.now() + 3600000) // 1 hour
                    },
                    message: 'Cryptocurrency payment initialized successfully'
                };
            }

            throw new Error(response.data.message || 'Failed to initialize crypto payment');

        } catch (error) {
            console.error('[Cryptomus] Initialize error:', error.message);
            console.error('[Cryptomus] Error details:', {
                status: error.response?.status,
                statusText: error.response?.statusText,
                data: error.response?.data,
                headers: error.response?.headers
            });

            // Provide more helpful error messages
            let errorMessage = error.message || 'Crypto payment initialization failed';

            if (error.response?.status === 401) {
                const apiError = error.response?.data?.message || error.response?.data?.error || 'Unauthorized';
                errorMessage = `Cryptomus API Error (401): ${apiError}. Please verify your Merchant ID and API keys are correct and match your Cryptomus account.`;
            } else if (error.response?.data?.message) {
                errorMessage = `Cryptomus API Error: ${error.response.data.message}`;
            } else if (error.code === 'ENOTFOUND') {
                errorMessage = 'Cannot reach Cryptomus API. Please check your internet connection.';
            }

            return {
                success: false,
                message: errorMessage
            };
        }
    }

    /**
     * Verify cryptocurrency payment status
     * @param {string} reference - Payment reference (order_id)
     * @returns {Promise<object>} Verification result
     */
    async verifyPayment(reference) {
        try {
            console.log('[Cryptomus] Verifying payment:', reference);

            const payload = {
                order_id: reference
            };

            const signature = this.generateSignature(payload);

            const response = await axios.post(
                `${this.baseUrl}/payment/info`,
                payload,
                {
                    headers: {
                        'merchant': this.merchantId,
                        'sign': signature,
                        'Content-Type': 'application/json'
                    },
                    timeout: 30000
                }
            );

            if (response.data.state === 0 && response.data.result) {
                const transaction = response.data.result;

                // Cryptomus payment statuses
                const statusMap = {
                    'paid': 'completed',
                    'paid_over': 'completed',
                    'confirm_check': 'pending',
                    'check': 'pending',
                    'process': 'pending',
                    'fail': 'failed',
                    'wrong_amount': 'failed',
                    'cancel': 'failed',
                    'system_fail': 'failed',
                    'refund_process': 'failed',
                    'refund_fail': 'failed',
                    'refund_paid': 'failed'
                };

                const mappedStatus = statusMap[transaction.status] || 'pending';

                if (mappedStatus === 'completed') {
                    console.log('[Cryptomus] Payment verified as successful:', reference);

                    // Parse additional data to get original NGN amount
                    let amountNGN = null;
                    try {
                        const additionalData = JSON.parse(transaction.additional_data || '{}');
                        amountNGN = additionalData.amount_ngn || null;
                    } catch (e) {
                        console.warn('[Cryptomus] Could not parse additional_data');
                    }

                    return {
                        success: true,
                        data: {
                            status: 'completed',
                            amount: amountNGN || parseFloat(transaction.amount) * this.exchangeRate, // Fallback to conversion
                            amount_usd: parseFloat(transaction.amount),
                            currency: 'NGN',
                            crypto_currency: transaction.currency,
                            crypto_amount: parseFloat(transaction.payer_amount || transaction.amount),
                            reference,
                            transaction_id: transaction.uuid,
                            payment_method: `Crypto (${transaction.currency})`,
                            paid_at: transaction.created_at || new Date().toISOString(),
                            network: transaction.network || null,
                            txid: transaction.txid || null
                        },
                        message: 'Cryptocurrency payment verified successfully'
                    };
                } else if (mappedStatus === 'pending') {
                    return {
                        success: false,
                        message: 'Payment is still pending confirmation',
                        data: {
                            status: 'pending',
                            crypto_status: transaction.status
                        }
                    };
                } else if (mappedStatus === 'failed') {
                    return {
                        success: false,
                        message: `Payment ${transaction.status.replace('_', ' ')}`,
                        data: {
                            status: 'failed',
                            crypto_status: transaction.status
                        }
                    };
                }
            }

            return {
                success: false,
                message: 'Payment not found or not completed'
            };

        } catch (error) {
            console.error('[Cryptomus] Verify error:', error.message);

            return {
                success: false,
                message: error.response?.data?.message || error.message || 'Payment verification failed'
            };
        }
    }

    /**
     * Handle webhook notification from Cryptomus
     * @param {object} payload - Webhook payload
     * @param {string} signature - Signature from header
     * @returns {object} Processing result
     */
    handleWebhook(payload, signature) {
        try {
            console.log('[Cryptomus] Webhook received:', payload.status);

            // Verify signature
            const expectedSignature = this.generateSignature(payload);

            if (signature !== expectedSignature) {
                console.warn('[Cryptomus] Invalid webhook signature');
                return { success: false, message: 'Invalid signature' };
            }

            // Process paid status
            if (payload.status === 'paid' || payload.status === 'paid_over') {
                console.log('[Cryptomus] Processing successful payment:', payload.order_id);

                // Parse additional data for original NGN amount
                let amountNGN = null;
                try {
                    const additionalData = JSON.parse(payload.additional_data || '{}');
                    amountNGN = additionalData.amount_ngn || null;
                } catch (e) {
                    console.warn('[Cryptomus] Could not parse additional_data');
                }

                return {
                    success: true,
                    data: {
                        reference: payload.order_id,
                        amount: amountNGN || parseFloat(payload.amount) * this.exchangeRate,
                        amount_usd: parseFloat(payload.amount),
                        currency: 'NGN',
                        crypto_currency: payload.currency,
                        crypto_amount: parseFloat(payload.payer_amount || payload.amount),
                        status: 'completed',
                        transaction_id: payload.uuid,
                        payment_method: `Crypto (${payload.currency})`,
                        paid_at: payload.created_at || new Date().toISOString(),
                        network: payload.network || null,
                        txid: payload.txid || null
                    }
                };
            }

            console.log('[Cryptomus] Unhandled webhook status:', payload.status);
            return { success: false, message: 'Unhandled payment status' };

        } catch (error) {
            console.error('[Cryptomus] Webhook error:', error.message);
            return { success: false, message: error.message };
        }
    }

    /**
     * Get list of supported cryptocurrencies
     * @returns {Promise<Array>} List of supported currencies
     */
    async getSupportedCurrencies() {
        try {
            const response = await axios.get(
                `${this.baseUrl}/payment/services`,
                {
                    headers: {
                        'merchant': this.merchantId,
                        'Content-Type': 'application/json'
                    },
                    timeout: 10000
                }
            );

            if (response.data.state === 0 && response.data.result) {
                return {
                    success: true,
                    data: response.data.result
                };
            }

            return { success: false, message: 'Could not fetch currencies' };

        } catch (error) {
            console.error('[Cryptomus] Error fetching currencies:', error.message);
            return {
                success: false,
                message: error.message
            };
        }
    }

    /**
     * Get payment status (simplified version of verifyPayment)
     * @param {string} reference - Payment reference
     * @returns {Promise<string>} Status: 'pending', 'processing', 'completed', 'failed'
     */
    async getPaymentStatus(reference) {
        const result = await this.verifyPayment(reference);

        if (result.success && result.data) {
            return result.data.status; // 'completed', 'pending', 'failed'
        }

        return 'failed';
    }

    /**
     * Get service configuration
     * @returns {object} Service configuration
     */
    getConfig() {
        return {
            name: 'Cryptomus',
            code: 'cryptomus',
            type: 'crypto',
            isAutomated: true,
            requiresProof: false,
            isHidden: false,
            supports: ['USDT', 'BTC', 'ETH', 'USDC', 'BNB', 'TRX', 'LTC', 'DOGE', 'XRP', '100+ coins'],
            currency: 'USD',
            baseCurrency: 'NGN',
            exchangeRate: this.exchangeRate,
            processingTime: '2-10 minutes',
            merchantId: this.merchantId ? 'Configured' : 'Not configured'
        };
    }
}

module.exports = CryptomusService;
