'use strict';
/**
 * testLogin.js — Diagnóstico de login en Instagram.
 *
 * Uso (desde dist-worker/):
 *   node worker/testLogin.js                      → usa BROWSER_ENGINE del .env (default: playwright)
 *   node worker/testLogin.js --playwright          → forzar Patchright/Chrome
 *   node worker/testLogin.js --cloak               → forzar CloakBrowser
 *   node worker/testLogin.js --no-cookies          → sin inyectar ig_did
 *   node worker/testLogin.js --cookies             → forzar inyección de cookies
 *
 * Objetivo: aislar si el captcha viene del motor (CloakBrowser) o de las cookies.
 */

const path = require('path');
const os   = require('os');
const fs   = require('fs');

// ── Cargar .env y .env.dev antes de leer las variables ───────────────────────
// testLogin.js se corre directamente con `node`, sin pasar por el Electron launcher
// que normalmente inyecta las variables del .env al proceso.
try {
    const { config: dotenvConfig } = require('dotenv');
    const root = path.join(__dirname, '..');
    dotenvConfig({ path: path.join(root, '.env') });           // base: .env
    dotenvConfig({ path: path.join(root, '.env.dev'),          // override: .env.dev (dev mode)
        override: true });
} catch (_) { /* dotenv opcional */ }

const argv       = new Set(process.argv.slice(2));
// Modo: CLI flags tienen prioridad sobre .env.dev
//   --cloak / --cloakbrowser → forzar CloakBrowser aunque .env diga playwright
//   --playwright / --plain   → forzar Patchright/Chrome aunque .env diga cloak
//   (sin flag)               → usa BROWSER_ENGINE del .env.dev
const forceCloak  = argv.has('--cloak') || argv.has('--cloakbrowser');
const usePlain    = !forceCloak && (argv.has('--playwright') || argv.has('--plain') || process.env.BROWSER_ENGINE === 'playwright');

// Canal de Chrome: BROWSER_CHANNEL=chrome usa Google Chrome del sistema
// CLI: --chrome → fuerza canal Chrome; --chromium → fuerza Chromium de Patchright
const browserChannel = argv.has('--chromium') ? undefined
    : argv.has('--chrome') ? 'chrome'
    : (process.env.BROWSER_CHANNEL || undefined);

// Cookies: --no-cookies/--cookies en CLI, INJECT_CHROME_COOKIES en .env, o smart default
const _forceCookies  = argv.has('--cookies');
const _noCookiesFlag = argv.has('--no-cookies');
const _envCookies    = process.env.INJECT_CHROME_COOKIES;
const noCookies = _forceCookies ? false
    : _noCookiesFlag ? true
    : _envCookies !== undefined && _envCookies !== '' ? _envCookies === 'false'
    : !usePlain;   // CloakBrowser → sin cookies por defecto; Playwright → con cookies
const headless   = argv.has('--headless');

// ─────────────────────────────────────────────────────────────────────────────

async function main() {
    console.log('\n' + '═'.repeat(55));
    console.log('  xponencIA — Test de Login Instagram');
    console.log('═'.repeat(55));
    const motorLabel = usePlain
        ? `🌐 Patchright + ${browserChannel === 'chrome' ? 'Google Chrome' : 'Chromium'}`
        : '🛡  CloakBrowser (Real PC Mode)';
    console.log(`  Motor:    ${motorLabel}`);
    console.log(`  Cookies:  ${noCookies ? '✗ desactivadas' : '✓ ig_did + device cookies de Chrome'}`);
    console.log(`  Headless: ${headless ? 'sí' : 'no (ventana visible)'}`);
    console.log('═'.repeat(55) + '\n');

    // ── 1. Lanzar navegador ───────────────────────────────────────────────────
    const tmpDir = path.join(os.tmpdir(), `xp_test_${Date.now()}`);
    fs.mkdirSync(tmpDir, { recursive: true });

    let context;

    if (usePlain) {
        // Patchright (→ fallback playwright) + stealth patch
        const { getChromium, applyPlaywrightStealth } = require('./realPcContext');
        let chromium;
        try {
            chromium = getChromium();
        } catch (e) {
            console.error('✗ Ni patchright ni playwright están instalados en node_modules.');
            process.exit(1);
        }
        const channelLabel = browserChannel ? ` (canal: ${browserChannel})` : '';
        console.log(`[browser] Lanzando Patchright${channelLabel} + stealth patch...`);
        context = await chromium.launchPersistentContext(tmpDir, {
            headless,
            channel: browserChannel,   // 'chrome' → Google Chrome del sistema; undefined → Chromium
            args: [
                '--no-sandbox',
                // Impide que Chrome ponga navigator.webdriver=true cuando es controlado por CDP.
                // Patchright lo parchea en su Chromium bundleado, pero con channel:chrome
                // (Google Chrome del sistema) puede no aplicarse a nivel binario.
                '--disable-blink-features=AutomationControlled',
            ],
            viewport: null,            // null = Chrome decide el viewport según la ventana real
        });
        await applyPlaywrightStealth(context);
    } else {
        // CloakBrowser — Real PC Mode (igual que en producción)
        let launchPersistentContext;
        try {
            const cb = await import('cloakbrowser');
            launchPersistentContext = cb.launchPersistentContext;
        } catch (e) {
            console.error('✗ CloakBrowser no disponible:', e.message);
            process.exit(1);
        }
        console.log('[browser] Lanzando CloakBrowser (Real PC Mode)...');
        const { REAL_PC_LAUNCH_OPTIONS, getLaunchArgs, detectRealGpu, detectCssScreenSize, applyRealPcPatches } = require('./realPcContext');

        // Detectar GPU real (passthrough) y cachear en tmpDir
        process.stdout.write('[hardware] Detectando GPU real... ');
        const realGpu = await detectRealGpu(tmpDir);
        if (realGpu) {
            console.log(`✓ ${realGpu.renderer}`);
        } else {
            console.log('⚠ no detectada — se usará GPU del seed');
        }

        // Detectar pantalla CSS (PowerShell fallback, o 1920x1080)
        const cssScreen = detectCssScreenSize(tmpDir);
        console.log(`[hardware] Pantalla CSS detectada: ${cssScreen.width}x${cssScreen.height}`);

        context = await launchPersistentContext({
            userDataDir: tmpDir,
            headless,
            ...REAL_PC_LAUNCH_OPTIONS,
            args: getLaunchArgs(tmpDir, cssScreen),
        });
        await applyRealPcPatches(context);
    }

    // ── 2. Inyectar cookies de Chrome ─────────────────────────────────────────
    if (!noCookies) {
        try {
            const { extractChromeDeviceCookies } = require('./chromeImporter');
            console.log('[cookies] Leyendo cookies de Chrome...');
            const { device } = await extractChromeDeviceCookies();
            if (device.length > 0) {
                await context.addCookies(device);
                console.log(`[cookies] ✓ Inyectadas: ${device.map(c => c.name).join(', ')}`);
            } else {
                console.log('[cookies] ⚠ Chrome no tiene cookies de Instagram (abrí instagram.com en Chrome)');
            }
        } catch (e) {
            console.log(`[cookies] ⚠ No se pudo leer Chrome: ${e.message}`);
        }
    } else {
        console.log('[cookies] Skipped (--no-cookies)');
    }

    const page = context.pages()[0] || await context.newPage();

    // ── 3. Checks de fingerprint ANTES de navegar ─────────────────────────────
    // NOTA: addInitScript corre en cada navegación, NO en la página en blanco
    // ya abierta. Los valores aquí son SIN parchear (RAW del navegador).
    // El patch de screen/CPU se verifica en el check POST-navegación (paso 6).
    console.log('\n[fingerprint] RAW — página en blanco (sin addInitScript aún):');
    const fp = await page.evaluate(() => ({
        webdriver:    navigator.webdriver,
        userAgent:    navigator.userAgent.slice(0, 80),
        platform:     navigator.platform,
        languages:    navigator.languages?.join(', '),
        plugins:      navigator.plugins?.length,
        hasChrome:    typeof window.chrome !== 'undefined',
        cpus:         navigator.hardwareConcurrency,
        screenW:      screen.width,
        screenH:      screen.height,
        availW:       screen.availWidth,
        availH:       screen.availHeight,
        dpr:          window.devicePixelRatio,
        webglRenderer: (() => { try { const c=document.createElement('canvas'); const g=c.getContext('webgl'); const ext=g.getExtension('WEBGL_debug_renderer_info'); return g.getParameter(ext.UNMASKED_RENDERER_WEBGL); } catch(e){ return 'error'; } })(),
    })).catch(() => ({}));

    console.log(`  navigator.webdriver = ${fp.webdriver}  ${fp.webdriver ? '🚨 DETECTADO como bot' : '✓ oculto'}`);
    console.log(`  userAgent           = ${fp.userAgent}`);
    console.log(`  platform            = ${fp.platform}`);
    console.log(`  languages           = ${fp.languages}`);
    console.log(`  plugins.length      = ${fp.plugins}  ${fp.plugins === 0 ? '⚠ 0 plugins' : '✓'}`);
    console.log(`  window.chrome       = ${fp.hasChrome ? '✓ presente' : '✗ ausente (red flag)'}`);
    console.log(`  hardwareConcurrency = ${fp.cpus}  (raw, sin patch)`);
    console.log(`  devicePixelRatio    = ${fp.dpr}`);
    console.log(`  screen              = ${fp.screenW}x${fp.screenH} (avail ${fp.availW}x${fp.availH})  (raw, sin patch)`);
    console.log(`  WebGL renderer      = ${fp.webglRenderer}`);

    // ── 4. Navegar a Instagram ────────────────────────────────────────────────
    console.log('\n[nav] Navegando a instagram.com...');
    try {
        await page.goto('https://www.instagram.com/', {
            waitUntil: 'domcontentloaded',
            timeout: 30_000,
        });
    } catch (e) {
        console.log(`[nav] ⚠ goto timeout/error: ${e.message}`);
    }
    await page.waitForTimeout(2500);

    // ── 5a. Fingerprint POST-navegación (con addInitScript aplicado) ──────────
    // Estos valores SÍ tienen los patches de realPcContext.js corriendo.
    // Si screen o CPU siguen mal aquí, el addInitScript no está funcionando.
    console.log('\n[fingerprint] PATCHED — post-navegación (addInitScript corrió):');
    const fp2 = await page.evaluate(() => ({
        webdriver:   navigator.webdriver,
        cpus:        navigator.hardwareConcurrency,
        screenW:     screen.width,
        screenH:     screen.height,
        availW:      screen.availWidth,
        availH:      screen.availHeight,
        dpr:         window.devicePixelRatio,
        webglRenderer: (() => { try { const c=document.createElement('canvas'); const g=c.getContext('webgl'); const ext=g.getExtension('WEBGL_debug_renderer_info'); return g.getParameter(ext.UNMASKED_RENDERER_WEBGL); } catch(e){ return 'error'; } })(),
    })).catch(() => ({}));
    const screenPatched = fp2.screenW <= 1920;
    console.log(`  navigator.webdriver = ${fp2.webdriver}  ${fp2.webdriver ? '🚨 AÚN DETECTADO (--disable-blink-features no aplicó o patch JS falló)' : '✓ oculto (undefined)'}`);
    console.log(`  hardwareConcurrency = ${fp2.cpus}  ${fp2.cpus === fp.cpus ? '⚠ sin cambios (patch no corrió o ya era correcto)' : `✓ corregido de ${fp.cpus}`}`);
    console.log(`  devicePixelRatio    = ${fp2.dpr}`);
    console.log(`  screen              = ${fp2.screenW}x${fp2.screenH} (avail ${fp2.availW}x${fp2.availH})  ${screenPatched ? '✓ en rango CSS' : `⚠ sigue en píxeles físicos (dpr=${fp2.dpr}, avail=${fp2.availW})`}`);
    console.log(`  WebGL renderer      = ${fp2.webglRenderer}`);

    // ── 5. Detectar estado de la página ──────────────────────────────────────
    const state = await page.evaluate(() => {
        const url  = location.href;
        const body = document.body?.innerText || '';

        const hasCaptcha = !!(
            document.querySelector('iframe[src*="recaptcha"]') ||
            document.querySelector('iframe[src*="captcha"]') ||
            document.querySelector('[class*="captcha" i]') ||
            body.match(/captcha|no eres un robot|not a robot|verificación de seguridad/i)
        );
        const hasChallenge = url.includes('/challenge') || url.includes('/checkpoint');
        const hasLogin = !!(
            document.querySelector('input[name="username"]') ||
            document.querySelector('input[aria-label*="usuario" i]') ||
            document.querySelector('input[aria-label*="username" i]')
        );
        const hasHome = !!(
            document.querySelector('svg[aria-label*="Home" i]') ||
            document.querySelector('svg[aria-label*="Inicio" i]') ||
            document.querySelector('a[href="/direct/inbox/"]')
        );

        return {
            url,
            title:        document.title.slice(0, 70),
            hasCaptcha,
            hasChallenge,
            hasLogin,
            hasHome,
            statusCode:   null, // no disponible desde JS
        };
    }).catch(e => ({ url: 'error', title: e.message, hasCaptcha: false, hasChallenge: false, hasLogin: false, hasHome: false }));

    console.log('\n[resultado]');
    console.log(`  URL:       ${state.url}`);
    console.log(`  Título:    ${state.title}`);
    console.log('');
    if (state.hasCaptcha)   console.log('  🚨 CAPTCHA detectado en la página');
    if (state.hasChallenge) console.log('  🚨 CHECKPOINT / challenge detectado');
    if (state.hasLogin)     console.log('  → Pantalla de login (normal, hay que iniciar sesión)');
    if (state.hasHome)      console.log('  ✓ Ya logueado (home visible)');
    if (!state.hasCaptcha && !state.hasChallenge && !state.hasLogin && !state.hasHome)
        console.log('  ? Estado desconocido — revisá el navegador');

    // ── 6. Cookies actuales en el contexto ────────────────────────────────────
    const cookies = await context.cookies('https://www.instagram.com').catch(() => []);
    const igCookies = cookies.filter(c => ['ig_did','mid','datr','sessionid','csrftoken','ig_nrcb'].includes(c.name));
    console.log(`\n[cookies en contexto] (${cookies.length} total)`);
    if (igCookies.length === 0) {
        console.log('  (ninguna cookie relevante de instagram.com)');
    }
    for (const c of igCookies) {
        const preview = c.value ? c.value.slice(0, 14) + '…' : '(vacío)';
        const tag = c.name === 'ig_did' ? ' 🔑 DEVICE ID' : c.name === 'sessionid' ? ' 🔐 SESIÓN' : '';
        console.log(`  ${c.name.padEnd(14)} ${preview}${tag}`);
    }

    // ── 7. Comparativa ───────────────────────────────────────────────────────
    console.log('\n' + '─'.repeat(55));
    console.log('  Para comparar, corrés:');
    if (!usePlain)  console.log('  node scripts/test-login.js --playwright           (sin anti-detect)');
    if (usePlain)   console.log('  node scripts/test-login.js                        (CloakBrowser)');
    if (!noCookies) console.log('  node scripts/test-login.js --no-cookies           (sin ig_did)');
    console.log('─'.repeat(55));
    console.log('\n  Navegador abierto. Cerralo cuando termines (o Ctrl+C).\n');

    // Esperar hasta que el usuario cierre
    await new Promise(resolve => {
        const cleanup = async () => {
            await context.close().catch(() => {});
            fs.rmSync(tmpDir, { recursive: true, force: true });
            resolve();
        };
        page.on('close',    () => cleanup());
        context.on('close', () => cleanup());
        process.on('SIGINT', () => { console.log('\n[exit] Cerrando...'); cleanup(); });
    });
}

main().catch(e => {
    console.error('\n✗ Error fatal:', e.message);
    console.error(e.stack?.split('\n').slice(1, 4).join('\n'));
    process.exit(1);
});
