/**
 * IFSC Lookup Route
 * Returns bank details for a given IFSC code
 * Supports local database + Razorpay API fallback
 */

const express = require('express');
const router = express.Router();
const axios = require('axios');
const { authenticateApiKey } = require('../middleware/auth');
const { rateLimit } = require('../middleware/rateLimit');
const { query } = require('../database/connection');
const { cacheGet, cacheSet } = require('../cache/redis');
const { logApiCall } = require('../services/analytics');

/**
 * Fetch IFSC from Razorpay API and save to database
 */
async function fetchFromRazorpayAPI(ifsc) {
    try {
        console.log(`🌐 Fetching IFSC ${ifsc} from Razorpay API...`);

        const response = await axios.get(`https://ifsc.razorpay.com/${ifsc}`, {
            timeout: 10000
        });

        if (response.data && response.data.BANK) {
            const data = response.data;

            try {
                // Save to database for future lookups
                await query(
                    `INSERT INTO ifsc_codes (ifsc, bank_name, branch, address, city, district, state, contact, upi_enabled, rtgs_enabled, neft_enabled, imps_enabled, micr_code, swift_code, updated_at)
                     VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, NOW())`,
                    [
                        ifsc,
                        data.BANK || '',
                        data.BRANCH || '',
                        data.ADDRESS || '',
                        data.CITY || '',
                        data.DISTRICT || '',
                        data.STATE || '',
                        data.CONTACT || '',
                        data.UPI || false,
                        data.RTGS || false,
                        data.NEFT || false,
                        data.IMPS || false,
                        data.MICR || '',
                        data.SWIFT || null
                    ]
                );
                console.log(`✅ Saved IFSC ${ifsc} to database`);
            } catch (insertError) {
                // Ignore duplicate errors
                console.log(`⚠️ Could not save to DB (might already exist):`, insertError.message);
            }

            // Return normalized data
            return {
                success: true,
                data: {
                    ifsc: ifsc,
                    bank_name: data.BANK || '',
                    branch: data.BRANCH || '',
                    address: data.ADDRESS || '',
                    city: data.CITY || '',
                    district: data.DISTRICT || '',
                    state: data.STATE || '',
                    contact: data.CONTACT || '',
                    upi_enabled: data.UPI || false,
                    rtgs_enabled: data.RTGS || false,
                    neft_enabled: data.NEFT || false,
                    imps_enabled: data.IMPS || false,
                    micr_code: data.MICR || '',
                    swift_code: data.SWIFT || null
                },
                source: 'RAZORPAY_API'
            };
        }

        return { success: false, error: 'Invalid IFSC code' };
    } catch (error) {
        if (error.response && error.response.status === 404) {
            console.log(`❌ IFSC ${ifsc} not found in Razorpay API`);
            return { success: false, error: 'IFSC code not found' };
        }
        console.error(`❌ Razorpay API error for ${ifsc}:`, error.message);
        return { success: false, error: error.message };
    }
}

router.use(authenticateApiKey);
router.use(rateLimit);

/**
 * GET /v1/ifsc/bank/:bankName
 * Search branches by bank name
 */
router.get('/bank/:bankName', async (req, res, next) => {
    const startTime = Date.now();
    let success = false;

    try {
        const { bankName } = req.params;

        if (!bankName || bankName.trim().length < 2) {
            return res.status(400).json({
                success: false,
                error: { code: 'INVALID_QUERY', message: 'Bank name must be at least 2 characters' }
            });
        }

        const result = await query(
            `SELECT ifsc, bank_name, branch, address, city, district, contact, state 
             FROM ifsc_codes 
             WHERE bank_name ILIKE $1 
             LIMIT 50`,
            [`%${bankName}%`]
        );

        success = true;

        res.json({
            success: true,
            data: {
                count: result.rows.length,
                results: result.rows
            },
            meta: {
                request_id: `req_ifsc_bank_${Date.now()}`,
                credits_used: 1,
                credits_remaining: req.user.remaining - 1
            }
        });

    } catch (error) {
        next(error);
    } finally {
        await logApiCall({
            userId: req.user.id,
            apiKeyId: req.user.apiKeyId,
            endpoint: '/v1/ifsc/bank',
            method: 'GET',
            params: { bank: req.params.bankName },
            status: success ? 200 : 500,
            duration: Date.now() - startTime,
            success,
            isTestKey: req.user.isTestKey
        });
    }
});

/**
 * GET /v1/ifsc/state/:stateName
 * Search branches by state
 */
router.get('/state/:stateName', async (req, res, next) => {
    const startTime = Date.now();
    let success = false;

    try {
        const { stateName } = req.params;

        if (!stateName || stateName.trim().length < 2) {
            return res.status(400).json({
                success: false,
                error: { code: 'INVALID_QUERY', message: 'State name must be at least 2 characters' }
            });
        }

        const result = await query(
            `SELECT ifsc, bank_name, branch, city, district, state 
             FROM ifsc_codes 
             WHERE state ILIKE $1 
             LIMIT 50`,
            [`%${stateName}%`]
        );

        success = true;

        res.json({
            success: true,
            data: {
                count: result.rows.length,
                results: result.rows
            },
            meta: {
                request_id: `req_ifsc_state_${Date.now()}`,
                credits_used: 1,
                credits_remaining: req.user.remaining - 1
            }
        });

    } catch (error) {
        next(error);
    } finally {
        await logApiCall({
            userId: req.user.id,
            apiKeyId: req.user.apiKeyId,
            endpoint: '/v1/ifsc/state',
            method: 'GET',
            params: { state: req.params.stateName },
            status: success ? 200 : 500,
            duration: Date.now() - startTime,
            success,
            isTestKey: req.user.isTestKey
        });
    }
});

router.get('/:ifsc_code', async (req, res, next) => {
    const startTime = Date.now();
    let success = false;
    let source = 'LOCAL_DB';

    try {
        const { ifsc_code } = req.params;
        const ifscRegex = /^[A-Z]{4}0[A-Z0-9]{6}$/;

        if (!ifscRegex.test(ifsc_code.toUpperCase())) {
            return res.status(400).json({
                success: false,
                error: { code: 'INVALID_IFSC', message: 'Invalid IFSC format' }
            });
        }

        const ifsc = ifsc_code.toUpperCase();
        const cacheKey = `ifsc:${ifsc}`;
        let data = await cacheGet(cacheKey);

        if (data) {
            source = 'CACHE';
        } else {
            // Try local database first
            const result = await query('SELECT * FROM ifsc_codes WHERE ifsc = $1', [ifsc]);

            if (result.rows.length === 0) {
                // Fallback to Razorpay API
                console.log(`📦 IFSC ${ifsc} not in DB, trying Razorpay API...`);
                const apiResult = await fetchFromRazorpayAPI(ifsc);

                if (!apiResult.success) {
                    return res.status(404).json({
                        success: false,
                        error: { code: 'IFSC_NOT_FOUND', message: 'IFSC not found in any source' }
                    });
                }

                data = apiResult.data;
                source = 'RAZORPAY_API';
            } else {
                data = result.rows[0];
            }

            await cacheSet(cacheKey, data, 86400); // Cache for 24 hours
        }

        success = true;

        res.json({
            success: true,
            data: {
                ifsc: data.ifsc,
                source,
                bank: data.bank_name,
                branch: data.branch,
                address: data.address,
                city: data.city,
                district: data.district,
                state: data.state,
                contact: data.contact,
                upi: data.upi_enabled,
                rtgs: data.rtgs_enabled,
                neft: data.neft_enabled,
                imps: data.imps_enabled,
                micr: data.micr_code,
                swift: data.swift_code
            },
            meta: {
                request_id: `req_ifsc_${Date.now()}`,
                credits_used: 1,
                credits_remaining: req.user.remaining - 1
            }
        });

    } catch (error) {
        next(error);
    } finally {
        await logApiCall({
            userId: req.user.id,
            apiKeyId: req.user.apiKeyId,
            endpoint: '/v1/ifsc',
            method: 'GET',
            params: { ifsc: req.params.ifsc_code },
            status: success ? 200 : 500,
            duration: Date.now() - startTime,
            success,
            isTestKey: req.user.isTestKey
        });
    }
});

module.exports = router;
