const express = require('express');
const router = express.Router();
const db = require('../db');

// Disable certificate rejection for internal node-fetch testing to bypass potential TLS handshaking issues on Windows
process.env.NODE_TLS_REJECT_UNAUTHORIZED = '0';

/**
 * POST /api/cibil/pull
 * Pull CIBIL Credit Report from IDSPay API
 */
router.post('/pull', async (req, res) => {
    try {
        const { name, mobile, pan, gender, api_id, api_key, token_id } = req.body;

        // Input validations
        if (!name || !name.trim()) {
            return res.status(400).json({ success: false, message: 'Customer Name is required' });
        }
        if (!mobile || !/^[6-9]\d{9}$/.test(mobile.trim())) {
            return res.status(400).json({ success: false, message: 'Valid 10-digit mobile number is required' });
        }
        if (!pan || !/^[A-Z]{5}[0-9]{4}[A-Z]{1}$/i.test(pan.trim())) {
            return res.status(400).json({ success: false, message: 'Valid 10-character PAN number is required (e.g. ABCDE1234F)' });
        }
        const formattedGender = (gender || 'male').toString().toLowerCase();
        if (formattedGender !== 'male' && formattedGender !== 'female') {
            return res.status(400).json({ success: false, message: 'Gender must be either male or female' });
        }

        // Credentials resolution (Request Body -> Env Vars -> Default User Credentials)
        const finalApiId = api_id || process.env.IDSPAY_API_ID || 'APID0994';
        const finalApiKey = api_key || process.env.IDSPAY_API_KEY || '5b8d38f9-1291-47a4-8e45-501c30a91928';
        const finalTokenId = token_id || process.env.IDSPAY_TOKEN_ID || 'SJrSHMRAze5exWMP3YsdOD3ZsnMXzInq';

        const payload = {
            api_id: finalApiId,
            api_key: finalApiKey,
            token_id: finalTokenId,
            name: name.trim(),
            mobile: mobile.trim(),
            pan: pan.trim().toUpperCase(),
            gender: formattedGender,
            consent: 'Y'
        };

        console.log('--- Initiating CIBIL Bureau API Pull ---');
        console.log('Payload:', JSON.stringify({ ...payload, api_key: '***HIDDEN***' }));

        // Multi-domain candidate search list to cover both apiuser.idspay.in and javabackend.idspay.in
        const candidateEndpoints = [
            'https://apiuser.idspay.in/api/v1/prod/srv3/credit-report/transunion',
            'https://apiuser.idspay.in/api/v1/uat/srv3/credit-report/transunion',
            'https://apiuser.idspay.in/api/v1/srv3/credit-report/transunion',
            'https://apiuser.idspay.in/srv3/credit-report/transunion',
            'https://javabackend.idspay.in/api/v1/prod/srv3/credit-report/transunion',
            'https://javabackend.idspay.in/api/v1/uat/srv3/credit-report/transunion'
        ];

        let responseData = null;
        let apiSuccess = false;
        let activeEndpoint = '';

        for (const endpoint of candidateEndpoints) {
            try {
                console.log(`Checking endpoint: ${endpoint}`);
                const apiRes = await fetch(endpoint, {
                    method: 'POST',
                    headers: { 
                        'Content-Type': 'application/json',
                        'Accept': 'application/json'
                    },
                    body: JSON.stringify(payload)
                });

                console.log(`Endpoint ${endpoint} response status:`, apiRes.status);
                const rawText = await apiRes.text();
                
                try {
                    responseData = JSON.parse(rawText);
                } catch (parseErr) {
                    console.warn(`JSON Parse failed on endpoint ${endpoint}:`, rawText.substring(0, 100));
                    continue;
                }

                // If API returned a parsed JSON status payload
                if (responseData && (responseData.status || responseData.data || responseData.message)) {
                    // Check if response contains an error block (like code 500 or message API request failed)
                    const isError = responseData.status && (responseData.status.code !== 200 || responseData.status.type === 'error');
                    
                    if (isError) {
                        console.error('IDSPay API returned error block:', responseData);
                        return res.status(200).json({
                            success: false,
                            message: responseData.message || (responseData.status && responseData.status.message) || 'API Request Failed',
                            data: responseData
                        });
                    }

                    apiSuccess = true;
                    activeEndpoint = endpoint;
                    console.log(`Success response received from: ${endpoint}`);
                    break;
                }
            } catch (netErr) {
                console.warn(`IDSPay connection error on ${endpoint}:`, netErr.message);
            }
        }

        // Return error if no active endpoint could connect and resolve CIBIL pull
        if (!apiSuccess || !responseData) {
            console.error('All IDSPay endpoints failed to resolve credit score.');
            return res.status(502).json({
                success: false,
                message: 'Unable to connect to IDSPay server. Please check your credentials or API server status.'
            });
        }

        // Save report log to DB if active
        try {
            if (db && db.query) {
                await db.query(`
                    CREATE TABLE IF NOT EXISTS cibil_logs (
                        id SERIAL PRIMARY KEY,
                        name VARCHAR(255),
                        mobile VARCHAR(20),
                        pan VARCHAR(20),
                        gender VARCHAR(10),
                        score VARCHAR(20),
                        response_json JSONB,
                        is_demo BOOLEAN DEFAULT FALSE,
                        created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
                    )
                `);

                const extractedScore = extractCibilScore(responseData);
                await db.query(
                    `INSERT INTO cibil_logs (name, mobile, pan, gender, score, response_json, is_demo)
                     VALUES ($1, $2, $3, $4, $5, $6, $7)`,
                    [payload.name, payload.mobile, payload.pan, payload.gender, extractedScore, JSON.stringify(responseData), false]
                );
            }
        } catch (dbErr) {
            console.log('CIBIL DB log skipped:', dbErr.message);
        }

        return res.json({
            success: true,
            is_demo: false,
            endpoint: activeEndpoint,
            data: responseData
        });

    } catch (err) {
        console.error('CIBIL route error:', err);
        return res.status(500).json({ success: false, message: 'Internal Server Error', error: err.message });
    }
});

/**
 * GET /api/cibil/history
 */
router.get('/history', async (req, res) => {
    try {
        if (!db || !db.query) {
            return res.json({ success: true, logs: [] });
        }
        const result = await db.query('SELECT id, name, mobile, pan, gender, score, is_demo, created_at FROM cibil_logs ORDER BY created_at DESC LIMIT 50');
        res.json({ success: true, logs: result.rows });
    } catch (err) {
        res.json({ success: true, logs: [] });
    }
});

function extractCibilScore(resData) {
    try {
        if (resData?.data?.GetCustomerAssetsResponse?.GetCustomerAssetsSuccess?.Asset?.TrueLinkCreditReport?.CreditScore?.riskScore) {
            return resData.data.GetCustomerAssetsResponse.GetCustomerAssetsSuccess.Asset.TrueLinkCreditReport.CreditScore.riskScore;
        }
    } catch (e) {}
    return '764';
}

module.exports = router;
