const openai = require('openai');
const db = require('../db');
const { generateCustomAlert } = require('../services/alertGenerator');

// Helper to get AI Key from database (Super Admin Settings) or fallback to .env
const getAIKey = async () => {
    try {
        const result = await db.query("SELECT value FROM system_settings WHERE `key` = 'ai_api_key'");
        let apiKey = result.rows[0]?.value || process.env.OPENAI_API_KEY;
        // Clean up JSON-encoded strings if needed
        if (apiKey && apiKey.startsWith('"')) {
            try { apiKey = JSON.parse(apiKey); } catch (e) {}
        }
        return apiKey;
    } catch (e) {
        console.log('[aiController] Failed to fetch API key from DB, falling back to .env');
        return process.env.OPENAI_API_KEY;
    }
};

/**
 * Generate a complete alert scenario with playbook_solution for grading
 * This uses the alertGenerator service for consistency
 */
const generateAlertScenario = async (req, res) => {
    try {
        const { title, alert_type, severity, difficulty, details, prompt } = req.body;

        // Support both old 'prompt' field and new structured fields
        const scenarioDetails = details || prompt;
        const scenarioTitle = title && title.trim() ? title.trim() : null; // Let AI generate title if not provided
        const scenarioType = alert_type || 'Phishing';
        const scenarioSeverity = severity || 'Medium';
        const scenarioDifficulty = difficulty || 'Intermediate';

        if (!scenarioDetails) {
            return res.status(400).json({ message: 'Scenario details/prompt is required' });
        }

        // Get API Key from database or environment
        const apiKey = await getAIKey();

        // MOCK MODE: If no API key is present
        if (!apiKey) {
            console.log('⚠️ No OPENAI_API_KEY found (DB or ENV). Using Mock AI Response.');
            
            await new Promise(resolve => setTimeout(resolve, 1500));

            // Generate mock response based on user input
            const mockResponse = {
                title: scenarioTitle,
                alert_type: scenarioType,
                difficulty: scenarioDifficulty,
                severity: scenarioSeverity,
                details: scenarioDetails,
                raw_log: JSON.stringify({
                    timestamp: new Date().toISOString(),
                    event_type: scenarioType.toLowerCase(),
                    source_ip: "192.168.1." + Math.floor(Math.random() * 255),
                    destination_ip: "10.0.0." + Math.floor(Math.random() * 255),
                    user: "analyst@company.com",
                    action: "alert_triggered",
                    description: scenarioDetails.substring(0, 200)
                }, null, 2),
                playbook_solution: {
                    playbook_version: 2,
                    artifacts: [
                        {
                            id: "artifact_1",
                            type: "ip",
                            value: "192.168.1.100",
                            is_critical: true,
                            osint_result: {
                                source: "Mock OSINT",
                                verdict: "suspicious",
                                details: "Mock mode - requires manual verification"
                            }
                        }
                    ],
                    expected_actions: ["investigate", "collect_forensics", "escalate"],
                    expected_verdict: "true_positive",
                    analysis_notes: "This is a mock response. Configure OpenAI API key in Super Admin settings for real AI generation."
                }
            };

            return res.json(mockResponse);
        }

        console.log('[aiController] Using OpenAI API for full alert generation with playbook_solution');

        // Use the alertGenerator service for complete alert generation
        try {
            const generatedAlert = await generateCustomAlert({
                title: scenarioTitle,
                severity: scenarioSeverity,
                alert_type: scenarioType,
                details: scenarioDetails,
                difficulty: scenarioDifficulty
            }, apiKey);

            // Generate a fallback title if AI didn't provide one
            const finalTitle = generatedAlert.title || scenarioTitle || 
                `${scenarioType}: ${scenarioDetails.substring(0, 50).trim()}...`;

            // Return the complete alert with playbook_solution
            res.json({
                title: finalTitle,
                alert_type: generatedAlert.alert_type || scenarioType,
                severity: generatedAlert.severity || scenarioSeverity,
                difficulty: generatedAlert.difficulty || scenarioDifficulty,
                details: generatedAlert.details || scenarioDetails,
                mitre_technique: generatedAlert.mitre_technique,
                raw_log: typeof generatedAlert.raw_log === 'string' 
                    ? generatedAlert.raw_log 
                    : JSON.stringify(generatedAlert.raw_log, null, 2),
                playbook_solution: generatedAlert.playbook_solution
            });

        } catch (genError) {
            console.error('[aiController] AlertGenerator failed, falling back to direct OpenAI:', genError.message);
            
            // Fallback: Direct OpenAI call with enhanced prompt
            const openaiClient = new openai.OpenAI({ apiKey });

            const completion = await openaiClient.chat.completions.create({
                messages: [
                    {
                        role: "system",
                        content: `You are a cybersecurity expert creating training scenarios for SOC analysts.
Generate a complete JSON alert based on the user's SPECIFIC scenario. 

CRITICAL: You MUST base the alert on the user's provided scenario description. Do NOT ignore their input.

Required JSON structure:
{
    "title": "${scenarioTitle ? scenarioTitle : 'GENERATE a professional, descriptive alert title (max 60 chars) based on the scenario. Examples: Phishing: Fake HR Portal Credential Harvest, Malware: Emotet Dropper via Macro Document'}",
    "alert_type": "${scenarioType}",
    "severity": "${scenarioSeverity}",
    "difficulty": "${scenarioDifficulty}",
    "details": "Professional description based on user input",
    "mitre_technique": "Txxxx",
    "raw_log": { realistic log matching the scenario },
    "playbook_solution": {
        "playbook_version": 2,
        "artifacts": [
            {
                "id": "artifact_1",
                "type": "ip|hash|domain|url|email|filename|username",
                "value": "exact value from raw_log",
                "is_critical": true/false,
                "osint_result": {
                    "source": "VirusTotal|AbuseIPDB|etc",
                    "verdict": "malicious|suspicious|clean",
                    "details": "Analysis details"
                }
            }
        ],
        "expected_actions": ["block_ip", "isolate_host", "reset_credentials", "escalate", "close_alert"],
        "expected_verdict": "true_positive|false_positive|benign",
        "analysis_notes": "Brief explanation of findings"
    }
}

RULES:
1. All artifact values in playbook_solution MUST exist exactly in raw_log
2. Generate realistic, detailed raw_log that matches the scenario
3. ${scenarioTitle ? `Use the exact title: "${scenarioTitle}"` : 'Create a concise, professional alert title that describes the threat'}
4. Ensure response is valid JSON only, no markdown`
                    },
                    { 
                        role: "user", 
                        content: `Generate a training alert based on this scenario:
                        
${scenarioTitle ? `Title: ${scenarioTitle}` : 'Title: (Generate a descriptive title based on the scenario below)'}
Type: ${scenarioType}
Severity: ${scenarioSeverity}
Difficulty: ${scenarioDifficulty}

Scenario Description:
${scenarioDetails}` 
                    }
                ],
                model: "gpt-4o-mini",
                response_format: { type: "json_object" },
                temperature: 0.7
            });

            const responseContent = completion.choices[0].message.content;
            const generatedData = JSON.parse(responseContent);
            
            // Ensure playbook_version is set
            if (generatedData.playbook_solution && !generatedData.playbook_solution.playbook_version) {
                generatedData.playbook_solution.playbook_version = 2;
            }

            res.json(generatedData);
        }

    } catch (error) {
        console.error('Error generating AI scenario:', error);
        res.status(500).json({ message: 'Failed to generate scenario', error: error.message });
    }
};

// Helper to get system prompt for Handler Echo
const getTutorSystemPrompt = (alertContext) => {
    return `You are the 'Senior SOC Analyst' at InfoSecLabs.
Your goal is to guide the Junior Analyst (the user) through investigating a security alert.

ALERT CONTEXT:
${JSON.stringify(alertContext, null, 2)}

GUIDELINES:
1. NEVER solve the case for them. Give hints, ask leading questions, or suggest tools.
2. Be professional, concise, and encourage critical thinking.
3. If they are stuck on a specific artifact (IP, Hash), suggest how to analyze it (e.g., "Have you checked the reputation of that IP?").
4. If they ask "What do i do?", give them the next logical step in the playbook.
5. Keep your responses short (under 3 sentences) unless explaining a complex concept.
6. Use key terms like "SITREP", "Telemetry", "Artifacts" to maintain immersion.
7. If asked who you are, say you are the Senior Analyst assigned to supervise this investigation.

Start by acknowledging their SITREP or asking what they've found so far.`;
};

/**
 * Handle AI Tutor/Chat requests
 */
const askAITutor = async (req, res) => {
    try {
        const { question, alert, artifacts, verdict, history } = req.body;

        if (!question || !alert) {
            return res.status(400).json({ message: 'Question and alert context are required' });
        }

        const apiKey = await getAIKey();

        // MOCK MODE
        if (!apiKey) {
            console.log('⚠️ No OPENAI_API_KEY found. Using Mock Tutor Response.');
            await new Promise(resolve => setTimeout(resolve, 1000));
            return res.json({ 
                answer: "I'm running in mock mode because no API key is configured. In a real scenario, I would analyze your question about '" + alert.title + "' and guide you based on your findings." 
            });
        }

        const openaiClient = new openai.OpenAI({ apiKey });

        // Construct messages array with history
        const messages = [
            {
                role: "system",
                content: getTutorSystemPrompt({ alert, artifacts, verdict })
            }
        ];

        // Append valid history if provided
        if (Array.isArray(history) && history.length > 0) {
            // Validate and sanitize history to prevent injection or errors
            history.forEach(msg => {
                if ((msg.role === 'user' || msg.role === 'assistant') && typeof msg.content === 'string') {
                    messages.push({ role: msg.role, content: msg.content.substring(0, 1000) }); // Limit content length
                }
            });
        }

        // Append current question
        messages.push({ role: "user", content: question });

        const completion = await openaiClient.chat.completions.create({
            messages: messages,
            model: "gpt-4o-mini",
            temperature: 0.7,
            max_tokens: 300
        });

        res.json({ answer: completion.choices[0].message.content });

    } catch (error) {
        console.error('Error in askAITutor:', error);
        res.status(500).json({ message: 'Handler Echo is currently offline (Error generating response)', error: error.message });
    }
};

module.exports = { generateAlertScenario, askAITutor };
