import { NextRequest, NextResponse } from 'next/server';
import { prisma } from '@/lib/db';

export const dynamic = 'force-dynamic';

// GET - Query memories with filtering
export async function GET(request: NextRequest) {
  try {
    const { searchParams } = new URL(request.url);
    const category = searchParams.get('category');
    const search = searchParams.get('search');
    const tag = searchParams.get('tag');
    const importance = searchParams.get('importance');
    const limit = parseInt(searchParams.get('limit') || '50');
    const includeInactive = searchParams.get('includeInactive') === 'true';

    const where: Record<string, unknown> = {};
    
    if (!includeInactive) {
      where.isActive = true;
    }
    
    if (category) {
      where.category = category;
    }
    
    if (importance) {
      where.importance = { gte: parseInt(importance) };
    }
    
    if (search) {
      where.OR = [
        { key: { contains: search, mode: 'insensitive' } },
        { value: { contains: search, mode: 'insensitive' } },
        { context: { contains: search, mode: 'insensitive' } },
      ];
    }
    
    if (tag) {
      where.tags = { array_contains: [tag] };
    }

    const memories = await prisma.tesaMemory.findMany({
      where,
      orderBy: [
        { importance: 'desc' },
        { updatedAt: 'desc' },
      ],
      take: limit,
    });

    // Update access stats for retrieved memories
    const ids = memories.map((m: any) => m.id);
    if (ids.length > 0) {
      await prisma.tesaMemory.updateMany({
        where: { id: { in: ids } },
        data: {
          lastAccessed: new Date(),
          accessCount: { increment: 1 },
        },
      });
    }

    // Get category counts for stats
    const categoryCounts = await prisma.tesaMemory.groupBy({
      by: ['category'],
      where: { isActive: true },
      _count: { category: true },
    });

    return NextResponse.json({
      memories,
      stats: {
        total: memories.length,
        byCategory: Object.fromEntries(
          categoryCounts.map((c: any) => [c.category, c._count.category])
        ),
      },
    });
  } catch (error) {
    console.error('Error fetching Tesa memories:', error);
    return NextResponse.json(
      { error: 'Failed to fetch memories' },
      { status: 500 }
    );
  }
}

// POST - Create new memory
export async function POST(request: NextRequest) {
  try {
    const body = await request.json();
    const {
      category,
      key,
      value,
      context,
      source = 'conversation',
      importance = 5,
      confidence = 1.0,
      tags = [],
      relatedIds = [],
      expiresAt,
    } = body;

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

    // Check for existing memory with same key
    const existing = await prisma.tesaMemory.findFirst({
      where: { key, isActive: true },
    });

    let memory;
    if (existing) {
      // Update existing memory
      memory = await prisma.tesaMemory.update({
        where: { id: existing.id },
        data: {
          value,
          context,
          importance,
          confidence,
          tags,
          relatedIds,
          expiresAt: expiresAt ? new Date(expiresAt) : null,
          updatedAt: new Date(),
        },
      });
    } else {
      // Create new memory
      memory = await prisma.tesaMemory.create({
        data: {
          category,
          key,
          value,
          context,
          source,
          importance,
          confidence,
          tags,
          relatedIds,
          expiresAt: expiresAt ? new Date(expiresAt) : null,
        },
      });
    }

    return NextResponse.json({ memory, updated: !!existing });
  } catch (error) {
    console.error('Error creating Tesa memory:', error);
    return NextResponse.json(
      { error: 'Failed to create memory' },
      { status: 500 }
    );
  }
}

// PATCH - Update existing memory
export async function PATCH(request: NextRequest) {
  try {
    const body = await request.json();
    const { id, ...updates } = body;

    if (!id) {
      return NextResponse.json(
        { error: 'id is required' },
        { status: 400 }
      );
    }

    // Clean up the updates object
    const data: Record<string, unknown> = {};
    if (updates.value !== undefined) data.value = updates.value;
    if (updates.context !== undefined) data.context = updates.context;
    if (updates.importance !== undefined) data.importance = updates.importance;
    if (updates.confidence !== undefined) data.confidence = updates.confidence;
    if (updates.tags !== undefined) data.tags = updates.tags;
    if (updates.relatedIds !== undefined) data.relatedIds = updates.relatedIds;
    if (updates.isActive !== undefined) data.isActive = updates.isActive;
    if (updates.expiresAt !== undefined) {
      data.expiresAt = updates.expiresAt ? new Date(updates.expiresAt) : null;
    }

    const memory = await prisma.tesaMemory.update({
      where: { id },
      data,
    });

    return NextResponse.json({ memory });
  } catch (error) {
    console.error('Error updating Tesa memory:', error);
    return NextResponse.json(
      { error: 'Failed to update memory' },
      { status: 500 }
    );
  }
}

// DELETE - Soft delete (set isActive = false) or hard delete
export async function DELETE(request: NextRequest) {
  try {
    const { searchParams } = new URL(request.url);
    const id = searchParams.get('id');
    const hard = searchParams.get('hard') === 'true';

    if (!id) {
      return NextResponse.json(
        { error: 'id is required' },
        { status: 400 }
      );
    }

    if (hard) {
      await prisma.tesaMemory.delete({ where: { id } });
    } else {
      await prisma.tesaMemory.update({
        where: { id },
        data: { isActive: false },
      });
    }

    return NextResponse.json({ success: true, hard });
  } catch (error) {
    console.error('Error deleting Tesa memory:', error);
    return NextResponse.json(
      { error: 'Failed to delete memory' },
      { status: 500 }
    );
  }
}
