var sunatCfg = { BROWSERLESS_TOKEN: '', PERUAPI_KEY: '' };
try { sunatCfg = require('./sunat-config'); } catch (_) {}

const express = require('express');
const router = express.Router();
const puppeteer = require('puppeteer-extra');
const StealthPlugin = require('puppeteer-extra-plugin-stealth');
const db = require('../config/db');
const axios = require('axios');

puppeteer.use(StealthPlugin());

const SUNAT_URL = 'https://e-consultaruc.sunat.gob.pe/cl-ti-itmrconsruc/jcrS00Alias';

function getBrowserWSEndpoint() {
    var token = sunatCfg.BROWSERLESS_TOKEN || process.env.BROWSERLESS_TOKEN;
    return token
        ? 'wss://chrome.browserless.io?token=' + token
        : '';
}

async function launchBrowser() {
    var isWeb = (process.env.DB_TYPE || process.env.MODO_ERP || 'mssql').toLowerCase() === 'mysql' || (process.env.DB_TYPE || process.env.MODO_ERP || 'mssql').toLowerCase() === 'web';
    if (!isWeb) {
        var localPaths = [
            process.env.CHROME_PATH,
            'C:\\Program Files\\Google\\Chrome\\Application\\chrome.exe',
            'C:\\Program Files (x86)\\Google\\Chrome\\Application\\chrome.exe'
        ].filter(Boolean);
        for (var i = 0; i < localPaths.length; i++) {
            try {
                console.log('[SUNAT] Probando Chrome local:', localPaths[i]);
                var browser = await puppeteer.launch({ executablePath: localPaths[i], headless: true });
                console.log('[SUNAT] Chrome local OK');
                return browser;
            } catch (e) {
                console.log('[SUNAT] Chrome local no disponible en', localPaths[i] + ':', e.message);
            }
        }
        console.log('[SUNAT] Sin Chrome local, usando Browserless...');
    }
    var ws = getBrowserWSEndpoint();
    if (ws) {
        return await puppeteer.connect({ browserWSEndpoint: ws, defaultViewport: { width: 1280, height: 900 } });
    }
    throw new Error('No se pudo lanzar Chrome local ni conectar a Browserless.');
}

function validarRuc(ruc) {
    if (!ruc || ruc.length !== 11 || !/^\d+$/.test(ruc)) return false;
    var suma = 0, x = 6;
    for (var i = 0; i < 10; i++) {
        if (i === 4) x = 8;
        var digito = parseInt(ruc.charAt(i));
        x--;
        suma += digito * x;
    }
    var resto = suma % 11;
    resto = 11 - resto;
    if (resto >= 10) resto -= 10;
    return resto === parseInt(ruc.charAt(10));
}

function parsearUbigeo(direccion) {
    if (!direccion) return null;
    var parts = direccion.split(' - ');
    if (parts.length < 2) return null;
    return {
        provincia: parts[parts.length - 2].trim(),
        distrito: parts[parts.length - 1].trim()
    };
}

async function buscarCodUbigeo(provincia, distrito) {
    try {
        var deps = await db.query(
            'SELECT DISTINCT TOP 1 departamento FROM ubigeo WHERE provincia = @prov',
            { prov: { type: db.sql.NVarChar(100), value: provincia } }
        );
        if (deps.length === 0) return null;
        var departamento = deps[0].departamento;

        var rows = await db.query(
            'SELECT TOP 1 cod_ubigeo FROM ubigeo WHERE departamento = @dep AND provincia = @prov AND distrito = @dis AND activo = 1',
            {
                dep: { type: db.sql.NVarChar(100), value: departamento },
                prov: { type: db.sql.NVarChar(100), value: provincia },
                dis: { type: db.sql.NVarChar(100), value: distrito }
            }
        );
        if (rows.length === 0) return null;
        return { cod_ubigeo: rows[0].cod_ubigeo, departamento: departamento };
    } catch (error) {
        console.error('[SUNAT] Error al buscar ubigeo:', error.message);
        return null;
    }
}

router.get('/sunat/consultar-ruc/:ruc', async function(req, res) {
    var ruc = (req.params.ruc || '').replace(/\D/g, '');
    if (ruc.length !== 11) {
        return res.json({ ok: false, mensaje: 'El RUC debe tener 11 d\u00edgitos' });
    }
    if (!validarRuc(ruc)) {
        return res.json({ ok: false, mensaje: 'El RUC ingresado no es v\u00e1lido' });
    }

    var browser = null;
    try {
        browser = await launchBrowser();

        var page = await browser.newPage();
        await page.setUserAgent('Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36');
        await page.setViewport({ width: 1280, height: 900 });

        await page.goto(SUNAT_URL, { waitUntil: 'domcontentloaded', timeout: 20000 });
        await page.waitForSelector('#txtRuc', { timeout: 10000 });

        await page.evaluate(function(ruc) {
            window.txtRuc.val(ruc);
        }, ruc);

        await Promise.all([
            page.waitForNavigation({ waitUntil: 'domcontentloaded', timeout: 20000 }),
            page.click('#btnAceptar')
        ]);

        await page.waitForFunction(function() {
            return document.documentElement.outerHTML.indexOf('N\u00famero de RUC') >= 0 ||
                   document.documentElement.outerHTML.indexOf('Resultados') >= 0;
        }, { timeout: 15000 });

        var data = await page.evaluate(function() {
            var result = {};
            document.querySelectorAll('body *').forEach(function(el) {
                var text = (el.textContent || '').trim();
                if (text.indexOf('N\u00famero de RUC') >= 0) {
                    result.ruc = (el.parentNode && el.parentNode.nextElementSibling) ? el.parentNode.nextElementSibling.textContent.trim() : '';
                } else if (text.indexOf('Raz\u00f3n Social') >= 0) {
                    result.razon_social = (el.parentNode && el.parentNode.nextElementSibling) ? el.parentNode.nextElementSibling.textContent.trim() : '';
                } else if (text.indexOf('Estado del Contribuyente') >= 0) {
                    result.estado = (el.parentNode && el.parentNode.nextElementSibling) ? el.parentNode.nextElementSibling.textContent.trim() : '';
                } else if (text.indexOf('Condici\u00f3n del Contribuyente') >= 0) {
                    result.condicion = (el.parentNode && el.parentNode.nextElementSibling) ? el.parentNode.nextElementSibling.textContent.trim() : '';
                } else if (text.indexOf('Domicilio Fiscal') >= 0) {
                    result.direccion = (el.parentNode && el.parentNode.nextElementSibling) ? el.parentNode.nextElementSibling.textContent.replace(/\s+/g, ' ').trim() : '';
                }
            });
            return result;
        });

        if (!data.razon_social && data.ruc) {
            var parts = data.ruc.split(' - ');
            data.ruc = parts[0] || ruc;
            data.razon_social = parts.slice(1).join(' - ') || '';
        }

        if (!data.razon_social) {
            return res.json({ ok: false, mensaje: 'No se encontraron datos para el RUC ' + ruc });
        }

        var resultado = {
            ruc: ruc,
            razon_social: data.razon_social.trim(),
            direccion: (data.direccion || '').trim(),
            estado: (data.estado || '').trim(),
            condicion: (data.condicion || '').trim()
        };

        var ubigeo = parsearUbigeo(resultado.direccion);
        if (ubigeo) {
            var ubigeoResult = await buscarCodUbigeo(ubigeo.provincia, ubigeo.distrito);
            if (ubigeoResult) {
                resultado.cod_ubigeo = ubigeoResult.cod_ubigeo;

                var parts = resultado.direccion.split(' - ');
                var cleanAddr = parts.slice(0, -2).join(' - ').trim();

                var dept = ubigeoResult.departamento;
                if (cleanAddr.toUpperCase().endsWith(dept.toUpperCase())) {
                    cleanAddr = cleanAddr.substring(0, cleanAddr.length - dept.length).trim();
                    cleanAddr = cleanAddr.replace(/[,\s]+$/, '');
                }

                resultado.direccion = cleanAddr;
            }
        }

        res.json({ ok: true, data: resultado });

    } catch (error) {
        console.error('[SUNAT] Error al consultar RUC ' + ruc + ':', error.message);
        res.json({ ok: false, mensaje: 'Error al consultar SUNAT: ' + (error.message || 'sin respuesta') });
    } finally {
        if (browser) {
            try { await browser.close(); } catch (_) {}
        }
    }
});

// ============================================================
// GET /sunat/consultar-dni/:dni — Consulta DNI vía ApiInti
// ============================================================
router.get('/sunat/consultar-dni/:dni', async function(req, res) {
    var dni = (req.params.dni || '').replace(/\D/g, '');
    if (dni.length !== 8) {
        return res.json({ ok: false, mensaje: 'El DNI debe tener 8 d\u00edgitos' });
    }

    var apiintiKey = sunatCfg.APIINTI_KEY || process.env.APIINTI_KEY;
    var peruapiKey = sunatCfg.PERUAPI_KEY || process.env.PERUAPI_KEY;

    async function consultarApiInti() {
        var r = await axios.get('https://app.apiinti.dev/api/v1/dni/' + dni, {
            headers: { Authorization: 'Bearer ' + apiintiKey },
            timeout: 8000
        });
        if (!r.data.success || !r.data.data) throw new Error(r.data.mensaje || 'Sin datos');
        return r.data.data;
    }

    async function consultarPeruapi() {
        var r = await axios.get('https://peruapi.com/api/dni/' + dni, {
            params: { api_token: peruapiKey, summary: '0', plan: '0' },
            timeout: 8000
        });
        if (r.data.code !== '200' || !r.data.dni) throw new Error(r.data.mensaje || 'Sin datos');
        return {
            dni: r.data.dni,
            nombreCompleto: r.data.cliente || (r.data.nombres + ' ' + r.data.apellido_paterno + ' ' + r.data.apellido_materno).trim(),
            nombres: r.data.nombres || '',
            apellidoPaterno: r.data.apellido_paterno || '',
            apellidoMaterno: r.data.apellido_materno || ''
        };
    }

    try {
        var data;
        if (apiintiKey) {
            data = await consultarApiInti();
        } else if (peruapiKey) {
            data = await consultarPeruapi();
        } else {
            return res.json({ ok: false, mensaje: 'No hay API key configurada para consulta DNI' });
        }
        return res.json({
            ok: true,
            data: {
                dni: data.dni,
                razon_social: data.nombreCompleto,
                nombres: data.nombres || '',
                apellido_paterno: data.apellidoPaterno || '',
                apellido_materno: data.apellidoMaterno || ''
            }
        });
    } catch (error) {
        if (apiintiKey && peruapiKey) {
            console.log('[SUNAT] ApiInti falló, probando peruapi.com...');
            try {
                var data2 = await consultarPeruapi();
                return res.json({
                    ok: true,
                    data: {
                        dni: data2.dni,
                        razon_social: data2.nombreCompleto,
                        nombres: data2.nombres || '',
                        apellido_paterno: data2.apellidoPaterno || '',
                        apellido_materno: data2.apellidoMaterno || ''
                    }
                });
            } catch (error2) {
                console.error('[SUNAT] Error DNI ' + dni + ':', error2.message);
                return res.json({ ok: false, mensaje: 'Error al consultar DNI: ' + (error2.message || 'sin respuesta') });
            }
        }
        console.error('[SUNAT] Error DNI ' + dni + ':', error.message);
        res.json({ ok: false, mensaje: 'Error al consultar DNI: ' + (error.message || 'sin respuesta') });
    }
});

module.exports = router;
