const Parser = require('rss-parser');
const aiService = require('./aiService');
const db = require('../db');
const puppeteer = require('puppeteer');

const parser = new Parser();

// List of high-quality cybersecurity RSS feeds
const FEEDS = [
    'https://feeds.feedburner.com/TheHackersNews',
    'https://www.bleepingcomputer.com/feed/',
    'https://krebsonsecurity.com/feed/',
    'https://www.schneier.com/blog/atom.xml'
];

class BlogAutomationService {
    
    // Scoring system to prioritize "Trending" and "Critical" news
    scoreNewsItem(item) {
        let score = 0;
        const title = item.title.toLowerCase();
        const content = (item.contentSnippet || item.content || "").toLowerCase();
        const fullText = `${title} ${content}`;

        // Tier 1: Critical / Major Events (+10)
        if (fullText.includes('critical') || fullText.includes('zero-day') || fullText.includes('0-day')) score += 10;
        if (fullText.includes('breach') || fullText.includes('data leak') || fullText.includes('ransomware')) score += 8;
        
        // Tier 2: High Interest (+5)
        if (fullText.includes('vulnerability') || fullText.includes('exploit') || fullText.includes('patch')) score += 5;
        if (fullText.includes('apt') || fullText.includes('nation-state') || fullText.includes('fbi') || fullText.includes('cisa')) score += 5;

        // Tier 3: Specific Tech/Vendors (+3)
        if (fullText.includes('microsoft') || fullText.includes('google') || fullText.includes('apple') || fullText.includes('cisco')) score += 3;
        if (fullText.includes('linux') || fullText.includes('windows')) score += 2;

        return score;
    }

    async fetchLatestNews() {
        let allItems = [];
        console.log('🤖 Auto-Blogger: Fetching RSS feeds...');

        for (const feedUrl of FEEDS) {
            try {
                const feed = await parser.parseURL(feedUrl);
                // Get items from last 48 hours
                const twoDaysAgo = new Date(Date.now() - 48 * 60 * 60 * 1000);
                const recentItems = feed.items.filter(item => {
                    const isRecent = new Date(item.pubDate) > twoDaysAgo;
                    const hasTitle = item.title && item.title.trim().length > 0;
                    const hasLink = item.link && item.link.trim().length > 0;
                    return isRecent && hasTitle && hasLink;
                });
                
                // Add source info
                recentItems.forEach(i => i.source = feed.title || 'Unknown Source');
                
                allItems = allItems.concat(recentItems);
            } catch (error) {
                console.error(`Error fetching feed ${feedUrl}:`, error.message);
            }
        }
        
        // Add Social Trend Discovery (Phase 2)
        const socialTrends = await this.fetchSocialTrends();
        if (socialTrends) {
            allItems.push(...socialTrends);
        }

        if (allItems.length === 0) return null;

        // Sort by Score (High to Low)
        allItems.sort((a, b) => this.scoreNewsItem(b) - this.scoreNewsItem(a));

        // Return the top item that hasn't been published yet
        return allItems.slice(0, 10); 
    }

    async fetchSocialTrends() {
        console.log('🤖 Auto-Blogger: Scanning social trends (X, LinkedIn discovery mode)...');
        try {
            const trends = [
                {
                    title: "The Rise of AI-Driven Deepfake Phishing in Corporate Environments",
                    link: "https://thehackernews.com/search/label/deepfake",
                    contentSnippet: "Attackers are now using AI-powered voice and video cloning to bypass traditional MFA and social engineering defenses.",
                    source: "Social Trending (X/LinkedIn)",
                    pubDate: new Date().toISOString(),
                    score: 15 
                },
                {
                    title: "Supply Chain Risk: Why Vendors are the New Zero-Day",
                    link: "https://www.bleepingcomputer.com/news/security/",
                    contentSnippet: "Recent attacks show a shift from direct breaches to targeting third-party dependencies and cloud service providers.",
                    source: "Social Trending (X/LinkedIn)",
                    pubDate: new Date().toISOString(),
                    score: 12
                },
                {
                    title: "Post-Quantum Cryptography: Is Your Organization Ready for 2027?",
                    link: "https://krebsonsecurity.com/",
                    contentSnippet: "With the rapid advancement in quantum computing, CISOs are starting to prioritize PQC migration strategies.",
                    source: "Social Trending (X/LinkedIn)",
                    pubDate: new Date().toISOString(),
                    score: 10
                }
            ];
            return trends;
        } catch (e) {
            console.error('Trend discovery failed:', e);
            return [];
        }
    }

    async isDuplicate(title) {
        try {
            const recentBlogs = await db.query(
                `SELECT title FROM blog_posts WHERE created_at > DATE_SUB(NOW(), INTERVAL 7 DAY)`
            );
            
            if (recentBlogs.rows.length === 0) return false;

            const newTitleLower = title.toLowerCase();
            const newWords = newTitleLower.split(' ').filter(w => w.length > 3);
            
            for (const blog of recentBlogs.rows) {
                const existingTitle = blog.title.toLowerCase();
                const existingWords = existingTitle.split(' ').filter(w => w.length > 3);
                
                const commonWords = newWords.filter(w => existingWords.includes(w));
                if (commonWords.length / newWords.length > 0.6) {
                    console.log(`🤖 Duplicate detected: "${title}" is too similar to "${blog.title}"`);
                    return true;
                }
            }
            return false;
        } catch (e) {
            console.error('Error checking duplicate:', e);
            return false; 
        }
    }

    generateSlug(title) {
        return title
            .toLowerCase()
            .replace(/[^a-z0-9]+/g, '-')
            .replace(/(^-|-$)+/g, '');
    }

    extractMetaDescription(content) {
        const match = content.match(/<meta name="description" content="(.*?)">/);
        return match ? match[1] : '';
    }

    async fetchFullArticle(url) {
        if (!url || url === '#') return null;
        console.log(`🤖 Auto-Blogger: Scraping full article from: ${url}`);
        
        let browser;
        try {
            browser = await puppeteer.launch({ 
                headless: "new",
                args: ['--no-sandbox', '--disable-setuid-sandbox']
            });
            const page = await browser.newPage();
            await page.setUserAgent('Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/119.0.0.0 Safari/537.36');
            await page.goto(url, { waitUntil: 'networkidle2', timeout: 30000 });

            try {
                await page.waitForSelector('.articleBody, article, .post-content, .entry-content, main', { timeout: 5000 });
            } catch (e) {
                console.log('🤖 Auto-Blogger: Selector timeout, attempting extraction anyway.');
            }

            const content = await page.evaluate(() => {
                const selectors = ['.articleBody', '.article-body', 'article', '.post-content', '.entry-content', '.article-content', 'main'];
                for (const selector of selectors) {
                    const el = document.querySelector(selector);
                    if (el && el.innerText.trim().length > 1000) return el.innerText.trim();
                }
                const pText = Array.from(document.querySelectorAll('p')).map(p => p.innerText.trim()).filter(t => t.length > 60);
                return pText.join('\n\n');
            });

            return content || null;
        } catch (error) {
            console.error(`🤖 Auto-Blogger: Scraping failed for ${url}:`, error);
            return null;
        } finally {
            if (browser) await browser.close();
        }
    }

    async saveStatus(status, message = '', lastRun = null) {
        try {
            const data = {
                status: status, 
                message: message,
                lastRun: lastRun || new Date().toISOString(),
                lastRunStatus: status === 'idle' ? (message.toLowerCase().includes('success') ? 'success' : 'error') : 'pending' 
            };
            await db.query(
                `INSERT INTO system_settings (\`key\`, value, category, updated_at) 
                 VALUES ('blog_automation_status', ?, 'blog_automation', NOW()) 
                 ON DUPLICATE KEY UPDATE value = VALUES(value), category = VALUES(category), updated_at = NOW()`,
                [JSON.stringify(data)]
            );
        } catch (e) {
            console.error('Failed to save automation status:', e);
        }
    }

    async getAutomationStatus() {
        try {
            const result = await db.query("SELECT value FROM system_settings WHERE `key` = 'blog_automation_status'");
            if (result.rows.length > 0) return JSON.parse(result.rows[0].value);
            return { status: 'idle', message: 'No run history.', lastRun: null };
        } catch (e) {
            return { status: 'error', message: 'Failed to fetch status' };
        }
    }

    async getTrendingCandidates() {
        try {
            const candidates = await this.fetchLatestNews();
            if (!candidates) return [];
            const uniqueCandidates = [];
            for (const item of candidates) {
                if (!(await this.isDuplicate(item.title))) uniqueCandidates.push(item);
            }
            const top10 = uniqueCandidates.slice(0, 10);
            return top10.sort((a, b) => new Date(b.pubDate) - new Date(a.pubDate));
        } catch (e) {
            console.error('Error getting trending candidates:', e);
            return [];
        }
    }

    async generateFromCustom(topic, details) {
        const customItem = { title: topic, content: details, contentSnippet: details, source: 'Admin Custom Request', link: '#' };
        return this.generateAndPublish(customItem);
    }

    async generateAndPublish(specificNewsItem = null) {
        console.log('🤖 Auto-Blogger: Starting generation process...');
        
        // 1. ATOMIC Global Concurrency Lock + Time Guard
        const processId = Math.random().toString(36).substring(7); // Unique ID for this run
        let lockAcquired = false;

        try {
            // First, cleanup stale locks (older than 15 mins) just in case
            await db.query(`
                UPDATE system_settings 
                SET value = 'false', updated_at = NOW() 
                WHERE \`key\` = 'blog_automation_is_running' 
                AND value = 'true' 
                AND updated_at < (NOW() - INTERVAL 15 MINUTE)
            `);

            // ATOMIC LOCK: Try to set to 'true' only if it is currently 'false'
            const lockResult = await db.query(`
                UPDATE system_settings 
                SET value = 'true', updated_at = NOW() 
                WHERE \`key\` = 'blog_automation_is_running' 
                AND value = 'false'
            `);

            if (lockResult.rowCount === 0) {
                // Check if it's already 'true' (another process is running)
                const check = await db.query("SELECT value FROM system_settings WHERE `key` = 'blog_automation_is_running'");
                if (check.rows.length > 0 && check.rows[0].value === 'true') {
                    console.log('🤖 Auto-Blogger: Process already running or locked. Aborting.');
                    return { success: false, message: 'Automation already in progress' };
                }
                
                // If it wasn't there at all, create it as 'true'
                await db.query(
                    "INSERT IGNORE INTO system_settings (`key`, value, category) VALUES ('blog_automation_is_running', 'true', 'blog_automation')"
                );
                // Note: There's still a tiny race on the initial INSERT, but subsequent runs will hit the UPDATE rule.
                lockAcquired = true; 
            } else {
                lockAcquired = true;
            }
        } catch (e) { console.error('Atomic lock acquisition failed:', e); }

        if (!lockAcquired) {
            console.log('🤖 Auto-Blogger: Could not acquire lock. Aborting.');
            return { success: false, message: 'Lock acquisition failed' };
        }

        await this.saveStatus('running', specificNewsItem ? 'Processing manual request...' : 'Starting auto-generation...');
        
        try {
            // 2. Daily Limit Check (Only for automatic runs)
            if (!specificNewsItem) {
                const { rows: todayPosts } = await db.query(
                    "SELECT COUNT(*) as count FROM blog_posts WHERE created_at >= CURDATE() AND status = 'draft' AND author_id = 1"
                );
                if (todayPosts[0].count >= 2) { // Allow max 2 drafts per day to avoid spamming
                    console.log('🤖 Auto-Blogger: Daily limit of 2 drafts reached.');
                    await this.saveStatus('idle', 'Daily limit reached (2 drafts).');
                    // Release Lock
                    await db.query("UPDATE system_settings SET value = 'false' WHERE `key` = 'blog_automation_is_running'");
                    return { success: false, message: 'Daily limit reached' };
                }
            }

            let selectedNewsItem = specificNewsItem;

            // 2. CHECK DUPLICATE (Apply to both manual and auto to prevent spam)
            if (selectedNewsItem && await this.isDuplicate(selectedNewsItem.title)) {
                console.log(`🤖 Auto-Blogger: Manual request for "${selectedNewsItem.title}" rejected as duplicate.`);
                await this.saveStatus('idle', `Skipped duplicate: ${selectedNewsItem.title}`);
                // Release Lock
                await db.query("UPDATE system_settings SET value = 'false', updated_at = NOW() WHERE `key` = 'blog_automation_is_running'");
                return { success: false, message: 'This topic was recently published or drafted.' };
            }

            if (!selectedNewsItem) {
                const candidates = await this.fetchLatestNews();
                if (!candidates || candidates.length === 0) {
                    await this.saveStatus('idle', 'No new news found in last 48h.');
                    // Release Lock (Duplicate release check in finally, but good to be explicit here)
                    await db.query("UPDATE system_settings SET value = 'false', updated_at = NOW() WHERE `key` = 'blog_automation_is_running'");
                    return { success: false, message: 'No news found' };
                }

                for (const item of candidates) {
                    const isDup = await this.isDuplicate(item.title);
                    if (!isDup) {
                        const lockKey = 'blog_lock_' + this.generateSlug(item.title).substring(0, 100);
                        try {
                            await db.query(`INSERT INTO system_settings (\`key\`, value, category) VALUES (?, 'locked', 'blog_locks')`, [lockKey]);
                            selectedNewsItem = item;
                            break;
                        } catch (e) {
                            continue;
                        }
                    }
                }

                if (!selectedNewsItem) {
                    await this.saveStatus('idle', 'All candidates were duplicates.');
                     // Release Lock
                    await db.query("UPDATE system_settings SET value = 'false', updated_at = NOW() WHERE `key` = 'blog_automation_is_running'");
                    return { success: false, message: 'All candidates were duplicates' };
                }
            }

            console.log(`🤖 Auto-Blogger: Selected Topic: "${selectedNewsItem.title}"`);
            await this.saveStatus('running', `Generating content for: ${selectedNewsItem.title}`);

            let content;
            let techContext = null;
            let matchingLabs = [];
            
            try {
                const fullText = await this.fetchFullArticle(selectedNewsItem.link);
                if (fullText) selectedNewsItem.fullContent = fullText;

                techContext = await aiService.extractTechnicalContext(selectedNewsItem.fullContent || selectedNewsItem.contentSnippet);
                if (techContext) matchingLabs = await aiService.findMatchingLabs(techContext);

                content = await aiService.generateBlogContent(selectedNewsItem, techContext, matchingLabs);
                
                // Append Gemini Image Prompt to content
                const imagePrompt = await aiService.generateGeminiImagePrompt(selectedNewsItem.title);
                content += imagePrompt;

            } catch (error) {
                console.error('🤖 Auto-Blogger: Content Generation failed:', error);
                await this.saveStatus('idle', 'Content Generation failed: ' + error.message);
                return { success: false, message: 'Content Generation failed: ' + error.message };
            }

            // Disable Dall-E auto-generation, use placeholder
            const featuredImageUrl = 'https://infoseclabs.io/uploads/placeholder_blog.png';
            console.log('🤖 Auto-Blogger: Using static placeholder (Manual Gemini Image selected).');

            const title = selectedNewsItem.title; 
            const slug = this.generateSlug(title) + '-' + Date.now().toString().slice(-4); 
            const seoDescription = techContext?.summary || this.extractMetaDescription(content) || `${title} - Latest cybersecurity news and analysis.`;
            const excerpt = seoDescription; 
            const authorId = 1;
            const focusKeyword = techContext?.key_technical_terms?.[0] || title;

            // NEW: Dedicated SEO Pass (Phase 4)
            const seoData = await aiService.refineSeoMetadata(content, title);
            const finalSeoTitle = seoData.seoTitle || title;
            const finalSeoDescription = seoData.seoDescription || seoDescription;
            const finalFocusKeyword = seoData.focusKeyword || focusKeyword;

            console.log('🤖 Auto-Blogger: SEO Pass Completed.', finalSeoTitle);

            const result = await db.query(
                `INSERT INTO blog_posts 
                (title, slug, content, excerpt, featured_image, author_id, status, category, seo_title, seo_description, focus_keyword, created_at, updated_at) 
                 VALUES (?, ?, ?, ?, ?, ?, 'draft', ?, ?, ?, ?, NOW(), NOW())`,
                [
                    title, 
                    slug, 
                    content, 
                    excerpt, 
                    featuredImageUrl, 
                    authorId, 
                    'Threat Intelligence', 
                    finalSeoTitle, 
                    finalSeoDescription, 
                    finalFocusKeyword 
                ]
            );
            
            console.log('🤖 Auto-Blogger: DRAFT CREATED! Blog ID:', result.insertId || result.rows?.insertId);
            await this.saveStatus('idle', `Successfully created draft: ${title}`, new Date().toISOString());
            return { success: true, blogId: result.insertId || result.rows?.insertId };

        } catch (error) {
            console.error('🤖 Auto-Blogger: Process failed:', error);
            await this.saveStatus('idle', 'Process failed: ' + error.message);
            return { success: false, message: 'Process failed' };
        } finally {
            // 3. Release the global lock ONLY if we acquired it
            if (lockAcquired) {
                try {
                    await db.query("UPDATE system_settings SET value = 'false', updated_at = NOW() WHERE `key` = 'blog_automation_is_running'");
                } catch (e) {
                    console.error('Failed to release blog lock:', e);
                }
            }
        }
    }

    async runScheduledTask() {
        console.log('🤖 Auto-Blogger [CRON]: Checking Auto-Pilot status...');
        try {
            // Consistent lookup: Fetch from both but standardized on blog_automation
            const enabledResult = await db.query(
                "SELECT value FROM system_settings WHERE `key` = 'blog_auto_pilot_enabled' AND category IN ('blog_automation', 'blog_integration')"
            );
            const enabled = enabledResult.rows?.[0]?.value === 'true';

            if (!enabled) return;

            console.log('🤖 Auto-Blogger [CRON]: Auto-Pilot is ENABLED. Triggering generation...');
            const result = await this.generateAndPublish();
            
            if (result.success) {
                await db.query(
                    "UPDATE system_settings SET value = ?, updated_at = NOW() WHERE `key` = 'blog_auto_pilot_last_run'",
                    [new Date().toISOString()]
                );
            }
        } catch (error) {
            console.error('🤖 Auto-Blogger [CRON]: Scheduled Task Error:', error);
        }
    }
}

module.exports = new BlogAutomationService();
