const fs = require('fs');
const path = require('path');
const puppeteer = require('puppeteer-extra');
const StealthPlugin = require('puppeteer-extra-plugin-stealth');
puppeteer.use(StealthPlugin());

const { loadConfig, loadSitesFromFile } = require('./src/config');
const { processSite } = require('./src/processor');
const { createCLI, parseCLI } = require('./src/cli');

async function main() {
    const cliOptions = parseCLI();
    
    if (cliOptions.help) {
        createCLI().help();
        return;
    }
    
    const config = loadConfig();
    let sitesToProcess = config.sites || [];
    
    if (cliOptions.file) {
        console.log(`Loading sites from: ${cliOptions.file}`);
        sitesToProcess = loadSitesFromFile(cliOptions.file);
        console.log(`Loaded ${sitesToProcess.length} sites from file`);
    }
    
    const logFile = cliOptions.log ? path.join(__dirname, `run_${new Date().toISOString().replace(/[:.]/g, '-')}.log`) : null;
    
    if (cliOptions.target) {
        sitesToProcess = sitesToProcess.filter(site => 
            site.name.toLowerCase().includes(cliOptions.target.toLowerCase()) ||
            site.url.toLowerCase().includes(cliOptions.target.toLowerCase())
        );
        if (sitesToProcess.length === 0) {
            console.error(`No site found matching "${cliOptions.target}"`);
            return;
        }
        console.log(`Targeting ${sitesToProcess.length} site(s)`);
    }
    
    if (cliOptions.keepOpen) {
        console.log('Keep-open mode: Tabs will stay open for verification');
    }
    
    const browserConfig = config.browser || {};
    const globalCreds = config.global_credentials || {};
    const userDataDir = browserConfig.userDataDir;

    if (!userDataDir) {
        console.error('userDataDir not set in config.toml');
        return;
    }
    
    if (cliOptions.log && logFile) {
        const originalLog = console.log;
        const originalError = console.error;
        const originalWarn = console.warn;
        
        const writeToLog = (type, args) => {
            const message = args.map(arg => typeof arg === 'string' ? arg : JSON.stringify(arg)).join(' ');
            fs.appendFileSync(logFile, `[${new Date().toISOString()}] [${type}] ${message}\n`);
        };
        
        console.log = (...args) => { writeToLog('LOG', args); originalLog.apply(console, args); };
        console.error = (...args) => { writeToLog('ERROR', args); originalError.apply(console, args); };
        console.warn = (...args) => { writeToLog('WARN', args); originalWarn.apply(console, args); };
        console.log(`Logging to: ${logFile}`);
    }
    
    const failedSites = [];
    const processedCount = { success: 0, failed: 0 };
    
    const browser = await puppeteer.launch({
        headless: false,
        userDataDir: userDataDir,
        args: ['--start-maximized', '--no-sandbox', '--disable-setuid-sandbox']
    });

    try {
        console.log(`\nProcessing ${sitesToProcess.length} sites...\n`);
        
        for (let i = 0; i < sitesToProcess.length; i++) {
            const site = sitesToProcess[i];
            console.log(`[${i + 1}/${sitesToProcess.length}]`);
            
            const result = await processSite(browser, site, globalCreds, browserConfig, cliOptions.keepOpen, cliOptions.dryRun);
            
            if (result.siteFailed) {
                failedSites.push({
                    name: site.name,
                    url: site.url,
                    reason: result.failureReason,
                    timestamp: new Date().toISOString()
                });
                processedCount.failed++;
            } else {
                processedCount.success++;
            }
            
            await new Promise(r => setTimeout(r, 1000));
        }
        
        console.log(`\n${'='.repeat(70)}`);
        console.log(`Done: ${processedCount.success} success, ${processedCount.failed} failed`);
        
    } catch(error) {
        console.error('Fatal error:', error.message);
    } finally {
        if (cliOptions.keepOpen) {
            console.log(`\nBrowser kept open for verification`);
            console.log(`   Close browser manually when done`);
        } else {
            await browser.close();
        }
        
        if (failedSites.length > 0) {
            const reportPath = path.join(__dirname, 'failed_sites.txt');
            const now = new Date();
            const dateStr = now.toLocaleDateString('en-GB');
            const timeStr = now.toLocaleTimeString('en-GB');
            
            let reportContent = '';
            if (!fs.existsSync(reportPath)) {
                reportContent = 'DATE       | TIME     | WEBSITE                          | REASON\n';
                reportContent += '-'.repeat(100) + '\n';
            }
            
            for (const site of failedSites) {
                const website = `${site.name} (${site.url})`.substring(0, 32).padEnd(32);
                reportContent += `${dateStr} | ${timeStr} | ${website} | ${site.reason}\n`;
            }
            
            fs.appendFileSync(reportPath, reportContent);
            console.log(`${failedSites.length} failed. See: failed_sites.txt`);
        }
    }
}

main();
