const axios = require('axios');
const { generateV2AlertContent, validateAndFixAlerts } = require('../utils/aiService');
const { getAptProfile } = require('../data/aptProfiles');

/**
 * Generate a complete Operation scenario with connected alerts
 * 
 * @param {Object} params
 * @param {string} params.aptGroup - e.g. "APT-29"
 * @param {string} params.scenario - e.g. "Espionage against defense contractor"
 * @param {string} params.difficulty - "Beginner", "Intermediate", "Advanced"
 * @param {number} params.alertCount - Number of alerts to generate (3-7)
 * @param {string} params.apiKey - OpenAI API Key
 */
const generateOperation = async (params) => {
    const { aptGroup, scenario, difficulty, alertCount, apiKey } = params;

    if (!apiKey) {
        throw new Error("API Key is required for operation generation");
    }

    console.log(`[OperationGenerator] Generating operation: ${aptGroup} - ${scenario} (${alertCount} alerts)`);

    // 0. Get APT Profile Context
    const aptProfile = getAptProfile(aptGroup);
    if (aptProfile) {
        console.log(`[OperationGenerator] Found profile for ${aptGroup}: ${aptProfile.name}`);
    }

    // 1. Generate Operation Narrative & Structure
    const operationStructure = await generateOperationStructure({ ...params, aptProfile });
    
    // 2. Generate Detailed Alerts based on the structure
    const detailedAlerts = await generateDetailedAlerts(operationStructure.alerts_outline, apiKey, difficulty, aptProfile);

    // 3. Generate Intel Reports linking the alerts
    const intelReports = await generateIntelReports(operationStructure.operation, detailedAlerts, apiKey);

    return {
        operation: operationStructure.operation,
        alerts: detailedAlerts,
        intel_reports: intelReports
    };
};

/**
 * Phase 1: Generate the high-level narrative and alert outline
 */
const generateOperationStructure = async ({ aptGroup, scenario, difficulty, alertCount, apiKey, aptProfile }) => {
    
    const profileContext = aptProfile ? `
    KNOWN THREAT ACTOR PROFILE (${aptProfile.name}):
    - Origin: ${aptProfile.origin}
    - Targets: ${aptProfile.targets}
    - TTPs: ${aptProfile.ttps.join(', ')}
    - Notable Attacks: ${aptProfile.notableAttacks.join(', ')}
    - Description: ${aptProfile.description}
    USE THIS PROFILE TO ENSURE REALISM AND CONSISTENCY.
    ` : '';

    const prompt = `
    Create a cybersecurity operation training scenario.
    
    PARAMETERS:
    - APT Group: ${aptGroup}
    - Scenario: ${scenario}
    - Difficulty: ${difficulty}
    - Number of Alerts: ${alertCount}

    ${profileContext}
    
    OUTPUT: Valid JSON with:
    1. "operation": { 
         title, 
         description,     // Brief summary (SEO optimized meta description, < 160 chars)
         story_intro,     // Full narrative introduction (engaging, sets the scene)
         tags             // Array of 3-5 SEO keywords
       }
    2. "alerts_outline": Array of ${alertCount} items, each with:
       - step: 1, 2, 3...
       - title: Alert title
       - type: Attack type
       - objective: What the attacker is trying to achieve
       - source: Recommended source
       - narrative_context: How this connects to the overall story
    
    CRITICAL: 
    - Ensure the operation Title and Description are SEO-optimized for a cyber training platform.
    - If APT Profile is provided, specifically use its known TTPs in the alerts outline.
    - Build a logical kill chain: Initial Access -> Execution -> Persistence -> Lateral Movement -> Exfiltration.
    `;

    const response = await callOpenAI(apiKey, prompt, "You are a senior cyber threat intelligence analyst designing training scenarios.");
    return JSON.parse(response);
};

/**
 * Phase 2: Generate detailed v2 alerts for each item in the outline
 */
const generateDetailedAlerts = async (outline, apiKey, difficulty, aptProfile) => {
    const detailedAlerts = [];

    const profileContext = aptProfile ? `
    THREAT ACTOR TTPs (${aptProfile.name}):
    - Tactics: ${aptProfile.ttps.join(', ')}
    - Notable Tools/Malware: ${aptProfile.notableAttacks.join(', ')}
    ` : '';

    for (const item of outline) {
        console.log(`[OperationGenerator] Generating alert ${item.step}/${outline.length}: ${item.title}`);
        
        const prompt = `
        Generate a DETAILED cybersecurity alert (v2 format) for step ${item.step} of an operation.
        
        CONTEXT:
        - Title: ${item.title}
        - Type: ${item.type}
        - Objective: ${item.objective}
        - Source: ${item.source}
        - Narrative Context: ${item.narrative_context}
        - Difficulty: ${difficulty}
        
        ${profileContext}
        
        REQUIREMENTS:
        1. "raw_log": REALISTIC JSON log entry matching the source. Include specific indicators (IPs, hashes, users, filenames).
           - For internal IPs use 10.x.x.x or 192.168.x.x
           - For external attacker IPs use public-looking IPs (avoid reserved ranges if possible, or use clear malicious ones)
           - If using specific malware, use hashes/filenames associated with the APT if known, or realistic simulation artifacts.
        
        2. "playbook_solution":
           - "playbook_version": 2
           - "artifacts": Array of relevant artifacts found in raw_log (IPs, hashes, etc.)
             - "id": "artifact_x"
             - "type": "ip|hash|domain|url|email|filename|username"
             - "value": MUST MATCH EXACTLY with raw_log value
             - "is_critical": boolean
             - "osint_result": { source, verdict (malicious/suspicious/clean/internal), details }
           - "recommended_actions": ["isolate_host", "block_ip", "block_hash", "reset_credentials", "collect_forensics", "escalate"]
           - "expected_verdict": "True Positive" | "False Positive" | "Benign"
           - "expected_actions": Must be a subset of recommended_actions. Use only these IDs: 
             ["isolate_host", "block_ip", "block_hash", "reset_credentials", "collect_forensics", "escalate"]
        
        CRITICAL: Every artifact value MUST exist in the raw_log.
        
        OUTPUT: Valid JSON object for a single alert.
        {
           "title": "...",
           "severity": "Low|Medium|High|Critical",
           "source": "...",
           "details": "...",
           "alert_type": "...",
           "mitre_technique": "...",
           "real_world_example": 1,
           "raw_log": { ... },
           "playbook_solution": { ... }
        }
        `;

        const alertContent = await callOpenAI(apiKey, prompt, "You are a SIEM engineer creating realistic alert data. Every artifact must match the raw_log.");
        let alert = JSON.parse(alertContent);
        
        // Ensure playbook version is 2
        if (!alert.playbook_solution) alert.playbook_solution = {};
        alert.playbook_solution.playbook_version = 2;

        // STRICT VALIDATION: Fix any artifact mismatches with raw_log
        const validation = validateAndFixAlerts([alert]);
        if (validation.validAlerts.length > 0) {
            detailedAlerts.push(validation.validAlerts[0]);
        } else {
            console.warn(`[OperationGenerator] Alert ${item.step} failed validation and could not be fixed. Adding as-is but expect issues.`);
            detailedAlerts.push(alert);
        }
    }

    return detailedAlerts;
};

/**
 * Phase 3: Generate Intel Reports unlocked between alerts
 */
const generateIntelReports = async (narrative, alerts, apiKey) => {
    const reports = [];
    const reportCount = alerts.length - 1; // Creates reports BETWEEN alerts
    
    if (reportCount <= 0) return [];

    console.log(`[OperationGenerator] Generating ${reportCount} intel reports...`);

    const prompt = `
    Generate ${reportCount} intelligence reports that would be unlocked during this operation.
    
    OPERATION: ${narrative.title} - ${narrative.description}
    
    ALERTS CHAIN:
    ${alerts.map((a, i) => `${i+1}. ${a.title} (${a.alert_type})`).join('\n')}
    
    REQUIREMENTS:
    - Generate reports that would appear AFTER alert 1, AFTER alert 2, etc.
    - Reports should provide context for the NEXT alert or deeper insight into the PREVIOUS one.
    - Format content in Markdown.
    
    OUTPUT: Valid JSON with "reports" array. Each item:
    {
      "sequence_index": 1 (means unlocked after alert 1),
      "title": "Report Title",
      "content": "Markdown content..."
    }
    `;

    const response = await callOpenAI(apiKey, prompt, "You are a cyber intelligence officer writing field reports.");
    const validReports = JSON.parse(response).reports || [];
    
    // Ensure we have the right structure
    return validReports.map(r => ({
        title: r.title,
        content: r.content,
        sequence_order: r.sequence_index // Corresponds to the alert sequence after which it appears
    }));
};

/**
 * Helper to call OpenAI
 */
const callOpenAI = async (apiKey, prompt, systemMsg) => {
    try {
        const response = await axios.post('https://api.openai.com/v1/chat/completions', {
            model: "gpt-4o",
            messages: [
                { role: "system", content: systemMsg + " Output valid JSON only." },
                { role: "user", content: prompt }
            ],
            response_format: { type: "json_object" },
            temperature: 0.7
        }, {
            headers: {
                'Content-Type': 'application/json',
                'Authorization': `Bearer ${apiKey}`
            },
            timeout: 120000
        });

        return response.data.choices[0].message.content;
    } catch (error) {
        console.error("OpenAI API Error:", error.message);
        if (error.response) console.error("Response data:", error.response.data);
        throw new Error("Failed to generate content from AI");
    }
};

module.exports = {
    generateOperation
};
