/**
 * PAN Verification Service
 * Primary: Setu API | Fallback: Local Database
 */

const axios = require('axios');
const { cacheGet, cacheSet } = require('../cache/redis');
const { pool } = require('../database/connection');
const { verifyPanSetu } = require('./setuService');

// PAN Types based on 4th character
const PAN_TYPES = {
    'P': 'Individual',
    'C': 'Company',
    'H': 'HUF',
    'A': 'AOP',
    'B': 'BOI',
    'G': 'Government',
    'J': 'Artificial Juridical Person',
    'L': 'Local Authority',
    'F': 'Firm/Partnership',
    'T': 'Trust'
};

async function verifyPAN(pan, name = null, dob = null) {
    try {
        const cacheKey = `pan:${pan}`;
        const cached = await cacheGet(cacheKey);
        if (cached) {
            console.log(`📦 PAN ${pan} found in cache`);
            return addNameMatch({ success: true, source: cached.source || 'CACHE', data: cached }, name);
        }

        // 1. Regex Validation (Standard 10-char PAN format)
        const panRegex = /^[A-Z]{5}[0-9]{4}[A-Z]{1}$/;
        if (!panRegex.test(pan)) {
            return { success: false, statusCode: 400, errorCode: 'INVALID_FORMAT', message: 'Invalid PAN format. Expected: AAAAA0000A' };
        }

        // 2. PRIMARY: Try Setu API first
        try {
            console.log(`🌐 Attempting Setu API verification for PAN: ${pan}`);
            const setuResult = await verifyPanSetu(pan);

            if (setuResult.success) {
                const panType = PAN_TYPES[pan.charAt(3)] || 'Unknown';

                const data = {
                    pan: pan,
                    name: setuResult.data.full_name || setuResult.data.name,
                    status: 'Valid',
                    type: panType,
                    source: 'SETU_API',
                    // Include any additional fields from Setu response
                    ...setuResult.data
                };

                // Cache the successful result for 24 hours
                await cacheSet(cacheKey, data, 86400);
                console.log(`✅ Setu API verification successful for PAN: ${pan}`);
                return addNameMatch({ success: true, source: 'SETU_API', data }, name);
            }
        } catch (setuError) {
            // Log the Setu error and fall back to local DB
            console.warn(`⚠️ Setu API failed for PAN ${pan}: ${setuError.message}`);
            console.log(`🔄 Switching to local database lookup...`);
        }

        // 3. FALLBACK: Local Database Lookup
        const result = await pool.query('SELECT * FROM pan_data WHERE pan_number = $1', [pan]);

        if (result.rows.length > 0) {
            const row = result.rows[0];
            const panType = PAN_TYPES[pan.charAt(3)] || 'Unknown';

            const data = {
                pan: row.pan_number,
                name: row.full_name,
                status: row.status || 'Valid',
                type: panType,
                father_name: row.father_name,
                dob: row.date_of_birth,
                gender: row.gender,
                category: row.category,
                source: 'LOCAL_DB'
            };

            await cacheSet(cacheKey, data, 86400);
            console.log(`✅ Local DB verification successful for PAN: ${pan}`);
            return addNameMatch({ success: true, source: 'LOCAL_DB', data }, name);
        } else {
            return { success: false, statusCode: 404, errorCode: 'PAN_NOT_FOUND', message: 'PAN not found in any verification source' };
        }
    } catch (error) {
        if (error.code === 'ECONNABORTED') {
            return { success: false, statusCode: 504, errorCode: 'PROVIDER_TIMEOUT', message: 'Service timeout' };
        }
        console.error('PAN verification error:', error.message);
        return { success: false, statusCode: 500, errorCode: 'VERIFICATION_FAILED', message: 'Verification failed' };
    }
}

function formatPANData(pan, d) {
    return {
        pan,
        name: d.name || d.full_name,
        status: d.status || 'Valid',
        type: PAN_TYPES[pan.charAt(3)] || 'Unknown',
        last_name: d.last_name || '',
        first_name: d.first_name || '',
        middle_name: d.middle_name || '',
        title: d.title || ''
    };
}

function addNameMatch(result, inputName) {
    if (!result.success || !inputName) return result;

    const registeredName = result.data.name.toUpperCase();
    const providedName = inputName.toUpperCase();

    // Simple name matching
    const nameMatch = registeredName === providedName ||
        registeredName.includes(providedName) ||
        providedName.includes(registeredName);

    // Calculate match score
    let matchScore = 0;
    if (nameMatch) {
        matchScore = registeredName === providedName ? 100 : 80;
    } else {
        // Partial matching
        const regWords = registeredName.split(' ');
        const provWords = providedName.split(' ');
        const matches = regWords.filter(w => provWords.includes(w)).length;
        matchScore = Math.round((matches / Math.max(regWords.length, provWords.length)) * 100);
    }

    result.data.name_match = matchScore >= 80;
    result.data.name_match_score = matchScore;

    return result;
}

module.exports = { verifyPAN };
