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

interface RouteParams {
  params: Promise<{ userId: string }>;
}

/**
 * GET /api/messages/[userId]?currentUserId=xxx&before=xxx&limit=50
 * Get messages between the current user and another user.
 *
 * Path param:
 *   - userId: the other user's ID
 *
 * Query params:
 *   - currentUserId (required): the logged-in user's ID
 *   - before (optional): message ID cursor for pagination (load messages before this ID)
 *   - limit (optional, default 50): number of messages to return
 */
export async function GET(
  request: NextRequest,
  { params }: RouteParams
) {
  try {
    const { userId: otherUserId } = await params;
    const { searchParams } = new URL(request.url);
    const currentUserId = searchParams.get('currentUserId');
    const before = searchParams.get('before');
    const limitParam = searchParams.get('limit');

    // Validate required parameters
    if (!currentUserId) {
      return NextResponse.json(
        { error: 'currentUserId query parameter is required' },
        { status: 400 }
      );
    }

    if (!isValidId(currentUserId)) {
      return NextResponse.json(
        { error: 'Invalid current user ID format' },
        { status: 400 }
      );
    }

    if (!isValidId(otherUserId)) {
      return NextResponse.json(
        { error: 'Invalid user ID format in path' },
        { status: 400 }
      );
    }

    if (currentUserId === otherUserId) {
      return NextResponse.json(
        { error: 'Cannot retrieve messages with yourself' },
        { status: 400 }
      );
    }

    // Validate and parse limit
    const limit = Math.min(100, Math.max(1, parseInt(limitParam || '50') || 50));

    // Validate 'before' cursor if provided
    if (before && !isValidId(before)) {
      return NextResponse.json(
        { error: 'Invalid "before" cursor format' },
        { status: 400 }
      );
    }

    // Verify both users exist
    const [currentUser, otherUser] = await Promise.all([
      db.user.findUnique({ where: { id: currentUserId }, select: { id: true } }),
      db.user.findUnique({ where: { id: otherUserId }, select: { id: true } }),
    ]);

    if (!currentUser) {
      return NextResponse.json(
        { error: 'Current user not found' },
        { status: 404 }
      );
    }

    if (!otherUser) {
      return NextResponse.json(
        { error: 'Other user not found' },
        { status: 404 }
      );
    }

    // Build the where clause for messages between the two users
    const whereClause: Record<string, unknown> = {
      OR: [
        { senderId: currentUserId, receiverId: otherUserId },
        { senderId: otherUserId, receiverId: currentUserId },
      ],
    };

    // If 'before' cursor is provided, find messages created before that message
    if (before) {
      const cursorMessage = await db.message.findUnique({
        where: { id: before },
        select: { createdAt: true },
      });

      if (cursorMessage) {
        whereClause.createdAt = { lt: cursorMessage.createdAt };
      }
    }

    // Fetch messages sorted by createdAt ascending (chronological order)
    const messages = await db.message.findMany({
      where: whereClause,
      include: {
        sender: {
          select: { id: true, name: true, phone: true, avatar: true },
        },
      },
      orderBy: { createdAt: 'asc' },
      take: limit,
    });

    // Mark unread messages as read (where the current user is the receiver)
    const markReadResult = await db.message.updateMany({
      where: {
        senderId: otherUserId,
        receiverId: currentUserId,
        isRead: false,
      },
      data: { isRead: true },
    });

    // Determine if there are more messages (for frontend pagination)
    const hasMore = messages.length === limit;

    return NextResponse.json({
      messages,
      hasMore,
      markedAsRead: markReadResult.count,
    });
  } catch (error) {
    console.error('Messages [userId] GET error:', error);
    return NextResponse.json(
      { error: 'Internal server error' },
      { status: 500 }
    );
  }
}
