const db = require('../db');
const { sendEmail } = require('../utils/emailService');

const cleanValue = (val) => {
    try {
        if (typeof val === 'string') {
            if (val.toLowerCase() === 'true') return true;
            if (val.toLowerCase() === 'false') return false;
            if (val.startsWith('"')) {
                return JSON.parse(val);
            }
        }
    } catch (e) {
        // ignore
    }
    return val;
};

exports.getPublicConfig = async (req, res) => {
    try {
        const result = await db.query(
"SELECT `key`, value FROM system_settings WHERE `key` IN ('stripe_publishable_key', 'stripe_price_monthly', 'stripe_price_yearly', 'stripe_price_display_monthly', 'stripe_price_display_yearly', 'stripe_price_original_monthly', 'stripe_price_original_yearly', 'free_tier_limit', 'plan_free_name', 'plan_monthly_name', 'plan_yearly_name', 'hide_tiers', 'site_title', 'site_description', 'site_keywords', 'og_image', 'twitter_handle', 'tier_small_price', 'tier_medium_price', 'tier_large_price', 'tier_small_stripe_id', 'tier_medium_stripe_id', 'tier_large_stripe_id', 'tier_small_stripe_id_yearly', 'tier_medium_stripe_id_yearly', 'tier_large_stripe_id_yearly', 'google_analytics_id', 'google_enabled', 'google_client_id', 'linkedin_enabled', 'linkedin_client_id')"
        );

        const config = {};
        result.rows.forEach(row => {
            config[row.key] = cleanValue(row.value);
        });

        res.json(config);
    } catch (error) {
        console.error(error);
        res.status(500).json({ message: 'Server error' });
    }
};

exports.getSettings = async (req, res) => {
    try {
        const result = await db.query('SELECT * FROM system_settings ORDER BY category, `key`');
        const settings = {};

        result.rows.forEach(row => {
            if (!settings[row.category]) {
                settings[row.category] = {};
            }
            settings[row.category][row.key] = cleanValue(row.value);
        });

        res.json(settings);
    } catch (error) {
        console.error(error);
        res.status(500).json({ message: 'Server error' });
    }
};

exports.updateSettings = async (req, res) => {
    // Handle both wrapped { settings: {...} } and direct {...} formats
    const settings = req.body.settings || req.body;

    // Validate settings object
    if (!settings || typeof settings !== 'object') {
        return res.status(400).json({ message: 'Invalid settings format received' });
    }

    const client = await db.pool.getConnection(); // Use a dedicated client for transaction

    try {
        await client.query('BEGIN');

        for (const category in settings) {
            // Skip non-object properties (like tokens or generic keys)
            if (!settings[category] || typeof settings[category] !== 'object') continue;

            for (const key in settings[category]) {
                let rawValue = settings[category][key];

                // Skip if value is undefined
                if (rawValue === undefined) continue;

                // Ensure we store it as a valid JSON string
                const value = JSON.stringify(rawValue);

                await client.query(
                    `INSERT INTO system_settings (\`key\`, value, category, updated_at) 
                     VALUES (?, ?, ?, NOW()) 
                     ON DUPLICATE KEY UPDATE value = VALUES(value), updated_at = NOW()`,
                    [key, value, category]
                );
            }
        }

        await client.query('COMMIT');
        res.json({ message: 'Settings updated successfully' });
    } catch (error) {
        await client.query('ROLLBACK');
        console.error('Error updating settings:', error);
        res.status(500).json({ message: 'Server error updating settings', details: error.message });
    } finally {
        client.release();
    }
};

exports.testEmail = async (req, res) => {
    const { to } = req.body;
    try {
        const info = await sendEmail(to, 'Test Email from InfoSec Labs', '<h1>It Works!</h1><p>This is a test email to verify your SMTP settings.</p>');
        if (info) {
            res.json({ message: 'Test email sent successfully', messageId: info.messageId });
        } else {
            res.status(500).json({ message: 'Failed to send test email. Check server logs.' });
        }
    } catch (error) {
        console.error(error);
        res.status(500).json({ message: 'Server error: ' + error.message, details: error.toString() });
    }
};

exports.createStripePrice = async (req, res) => {
    const { amount, interval, productName } = req.body;

    try {
        // Fetch Secret Key
        const settingsResult = await db.query("SELECT value FROM system_settings WHERE `key` = 'stripe_secret_key' AND category = 'payment'");
        let secretKey = settingsResult.rows[0]?.value;

        if (!secretKey) {
            // Fallback to env
            secretKey = process.env.STRIPE_SECRET_KEY;
        } else {
            // Handle potential JSON stringification from system_settings
            try {
                if (secretKey.startsWith('"')) secretKey = JSON.parse(secretKey);
            } catch (e) {
                // ignore, usage as raw string
            }
        }

        if (!secretKey) {
            return res.status(400).json({ message: 'Stripe Secret Key not found in settings' });
        }

        const stripe = require('stripe')(secretKey);

        const price = await stripe.prices.create({
            unit_amount: Math.round(amount * 100), // Convert to cents
            currency: 'usd',
            recurring: { interval: interval }, // 'month' or 'year'
            product_data: {
                name: productName || `Pro Plan (${interval})`,
            },
        });

        const displayPrice = `$${amount}`;

        // Auto-update the display price in settings based on interval
        const displayKey = interval === 'month' ? 'stripe_price_display_monthly' : 'stripe_price_display_yearly';
        const priceKey = interval === 'month' ? 'stripe_price_monthly' : 'stripe_price_yearly';

        // Save Display Price
        await db.query(
            `INSERT INTO system_settings (\`key\`, value, category, updated_at) 
             VALUES (?, ?, 'payment', NOW()) 
             ON DUPLICATE KEY UPDATE value = VALUES(value), updated_at = NOW()`,
            [displayKey, JSON.stringify(displayPrice)]
        );

        // Save Price ID (Clean String)
        await db.query(
            `INSERT INTO system_settings (\`key\`, value, category, updated_at) 
             VALUES (?, ?, 'payment', NOW()) 
             ON DUPLICATE KEY UPDATE value = VALUES(value), updated_at = NOW()`,
            [priceKey, JSON.stringify(price.id)]
        );

        res.json({
            priceId: price.id,
            displayPrice: displayPrice
        });

    } catch (error) {
        console.error('Error creating Stripe price:', error);
        res.status(500).json({ message: error.message || 'Failed to create price' });
    }
};

exports.getSeoPages = async (req, res) => {
    try {
        const result = await db.query('SELECT * FROM seo_metadata ORDER BY route');
        res.json(result.rows || []);
    } catch (error) {
        console.error('Error fetching SEO pages:', error);
        res.status(500).json({ message: 'Server error' });
    }
};

exports.updateSeoPage = async (req, res) => {
    const { route, title, description, keywords, og_image } = req.body;
    if (!route) return res.status(400).json({ message: 'Route is required' });

    try {
        await db.query(
            `INSERT INTO seo_metadata (route, title, description, keywords, og_image, updated_at)
             VALUES (?, ?, ?, ?, ?, NOW())
             ON DUPLICATE KEY UPDATE 
                title = VALUES(title), 
                description = VALUES(description), 
                keywords = VALUES(keywords), 
                og_image = VALUES(og_image), 
                updated_at = NOW()`,
            [route, title, description, keywords, og_image]
        );
        res.json({ message: 'SEO metadata updated successfully' });
    } catch (error) {
        console.error('Error updating SEO page:', error);
        res.status(500).json({ message: 'Server error' });
    }
};

exports.pingSitemap = async (req, res) => {
    try {
        const https = require('https');
        https.get('https://www.google.com/ping?sitemap=https://infoseclabs.io/sitemap.xml', (resp) => {
            if (resp.statusCode >= 200 && resp.statusCode < 300) {
                res.json({ message: 'Google accepted the sitemap ping.' });
            } else {
                res.status(resp.statusCode).json({ message: 'Google returned an error.', code: resp.statusCode });
            }
        }).on("error", (err) => {
            res.status(500).json({ message: 'Failed to ping Google.', error: err.message });
        });
    } catch (error) {
        console.error('Error pinging sitemap:', error);
        res.status(500).json({ message: 'Server error' });
    }
};

exports.exportUsers = async (req, res) => {
    try {
        const result = await db.query('SELECT id, username, email, role, created_at FROM users');
        const csv = 'id,username,email,role,created_at\n' + result.rows.map(r => `${r.id},"${r.username}","${r.email}","${r.role}","${r.created_at}"`).join('\n');
        res.setHeader('Content-Type', 'text/csv');
        res.setHeader('Content-Disposition', 'attachment; filename="infoseclabs_users.csv"');
        res.send(csv);
    } catch (error) {
        console.error('Error exporting users:', error);
        res.status(500).json({ message: 'Server error during export' });
    }
};

exports.exportInvestigations = async (req, res) => {
    try {
        const result = await db.query('SELECT id, user_id, alert_id, status, grade, created_at FROM investigations');
        const csv = 'id,user_id,alert_id,status,grade,created_at\n' + result.rows.map(r => `${r.id},${r.user_id},${r.alert_id},"${r.status}","${r.grade || ''}","${r.created_at}"`).join('\n');
        res.setHeader('Content-Type', 'text/csv');
        res.setHeader('Content-Disposition', 'attachment; filename="infoseclabs_investigations.csv"');
        res.send(csv);
    } catch (error) {
        console.error('Error exporting investigations:', error);
        res.status(500).json({ message: 'Server error during export' });
    }
};

exports.getAuditLogs = async (req, res) => {
    try {
        await db.query(`
            CREATE TABLE IF NOT EXISTS system_audit_logs (
                id INT AUTO_INCREMENT PRIMARY KEY,
                user_id INT,
                action VARCHAR(255),
                details TEXT,
                ip_address VARCHAR(45),
                created_at DATETIME DEFAULT CURRENT_TIMESTAMP
            )
        `);
        const result = await db.query('SELECT a.*, u.username, u.email FROM system_audit_logs a LEFT JOIN users u ON a.user_id = u.id ORDER BY a.created_at DESC LIMIT 100');
        res.json(result.rows || []);
    } catch (error) {
        console.error('Error fetching audit logs:', error);
        res.status(500).json({ message: 'Server error fetching logs' });
    }
};
