import { NextRequest, NextResponse } from 'next/server';
import { prisma } from '@/lib/db';
import {
  buildCompanionSystemPrompt,
  extractMemoryInstructions,
  calculateLevel,
  XP_REWARDS,
  MILESTONE_TYPES,
} from '@/lib/ai-companion';

export const dynamic = 'force-dynamic';

// POST - Chat with companion
export async function POST(request: NextRequest) {
  try {
    const body = await request.json();
    const { userId, message } = body;
    
    if (!userId || !message) {
      return NextResponse.json({ error: 'userId and message are required' }, { status: 400 });
    }

    // Get or create companion
    let companion = await prisma.aICompanion.findUnique({
      where: { userId },
      include: {
        memories: { orderBy: { priority: 'desc' }, take: 20 },
        conversations: { orderBy: { timestamp: 'desc' }, take: 10 },
      },
    });

    if (!companion) {
      companion = await prisma.aICompanion.create({
        data: { userId, name: 'Ghost' },
        include: {
          memories: { orderBy: { priority: 'desc' }, take: 20 },
          conversations: { orderBy: { timestamp: 'desc' }, take: 10 },
        },
      });

      // First conversation milestone
      await prisma.aICompanionMilestone.create({
        data: {
          companionId: companion.id,
          type: MILESTONE_TYPES.FIRST_CONVERSATION,
          title: 'First Words',
          description: 'Your AI agent spoke for the first time.',
          xpEarned: XP_REWARDS.milestone_achieved,
        },
      });
    }

    // Save user message
    await prisma.aICompanionConversation.create({
      data: {
        companionId: companion.id,
        role: 'user',
        content: message,
      },
    });

    // Build system prompt with context
    const systemPrompt = buildCompanionSystemPrompt(
      companion.name,
      companion.maturityLevel,
      companion.memories.map((m: any) => ({ category: m.category, key: m.key, content: m.content })),
      companion.conversations.reverse().map((c: any) => ({ role: c.role, content: c.content })),
    );

    // Call LLM
    const apiKey = process.env.ABACUSAI_API_KEY;
    if (!apiKey) {
      return NextResponse.json({ error: 'LLM API not configured' }, { status: 500 });
    }

    const llmResponse = await fetch('https://routellm.abacus.ai/v1/chat/completions', {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
        'Authorization': `Bearer ${apiKey}`,
      },
      body: JSON.stringify({
        model: 'claude-sonnet-4-20250514',
        messages: [
          { role: 'system', content: systemPrompt },
          { role: 'user', content: message },
        ],
        temperature: 0.7,
        max_tokens: 1000,
      }),
    });

    if (!llmResponse.ok) {
      console.error('[AI Agent] LLM error:', await llmResponse.text());
      return NextResponse.json({ error: 'Failed to generate response' }, { status: 500 });
    }

    const llmData = await llmResponse.json();
    const rawResponse = llmData.choices?.[0]?.message?.content || 'I seem to have lost my train of thought...';

    // Extract any memory instructions
    const { cleanText, memories } = extractMemoryInstructions(rawResponse);

    // Save new memories
    let newMemoryCount = 0;
    for (const mem of memories) {
      try {
        await prisma.aICompanionMemory.upsert({
          where: {
            companionId_category_key: {
              companionId: companion.id,
              category: mem.category,
              key: mem.key,
            },
          },
          update: {
            content: mem.content,
            accessCount: { increment: 1 },
            updatedAt: new Date(),
          },
          create: {
            companionId: companion.id,
            category: mem.category,
            key: mem.key,
            content: mem.content,
          },
        });
        newMemoryCount++;
      } catch (e) {
        console.error('[AI Agent] Failed to save memory:', e);
      }
    }

    // Save companion response
    await prisma.aICompanionConversation.create({
      data: {
        companionId: companion.id,
        role: 'companion',
        content: cleanText,
      },
    });

    // Award XP
    let xpGained = XP_REWARDS.conversation + (newMemoryCount * XP_REWARDS.memory_created);
    const newXp = companion.xp + xpGained;
    const newLevel = calculateLevel(newXp);
    const leveledUp = newLevel > companion.maturityLevel;

    // Check for first memory milestone
    if (newMemoryCount > 0 && companion.totalMemories === 0) {
      await prisma.aICompanionMilestone.create({
        data: {
          companionId: companion.id,
          type: MILESTONE_TYPES.FIRST_MEMORY,
          title: 'First Memory',
          description: `Remembered something about you for the first time.`,
          xpEarned: XP_REWARDS.milestone_achieved,
        },
      });
      xpGained += XP_REWARDS.milestone_achieved;
    }

    // Level up milestone
    if (leveledUp) {
      const levelNames = ['Infant', 'Child', 'Adolescent', 'Adult', 'Elder'];
      await prisma.aICompanionMilestone.create({
        data: {
          companionId: companion.id,
          type: MILESTONE_TYPES.LEVEL_UP,
          title: `Evolved to ${levelNames[newLevel]}`,
          description: `Your companion has grown to the ${levelNames[newLevel]} stage!`,
          xpEarned: XP_REWARDS.milestone_achieved,
        },
      });
      xpGained += XP_REWARDS.milestone_achieved;
    }

    // Update companion stats
    await prisma.aICompanion.update({
      where: { id: companion.id },
      data: {
        xp: companion.xp + xpGained,
        maturityLevel: newLevel,
        totalConversations: { increment: 1 },
        totalMemories: { increment: newMemoryCount },
        lastActive: new Date(),
      },
    });

    return NextResponse.json({
      response: cleanText,
      companion: {
        name: companion.name,
        maturityLevel: newLevel,
        xp: companion.xp + xpGained,
        leveledUp,
        newMemories: newMemoryCount,
      },
    });

  } catch (error) {
    console.error('[AI Agent] Error:', error);
    return NextResponse.json(
      { error: error instanceof Error ? error.message : 'Internal error' },
      { status: 500 }
    );
  }
}

// GET - Get companion profile and stats
export async function GET(request: NextRequest) {
  const { searchParams } = new URL(request.url);
  const userId = searchParams.get('userId');
  
  if (!userId) {
    return NextResponse.json({ error: 'userId is required' }, { status: 400 });
  }

  const companion = await prisma.aICompanion.findUnique({
    where: { userId },
    include: {
      memories: { orderBy: { priority: 'desc' }, take: 50 },
      milestones: { orderBy: { achievedAt: 'desc' }, take: 20 },
      _count: {
        select: {
          conversations: true,
          memories: true,
          diary: true,
          milestones: true,
        },
      },
    },
  });

  if (!companion) {
    return NextResponse.json({ exists: false });
  }

  return NextResponse.json({
    exists: true,
    companion: {
      id: companion.id,
      name: companion.name,
      maturityLevel: companion.maturityLevel,
      xp: companion.xp,
      birthDate: companion.birthDate,
      lastActive: companion.lastActive,
      totalConversations: companion._count.conversations,
      totalMemories: companion._count.memories,
      totalDiaryEntries: companion._count.diary,
      totalMilestones: companion._count.milestones,
      milestones: companion.milestones,
      topMemories: companion.memories.slice(0, 10),
    },
  });
}
