// Narrator Agent - Generates story content

const axios = require('axios');
const { NARRATOR_PROMPT } = require('../prompts/agentPrompts');

const LM_STUDIO_URL = 'http://localhost:1234';

class NarratorAgent {
  constructor() {
    this.model = 'local-model';
  }

  // Generate initial narration
  async generateNarration(context, playerInput, constraints, expectedElements) {
    const prompt = `${NARRATOR_PROMPT}

=== SYSTEM PROMPT ===
${context.systemPrompt || 'You are a skilled narrator for a text-based RPG.'}

=== CURRENT CONTEXT ===
Location: ${context.currentLocation || 'Unknown'}
Characters Present: ${context.characters.map(c => `${c.name} - ${c.description?.substring(0, 50) || 'No description'}`).join('\n') || 'None'}
Inventory: ${context.inventory.map(i => i.name).join(', ') || 'Empty'}
Active Quests: ${context.quests.map(q => q.title).join(', ') || 'None'}

Journal Summary: ${context.journal.summary || 'No summary yet'}

Recent Messages:
${context.recentMessages.map(m => `[${m.role}] ${m.content.substring(0, 100)}`).join('\n') || 'None'}

=== CONSTRAINTS FROM REASONER ===
${constraints.map((c, i) => `${i + 1}. ${c}`).join('\n') || 'None'}

=== EXPECTED ELEMENTS ===
${expectedElements.map((e, i) => `${i + 1}. ${e}`).join('\n') || 'None'}

=== PLAYER INPUT ===
"${playerInput}"

=== YOUR TASK ===
Generate the narration for this RPG response.
Follow ALL constraints strictly.
Include expected elements naturally.
Keep it 200-400 words.
End with opportunity for player action.

Write your response now:`;

    try {
      const response = await axios.post(`${LM_STUDIO_URL}/v1/chat/completions`, {
        model: this.model,
        messages: [
          { role: 'system', content: NARRATOR_PROMPT },
          { role: 'user', content: prompt }
        ],
        temperature: 0.8,
        max_tokens: 600,
        stream: false
      }, { timeout: 60000 });

      return {
        narration: response.data.choices[0].message.content,
        success: true
      };
    } catch (error) {
      console.error('Narrator (generate) error:', error.message);
      return {
        narration: 'The world awaits your action... (Narrator unavailable)',
        success: false,
        error: error.message
      };
    }
  }

  // Revise narration based on feedback
  async reviseNarration(context, playerInput, originalResponse, revisionInstructions, focusAreas) {
    const prompt = `${NARRATOR_PROMPT}

=== ORIGINAL PLAYER INPUT ===
"${playerInput}"

=== YOUR ORIGINAL RESPONSE ===
${originalResponse}

=== REVISION INSTRUCTIONS ===
${revisionInstructions.map((r, i) => `${i + 1}. ${r}`).join('\n')}

=== FOCUS AREAS ===
${focusAreas.map((f, i) => `${i + 1}. ${f}`).join('\n')}

=== YOUR TASK ===
Revise your response following the instructions above.
Keep what works, fix what's broken.
Make sure all critical issues are resolved.

Write your revised response now:`;

    try {
      const response = await axios.post(`${LM_STUDIO_URL}/v1/chat/completions`, {
        model: this.model,
        messages: [
          { role: 'system', content: NARRATOR_PROMPT },
          { role: 'user', content: prompt }
        ],
        temperature: 0.7,
        max_tokens: 600,
        stream: false
      }, { timeout: 60000 });

      return {
        narration: response.data.choices[0].message.content,
        success: true
      };
    } catch (error) {
      console.error('Narrator (revise) error:', error.message);
      return {
        narration: originalResponse, // Return original if revision fails
        success: false,
        error: error.message
      };
    }
  }

  // Generate context extraction (what changed in the story)
  async extractContextUpdates(context, playerInput, narration) {
    const prompt = `Analyze this RPG exchange and extract any context updates.

=== PLAYER INPUT ===
${playerInput}

=== NARRATOR RESPONSE ===
${narration}

=== YOUR TASK ===
Extract any changes to game state.
If nothing changed, return empty arrays.

Return ONLY valid JSON:
{
  "characters": [
    {"name": "New Character Name", "description": "...", "traits": [], "status": "Active"}
  ],
  "locations": [
    {"name": "New Location", "description": "...", "atmosphere": "..."}
  ],
  "inventory": [
    {"name": "Item Name", "description": "...", "type": "...", "action": "add"}
  ],
  "quests": [
    {"title": "Quest Title", "description": "...", "status": "Active"}
  ],
  "journal": {
    "summaryUpdate": "Brief 1-2 sentence summary of what happened",
    "keyEvent": "Significant event description",
    "characterArcNotes": {"CharacterName": "Development notes"}
  },
  "storyState": {
    "key": "value for important world facts"
  }
}`;

    try {
      const response = await axios.post(`${LM_STUDIO_URL}/v1/chat/completions`, {
        model: this.model,
        messages: [
          { role: 'system', content: 'You extract structured data from RPG narration. Return ONLY valid JSON.' },
          { role: 'user', content: prompt }
        ],
        temperature: 0.3,
        max_tokens: 800,
        stream: false
      }, { timeout: 30000 });

      const content = response.data.choices[0].message.content;
      const jsonMatch = content.match(/\{[\s\S]*\}/);
      const parsed = jsonMatch ? JSON.parse(jsonMatch[0]) : null;

      return parsed || {};
    } catch (error) {
      console.error('Narrator (extraction) error:', error.message);
      return {};
    }
  }
}

module.exports = NarratorAgent;
