const express = require('express');
const router = express.Router();
const { makeHttpsRequest } = require('../utils/network');
const { auditLog } = require('../utils/logging');
const config = require('../config/environment');
const QuickBooksPaymentsService = require('../services/quickbooks-payments');
const QuickBooksOnlineService = require('../services/quickbooks-online');

/**
 * Admin API Routes for QuickBooks Elementor Widget Compatibility
 * These endpoints provide API access for the WordPress Elementor widget
 */

// Get single transaction details
router.get('/transactions/:transactionId', async (req, res) => {
    try {
        const { transactionId } = req.params;
        auditLog('ADMIN_API_TRANSACTION_DETAILS_REQUEST', { transactionId }, req);
        
        const { accessToken, realmId } = req.qbTokens;
        
        if (!accessToken) {
            return res.status(401).json({
                success: false,
                message: 'QuickBooks not connected',
                requestId: req.requestId
            });
        }
        
        // Initialize QuickBooks Payments service
        const paymentsService = new QuickBooksPaymentsService(accessToken, config.QB_ENVIRONMENT);
        
        // Get transaction details from QuickBooks Payments API
        const apiUrl = `${paymentsService.baseUrl}/quickbooks/v4/payments/charges/${transactionId}`;
        
        const options = {
            method: 'GET',
            headers: {
                'Authorization': `Bearer ${accessToken}`,
                'Accept': 'application/json',
                'User-Agent': 'QuickBooks-Payment-Gateway/1.0',
                'Request-Id': req.requestId
            },
            timeout: 15000
        };
        
        auditLog('ADMIN_API_PAYMENTS_REQUEST', { 
            url: apiUrl, 
            transactionId,
            environment: config.QB_ENVIRONMENT
        }, req);
        
        const response = await makeHttpsRequest(apiUrl, options);
        
        if (response.status === 200 && response.data) {
            const transaction = response.data;
            
            auditLog('ADMIN_API_TRANSACTION_DETAILS_SUCCESS', { 
                transactionId, 
                status: transaction.status,
                amount: transaction.amount
            }, req);
            
            // Format transaction data for widget compatibility
            const formattedTransaction = {
                id: transaction.id,
                amount: transaction.amount,
                currency: transaction.currency || 'USD',
                status: transaction.status,
                created: transaction.created,
                updated: transaction.updated,
                card: transaction.card ? {
                    cardType: transaction.card.cardType,
                    number: transaction.card.number,
                    name: transaction.card.name,
                    expMonth: transaction.card.expMonth,
                    expYear: transaction.card.expYear
                } : null,
                paymentMethod: transaction.paymentMethod,
                customer: transaction.customer,
                authCode: transaction.authCode
            };
            
            res.json({
                success: true,
                transaction: formattedTransaction,
                requestId: req.requestId
            });
        } else {
            auditLog('ADMIN_API_TRANSACTION_NOT_FOUND', { 
                transactionId, 
                status: response.status 
            }, req);
            
            res.status(404).json({
                success: false,
                message: 'Transaction not found',
                requestId: req.requestId
            });
        }
        
    } catch (error) {
        auditLog('ADMIN_API_TRANSACTION_DETAILS_ERROR', { 
            error: error.message, 
            transactionId: req.params.transactionId 
        }, req);
        
        res.status(500).json({
            success: false,
            message: 'Failed to retrieve transaction details',
            error: error.message,
            requestId: req.requestId
        });
    }
});

// Process refund for transaction
router.post('/transactions/:transactionId/refund', async (req, res) => {
    try {
        const { transactionId } = req.params;
        const { amount, reason } = req.body;
        
        auditLog('ADMIN_API_REFUND_REQUEST', { transactionId, amount, reason }, req);
        
        const { accessToken, realmId, refreshAccessToken } = req.qbTokens;
        
        if (!accessToken) {
            return res.status(401).json({
                success: false,
                message: 'QuickBooks not connected',
                requestId: req.requestId
            });
        }
        
        // Validate refund data
        if (!amount || !reason) {
            return res.status(400).json({
                success: false,
                message: 'Refund amount and reason are required',
                requestId: req.requestId
            });
        }
        
        // Initialize services
        const paymentsService = new QuickBooksPaymentsService(accessToken, config.QB_ENVIRONMENT);
        const qboService = new QuickBooksOnlineService(accessToken, realmId, config.QB_ENVIRONMENT);
        
        // Prepare refund data
        // QuickBooks Payments API v4 expects simple format: {"amount": 200}
        const refundData = {
            amount: parseFloat(amount),
            reason: reason
        };
        
        auditLog('ADMIN_API_REFUND_PROCESSING', { 
            transactionId, 
            refundAmount: refundData.amount,
            reason: reason
        }, req);
        
        // Check if transaction has already been refunded
        const transactionDetails = await paymentsService.getTransactionDetails(transactionId, req);
        const existingRefunds = transactionDetails.data?.refundDetail || transactionDetails.data?.refunds || [];
        
        if (existingRefunds.length > 0) {
            const totalRefunded = existingRefunds.reduce((sum, refund) => {
                return sum + parseFloat(refund.amount || 0);
            }, 0);
            
            if (totalRefunded >= parseFloat(transactionDetails.data.amount)) {
                auditLog('REFUND_BLOCKED_ALREADY_REFUNDED', {
                    transactionId,
                    totalRefunded,
                    transactionAmount: transactionDetails.data.amount
                }, req);
                
                return res.status(400).json({
                    success: false,
                    message: `Transaction has already been fully refunded (Refund ID: ${existingRefunds[0].id})`,
                    totalRefunded: totalRefunded,
                    transactionAmount: transactionDetails.data.amount,
                    existingRefunds: existingRefunds,
                    requestId: req.requestId
                });
            }
        }
        
        // Process refund through QuickBooks Payments API
        const refundResponse = await paymentsService.processRefund(transactionId, refundData, req);
        
        if (refundResponse.status === 200 && refundResponse.data) {
            const refund = refundResponse.data;
            
            auditLog('ADMIN_API_REFUND_SUCCESS', { 
                transactionId, 
                refundId: refund.id,
                amount: refund.amount,
                status: refund.status
            }, req);
            
            // Create Refund Receipt in QuickBooks Online for accounting
            let refundReceipt = null;
            try {
                // First, try to find the original sales receipt to get customer info
                const salesReceiptQuery = `SELECT * FROM SalesReceipt WHERE DocNumber = '${transactionId}'`;
                const salesReceiptResponse = await qboService.makeQBOApiRequest('query', 'GET', null, salesReceiptQuery);
                
                let customer = null;
                if (salesReceiptResponse.data?.QueryResponse?.SalesReceipt?.length > 0) {
                    const originalReceipt = salesReceiptResponse.data.QueryResponse.SalesReceipt[0];
                    if (originalReceipt.CustomerRef) {
                        customer = { Id: originalReceipt.CustomerRef.value, DisplayName: originalReceipt.CustomerRef.name };
                    }
                }
                
                // Create refund receipt if we have customer info
                if (customer) {
                    const refundReceiptData = {
                        CustomerRef: {
                            value: customer.Id,
                            name: customer.DisplayName
                        },
                        TxnDate: new Date().toISOString().split('T')[0],
                        Line: [{
                            Amount: parseFloat(amount).toFixed(2),
                            DetailType: "SalesItemLineDetail",
                            SalesItemLineDetail: {
                                ItemRef: {
                                    value: "1",
                                    name: "Services"
                                }
                            }
                        }],
                        TotalAmt: parseFloat(amount).toFixed(2),
                        PrivateNote: `Refund processed via QuickBooks Payments API. Original Transaction ID: ${transactionId}. Refund ID: ${refund.id}. Reason: ${reason}`,
                        DocNumber: refund.id
                    };
                    
                    refundReceipt = await qboService.makeQBOApiRequest('refundreceipt', 'POST', refundReceiptData);
                    
                    auditLog('ADMIN_API_REFUND_RECEIPT_CREATED', { 
                        refundReceiptId: refundReceipt.data?.RefundReceipt?.Id,
                        customerId: customer.Id,
                        transactionId: transactionId,
                        refundId: refund.id
                    }, req);
                }
            } catch (receiptError) {
                auditLog('ADMIN_API_REFUND_RECEIPT_ERROR', { 
                    error: receiptError.message,
                    transactionId: transactionId,
                    refundId: refund.id,
                    refundStillSuccessful: true
                }, req);
                // Continue even if refund receipt creation fails - refund was successful
            }
            
            // Return success response
            res.json({
                success: true,
                message: 'Refund processed successfully',
                refund: {
                    id: refund.id,
                    amount: refund.amount,
                    status: refund.status,
                    created: refund.created,
                    originalTransactionId: transactionId
                },
                refundReceipt: refundReceipt ? {
                    id: refundReceipt.data?.RefundReceipt?.Id,
                    docNumber: refundReceipt.data?.RefundReceipt?.DocNumber
                } : null,
                requestId: req.requestId
            });
        } else {
            auditLog('ADMIN_API_REFUND_FAILED', { 
                transactionId, 
                status: refundResponse.status,
                error: refundResponse.data
            }, req);
            
            res.status(400).json({
                success: false,
                message: 'Refund processing failed',
                error: refundResponse.data,
                requestId: req.requestId
            });
        }
        
    } catch (error) {
        auditLog('ADMIN_API_REFUND_ERROR', { 
            error: error.message, 
            transactionId: req.params.transactionId 
        }, req);
        
        res.status(500).json({
            success: false,
            message: 'Refund processing error',
            error: error.message,
            requestId: req.requestId
        });
    }
});

// QuickBooks connection status endpoint
router.get('/qb-status', (req, res) => {
    try {
        auditLog('ADMIN_API_QB_STATUS_CHECK', {}, req);
        
        const { accessToken, refreshToken, tokenExpiresAt, realmId } = req.qbTokens;
        
        const hasAccessToken = !!accessToken;
        const hasRefreshToken = !!refreshToken;
        const isTokenExpired = Date.now() >= tokenExpiresAt;
        const canRefresh = hasRefreshToken && !isTokenExpired;
        
        const status = {
            success: true,
            connected: hasAccessToken && !isTokenExpired,
            hasAccessToken,
            hasRefreshToken,
            isTokenExpired,
            canRefresh,
            realmId: realmId || null,
            environment: config.QB_ENVIRONMENT,
            tokenExpiresAt: tokenExpiresAt ? new Date(tokenExpiresAt).toISOString() : null,
            requestId: req.requestId
        };
        
        if (!hasAccessToken) {
            status.message = 'Not connected to QuickBooks';
        } else if (isTokenExpired) {
            status.message = 'QuickBooks token has expired';
        } else {
            status.message = 'Connected to QuickBooks';
        }
        
        auditLog('ADMIN_API_QB_STATUS_RESPONSE', { 
            connected: status.connected,
            hasTokens: hasAccessToken && hasRefreshToken,
            isExpired: isTokenExpired
        }, req);
        
        res.json(status);
        
    } catch (error) {
        auditLog('ADMIN_API_QB_STATUS_ERROR', { error: error.message }, req);
        
        res.status(500).json({
            success: false,
            message: 'Failed to check QuickBooks status',
            error: error.message,
            requestId: req.requestId
        });
    }
});

// Gateway status endpoint
router.get('/gateway-status', (req, res) => {
    try {
        auditLog('ADMIN_API_GATEWAY_STATUS_CHECK', {}, req);
        
        res.json({
            success: true,
            status: 'operational',
            environment: config.QB_ENVIRONMENT,
            nodeVersion: process.version,
            uptime: process.uptime(),
            timestamp: new Date().toISOString(),
            requestId: req.requestId
        });
        
    } catch (error) {
        auditLog('ADMIN_API_GATEWAY_STATUS_ERROR', { error: error.message }, req);
        
        res.status(500).json({
            success: false,
            message: 'Failed to check gateway status',
            error: error.message,
            requestId: req.requestId
        });
    }
});

module.exports = router;
