const db = require('../db');

/**
 * Basic SQL Parser for SIEM Log Queries
 * Converts: src_ip=10.0.0.5 action=blocked
 * To: WHERE raw_data LIKE '%src_ip=10.0.0.5%' AND raw_data LIKE '%action=blocked%'
 */
const parseThreatQuery = (queryStr) => {
    if (!queryStr || queryStr.trim() === '' || queryStr.trim() === '*') return { sql: '', params: [] };
    
    // Split by spaces, trying not to split inside quotes (basic implementation)
    const tokens = queryStr.match(/(?:[^\s"]+|"[^"]*")+/g) || [];
    
    let conditions = [];
    let params = [];
    
    tokens.forEach(token => {
        // Strip quotes
        token = token.replace(/(^"|"$)/g, '');
        
        // Handle key=value
        if (token.includes('=')) {
            const [key, value] = token.split('=');
            conditions.push(`JSON_EXTRACT(raw_data, '$."${key}"') = ? OR raw_data LIKE ?`);
            params.push(value);
            params.push(`%${value}%`);
        } else {
            // Free text search across the JSON body and basic columns
            conditions.push(`(raw_data LIKE ? OR source_ip LIKE ? OR dest_ip LIKE ? OR event_type LIKE ?)`);
            const likeStr = `%${token}%`;
            params.push(likeStr, likeStr, likeStr, likeStr);
        }
    });

    if (conditions.length === 0) return { sql: '', params: [] };

    return {
        sql: 'WHERE ' + conditions.join(' AND '),
        params: params
    };
};

exports.searchLogs = async (req, res) => {
    try {
        const { query, timeRange = '24h', limit = 50, page = 1 } = req.body;
        
        const { sql: whereClause, params } = parseThreatQuery(query);
        
        // Time parsing
        let timeCondition = '';
        if (timeRange === '24h') {
            timeCondition = 'timestamp >= DATE_SUB(NOW(), INTERVAL 24 HOUR)';
        } else if (timeRange === '7d') {
            timeCondition = 'timestamp >= DATE_SUB(NOW(), INTERVAL 7 DAY)';
        } else if (timeRange === '30d') {
            timeCondition = 'timestamp >= DATE_SUB(NOW(), INTERVAL 30 DAY)';
        } else {
            timeCondition = '1=1'; // All time
        }

        const finalWhere = whereClause 
            ? `${whereClause} AND ${timeCondition}` 
            : `WHERE ${timeCondition}`;

        // Add index_name filter if provided in query explicitly, or just search all
        const maxLimit = Math.min(parseInt(limit) || 50, 500);
        const currentPage = Math.max(parseInt(page) || 1, 1);
        const offset = (currentPage - 1) * maxLimit;

        // Get total count for pagination
        const countSql = `
            SELECT COUNT(*) as total
            FROM simulated_logs 
            ${finalWhere}
        `;
        const countResult = await db.query(countSql, params);
        const totalLogs = countResult.rows[0].total;

        const sql = `
            SELECT id, timestamp, source_ip, dest_ip, event_type, action, raw_data, index_name 
            FROM simulated_logs 
            ${finalWhere}
            ORDER BY timestamp DESC 
            LIMIT ? OFFSET ?
        `;
        
        // Add limit and offset to params
        const finalParams = [...params, maxLimit, offset];

        // Ensure we are simulating the 'processing time' to make it feel like real SIEM querying
        // Introduce a slight delay between 500ms to 2000ms based on query complexity
        const delayMs = Math.floor(Math.random() * 1500) + 500;
        await new Promise(resolve => setTimeout(resolve, delayMs));

        const result = await db.query(sql, finalParams);

        res.json({
            success: true,
            count: result.rows.length,
            total: totalLogs,
            page: currentPage,
            totalPages: Math.ceil(totalLogs / maxLimit),
            logs: result.rows,
            query_parsed: whereClause || 'ALL'
        });

    } catch (error) {
        console.error('Error searching logs:', error);
        res.status(500).json({ success: false, message: 'Failed to execute threat hunt query.', error: error.message });
    }
};

exports.getIndexes = async (req, res) => {
    try {
        const result = await db.query(`SELECT DISTINCT index_name FROM simulated_logs`);
        const indexes = result.rows.map(r => r.index_name);
        res.json({ success: true, indexes });
    } catch (error) {
        console.error('Error fetching indexes:', error);
        res.status(500).json({ success: false, message: 'Failed to fetch indexes.' });
    }
};
