/**
 * KorapayService.js
 * Korapay Payment Gateway Integration for WakaTraffic
 * Supports: Bank Transfer, Cards, Mobile Money
 */

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

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

        this.mode = process.env.KORAPAY_MODE || 'test';

        if (this.mode === 'live') {
            this.publicKey = process.env.KORAPAY_PUBLIC_KEY_LIVE;
            this.secretKey = process.env.KORAPAY_SECRET_KEY_LIVE;
            this.baseUrl = process.env.KORAPAY_BASE_URL_LIVE;
        } else {
            this.publicKey = process.env.KORAPAY_PUBLIC_KEY_TEST;
            this.secretKey = process.env.KORAPAY_SECRET_KEY_TEST;
            this.baseUrl = process.env.KORAPAY_BASE_URL_TEST;
        }

        this.webhookSecret = process.env.KORAPAY_WEBHOOK_SECRET;
    }

    /**
     * Initialize payment with Korapay
     * @param {number} amount - Amount in NGN
     * @param {string} reference - Unique payment reference
     * @param {object} metadata - Customer info and additional data
     * @returns {Promise<object>} Payment initialization result
     */
    async initializePayment(amount, reference, metadata = {}) {
        try {
            // Check if credentials are configured (not undefined and not placeholder values)
            const isConfigured = this.secretKey &&
                                this.baseUrl &&
                                !this.secretKey.includes('GET_FROM') &&
                                !this.secretKey.includes('DASHBOARD');

            if (!isConfigured) {
                console.warn('[Korapay] API credentials not configured properly');
                return {
                    success: false,
                    message: 'Korapay payment gateway is not configured. Please use Bank Transfer or USSD Payment instead.'
                };
            }

            console.log('[Korapay] Initializing payment:', {
                amount,
                reference,
                mode: this.mode
            });

            const payload = {
                amount,
                currency: 'NGN',
                reference,
                customer: {
                    name: metadata.customer_name || 'WakaTraffic User',
                    email: metadata.customer_email || 'user@wakatraffic.ng',
                },
                notification_url: `${process.env.APP_URL}/api/webhooks/korapay`,
                redirect_url: `${process.env.APP_URL}/deposits/success`,
                channels: ['bank_transfer', 'card', 'mobile_money'],
                metadata: {
                    user_id: metadata.user_id || null,
                    platform: 'WakaTraffic',
                    timestamp: new Date().toISOString(),
                }
            };

            const response = await axios.post(
                `${this.baseUrl}/charges/initialize`,
                payload,
                {
                    headers: {
                        'Authorization': `Bearer ${this.secretKey}`,
                        'Content-Type': 'application/json',
                    },
                    timeout: 30000
                }
            );

            if (response.data.status === true) {
                console.log('[Korapay] Payment initialized successfully:', reference);

                return {
                    success: true,
                    data: {
                        payment_url: response.data.data.checkout_url,
                        reference,
                        access_code: response.data.data.reference || null,
                        expires_at: new Date(Date.now() + 3600000) // 1 hour
                    },
                    message: 'Payment initialized successfully'
                };
            }

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

        } catch (error) {
            console.error('[Korapay] Initialize error:', error.message);
            console.error('[Korapay] Error details:', {
                status: error.response?.status,
                statusText: error.response?.statusText,
                data: error.response?.data,
                config: {
                    url: error.config?.url,
                    method: error.config?.method,
                    data: error.config?.data
                }
            });

            let errorMessage = 'Payment initialization failed';

            if (error.response?.data?.message) {
                errorMessage = `Korapay API Error: ${error.response.data.message}`;
            } else if (error.response?.data?.error) {
                errorMessage = `Korapay API Error: ${error.response.data.error}`;
            } else if (error.message) {
                errorMessage = error.message;
            }

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

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

            const response = await axios.get(
                `${this.baseUrl}/charges/${reference}`,
                {
                    headers: {
                        'Authorization': `Bearer ${this.secretKey}`,
                    },
                    timeout: 30000
                }
            );

            if (response.data.status === true) {
                const transaction = response.data.data;

                if (transaction.status === 'success') {
                    console.log('[Korapay] Payment verified as successful:', reference);

                    return {
                        success: true,
                        data: {
                            status: 'completed',
                            amount: parseFloat(transaction.amount),
                            currency: transaction.currency,
                            reference,
                            transaction_id: transaction.reference,
                            payment_method: transaction.channel || 'unknown',
                            paid_at: transaction.paid_at || new Date().toISOString(),
                        },
                        message: 'Payment verified successfully'
                    };
                } else if (transaction.status === 'pending') {
                    return {
                        success: false,
                        message: 'Payment is still pending',
                        data: { status: 'pending' }
                    };
                } else if (transaction.status === 'failed') {
                    return {
                        success: false,
                        message: 'Payment failed',
                        data: { status: 'failed' }
                    };
                }
            }

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

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

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

    /**
     * Handle webhook notification from Korapay
     * @param {object} payload - Webhook payload
     * @returns {object} Processing result
     */
    handleWebhook(payload) {
        try {
            console.log('[Korapay] Webhook received:', payload.event);

            // Korapay sends 'charge.success' event on successful payment
            if (payload.event === 'charge.success') {
                const data = payload.data;

                console.log('[Korapay] Processing successful charge:', data.reference);

                return {
                    success: true,
                    data: {
                        reference: data.reference,
                        amount: parseFloat(data.amount),
                        currency: data.currency,
                        status: 'completed',
                        transaction_id: data.reference,
                        payment_method: data.channel || 'unknown',
                        paid_at: data.paid_at || new Date().toISOString(),
                    }
                };
            }

            console.log('[Korapay] Unhandled webhook event:', payload.event);

            return { success: false, message: 'Unhandled event type' };

        } catch (error) {
            console.error('[Korapay] Webhook error:', error.message);

            return { success: false, message: error.message };
        }
    }

    /**
     * Verify webhook signature
     * @param {string} payload - Raw webhook payload
     * @param {string} signature - Signature from header
     * @returns {boolean} Whether signature is valid
     */
    verifyWebhookSignature(payload, signature) {
        try {
            if (!this.webhookSecret) {
                console.warn('[Korapay] Webhook secret not configured, skipping verification');
                return true; // Allow in development
            }

            const crypto = require('crypto');
            const computedSignature = crypto
                .createHmac('sha256', this.webhookSecret)
                .update(payload)
                .digest('hex');

            const isValid = crypto.timingSafeEqual(
                Buffer.from(computedSignature),
                Buffer.from(signature)
            );

            if (!isValid) {
                console.warn('[Korapay] Invalid webhook signature');
            } else {
                console.log('[Korapay] Webhook signature verified');
            }

            return isValid;

        } catch (error) {
            console.error('[Korapay] Signature verification error:', error.message);
            return false;
        }
    }

    /**
     * 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: 'Korapay',
            code: 'korapay',
            type: 'api',
            isAutomated: true,
            requiresProof: false,
            isHidden: false,
            supports: ['bank_transfer', 'card', 'mobile_money'],
            currency: 'NGN',
            processingTime: 'Instant',
            mode: this.mode
        };
    }
}

module.exports = KorapayService;
