import { NextRequest, NextResponse } from 'next/server';
import { prisma } from '@/lib/db';
import { agentRemember, agentRecall, recordInteraction, escalateToParent } from '@/lib/agent-hierarchy/engine';
import { agentReason } from '@/lib/gfs/engine/agent-reasoning';
import { checkLLMGate } from '@/lib/gfs/engine/llm-gate';

export const dynamic = 'force-dynamic';

/**
 * POST /api/agents/chat
 * Chat with a specific domain agent.
 * 
 * Zero-Cost Default: Uses deterministic RAG + rules reasoning.
 * Only falls back to cloud LLM when:
 *   1. Deterministic confidence < 0.5 AND
 *   2. LLM gate for 'agents' scope is OPEN
 * 
 * Body: { agentId: string, message: string, userId?: string }
 */
export async function POST(request: NextRequest) {
  try {
    const { agentId, message, userId } = await request.json();

    if (!agentId || !message) {
      return NextResponse.json({ error: 'agentId and message are required' }, { status: 400 });
    }

    if (typeof message !== 'string' || message.length > 10_000) {
      return NextResponse.json({ error: 'Message too long. Maximum 10,000 characters.' }, { status: 400 });
    }

    if (typeof agentId !== 'string' || agentId.length > 100) {
      return NextResponse.json({ error: 'Invalid agent ID' }, { status: 400 });
    }

    // Fetch agent
    const agent = await prisma.domainAgent.findUnique({ where: { agentId } });
    if (!agent) {
      return NextResponse.json({ error: `Agent '${agentId}' not found` }, { status: 404 });
    }

    if (agent.status === 'dormant') {
      return NextResponse.json({
        error: `Agent ${agent.name} is currently dormant. Enable the ${agent.moduleId || 'associated'} module to activate.`,
        dormant: true,
      }, { status: 403 });
    }

    // Gather agent's memories for context
    const memories = await agentRecall(agentId, undefined, 15);

    // Check for pending escalations (CEO only)
    let escalationContext = '';
    if (agentId === 'agent-ceo') {
      const pendingEscalations = await prisma.domainAgentMessage.findMany({
        where: { toAgentId: 'agent-ceo', type: 'escalation', status: 'pending' },
        include: { fromAgent: { select: { name: true, domain: true } } },
        take: 5,
      });
      if (pendingEscalations.length > 0) {
        escalationContext = pendingEscalations.map((e: { fromAgent: { name: string; domain: string }; subject: string }) =>
          `- From ${e.fromAgent.name} (${e.fromAgent.domain}): ${e.subject}`
        ).join('\n');
      }
    }

    // ═══════════════════════════════════════════
    // STEP 1: Zero-cost deterministic reasoning
    // ═══════════════════════════════════════════
    const reasoning = await agentReason({
      agentId,
      agentName: agent.name,
      agentDomain: agent.domain,
      agentTitle: agent.title,
      systemPrompt: agent.systemPrompt,
      personality: agent.personality as string || '',
      userMessage: message,
      memories: memories.map((m: { category: string; key: string; content: unknown }) => ({
        category: m.category,
        key: m.key,
        content: m.content,
      })),
      escalationContext,
    });

    let reply = reasoning.reply;
    let responseSource = reasoning.source;

    // ═══════════════════════════════════════════
    // STEP 2: LLM fallback (only if needed + allowed)
    // ═══════════════════════════════════════════
    if (reasoning.requiresLLM && reasoning.confidence < 0.5) {
      const gate = await checkLLMGate('agents');
      if (gate.allowed) {
        try {
          const OpenAI = (await import('openai')).default;
          const openai = new OpenAI({
            apiKey: process.env.ABACUSAI_API_KEY || '',
            baseURL: 'https://routellm.abacus.ai/v1',
          });

          const memoryContext = memories.length > 0
            ? `\n\nYour current memories:\n${memories.map((m: { category: string; key: string; content: unknown }) => `- [${m.category}/${m.key}]: ${JSON.stringify(m.content)}`).join('\n')}`
            : '';

          const systemMessage = `${agent.systemPrompt}\n\nYour personality: ${agent.personality}${memoryContext}${escalationContext ? `\n\nPending escalations:\n${escalationContext}` : ''}\n\nIMPORTANT: Be concise and actionable.`;

          const completion = await openai.chat.completions.create({
            model: 'claude-sonnet-4-20250514',
            messages: [
              { role: 'system', content: systemMessage },
              { role: 'user', content: message },
            ],
            max_tokens: 1024,
            temperature: 0.7,
          });

          reply = completion.choices?.[0]?.message?.content || reply;
          responseSource = 'fallback' as typeof responseSource;
        } catch (llmError) {
          console.warn('[Agent Chat] LLM fallback failed, using deterministic response:', llmError);
          // Keep deterministic reply
        }
      }
    }

    // Record interaction and gain XP
    await recordInteraction(agentId);

    // Auto-remember key interactions
    const timestamp = new Date().toISOString();
    await agentRemember(agentId, 'user_interactions', `interaction_${Date.now()}`, {
      userMessage: message.substring(0, 200),
      agentReply: reply.substring(0, 200),
      timestamp,
      source: responseSource,
    }, { importance: 0.3, source: 'user_interaction' });

    // Check if response suggests escalation
    const shouldEscalate = reply.toLowerCase().includes('escalat') && agent.parentAgentId;
    if (shouldEscalate) {
      await escalateToParent(
        agentId,
        `User interaction requiring attention: ${message.substring(0, 100)}`,
        { userMessage: message, agentResponse: reply, timestamp }
      );
    }

    return NextResponse.json({
      agentId,
      agentName: agent.name,
      agentTitle: agent.title,
      avatarColor: agent.avatarColor,
      reply,
      xp: agent.xp + 5,
      maturityLevel: agent.maturityLevel,
      escalated: !!shouldEscalate,
      // Zero-cost metadata
      reasoning: {
        source: responseSource,
        confidence: reasoning.confidence,
        intent: reasoning.intent,
        ragCitations: reasoning.ragCitations.length,
        tokensUsed: responseSource === 'fallback' ? 'cloud' : 0,
        cost: responseSource === 'fallback' ? 'cloud-credits' : '$0.00',
      },
    });
  } catch (error) {
    console.error('Agent chat error:', error);
    return NextResponse.json({ error: 'Agent communication failed' }, { status: 500 });
  }
}
