import { createClient } from "@/lib/supabase/server";
import { NextRequest, NextResponse } from "next/server";
import { checkRateLimit, getClientIP, createRateLimitResponse } from "@/lib/rate-limit";
import { logger } from "@/lib/logger";

// 200 message fetches per 15 min window per IP (higher limit for active conversations)
const GET_MESSAGES_RATE_LIMIT = 200;
const GET_MESSAGES_WINDOW_MS = 15 * 60 * 1000;

export async function GET(
  request: NextRequest,
  { params }: { params: Promise<{ id: string }> }
) {
  try {
    const clientIP = getClientIP(request);
    const rateLimit = await checkRateLimit(`messages-get:${clientIP}`, GET_MESSAGES_RATE_LIMIT, GET_MESSAGES_WINDOW_MS);

    if (!rateLimit.allowed) {
      const retryAfter = Math.ceil((rateLimit.resetTime - Date.now()) / 1000);
      return createRateLimitResponse(clientIP, retryAfter);
    }

    const { id: conversationId } = await params;
    const supabase = await createClient();

    // Parse pagination params from URL
    const { searchParams } = new URL(request.url);
    const cursor = searchParams.get('cursor'); // message ID to fetch before
    const limit = Math.min(parseInt(searchParams.get('limit') || '100'), 100); // Max 100 messages per request

    // Check if user is authenticated
    const { data: { user }, error: authError } = await supabase.auth.getUser();

    if (authError || !user) {
      return NextResponse.json({ error: "Unauthorized" }, { status: 401 });
    }

    // Verify user is a participant in this conversation
    const { data: participant, error: participantError } = await supabase
      .from('conversation_participants')
      .select('id')
      .eq('conversation_id', conversationId)
      .eq('profile_id', user.id)
      .single();

    if (participantError || !participant) {
      return NextResponse.json({ error: "Conversation not found" }, { status: 404 });
    }

    // Get conversation details with other participant info
    const { data: conversationData, error: conversationError } = await supabase
      .from('conversation_participants')
      .select(`
        profile_id,
        profiles!inner(
          id,
          name,
          display_name,
          avatar_url,
          type
        )
      `)
      .eq('conversation_id', conversationId)
      .neq('profile_id', user.id)
      .single();

    if (conversationError || !conversationData) {
      return NextResponse.json(
        { error: "Failed to fetch conversation details" },
        { status: 500 }
      );
    }

    // Get messages in this conversation with cursor pagination
    let query = supabase
      .from('messages')
      .select(`
        id,
        content,
        sender_id,
        status,
        created_at,
        attachments
      `)
      .eq('conversation_id', conversationId)
      .order('created_at', { ascending: true })
      .limit(limit);

    // If cursor provided, fetch messages after this cursor (chronologically)
    if (cursor) {
      // Get the timestamp of the cursor message
      const { data: cursorMessage } = await supabase
        .from('messages')
        .select('created_at')
        .eq('id', cursor)
        .single();

      if (cursorMessage) {
        query = query.gt('created_at', cursorMessage.created_at);
      }
    }

    const { data: messages, error: messagesError } = await query;

    if (messagesError) {
      return NextResponse.json(
        { error: "Failed to fetch messages" },
        { status: 500 }
      );
    }

    // Update last_read_at and last_seen_at
    const now = new Date().toISOString();
    await supabase
      .from('conversation_participants')
      .update({ last_read_at: now })
      .eq('conversation_id', conversationId)
      .eq('profile_id', user.id);

    await supabase
      .from('profiles')
      .update({ last_seen_at: now })
      .eq('id', user.id);

    // Cast profiles to single object (inner join guarantees single row)
    const profile = conversationData.profiles as unknown as {
      id: string;
      name: string;
      avatar_url: string | null;
      type: string;
    };

    // Check if other user was active in the last 5 minutes
    const { data: otherProfile } = await supabase
      .from('profiles')
      .select('last_seen_at')
      .eq('id', profile.id)
      .single();

    const fiveMinAgo = Date.now() - 5 * 60 * 1000;
    const isOnline = otherProfile?.last_seen_at
      ? new Date(otherProfile.last_seen_at).getTime() > fiveMinAgo
      : false;

    // Determine if there are more messages (next cursor)
    const hasMore = messages && messages.length === limit;
    const nextCursor = hasMore && messages.length > 0
      ? messages[messages.length - 1].id
      : null;

    return NextResponse.json({
      conversation: {
        id: conversationId,
        otherParticipant: {
          id: profile.id,
          name: profile.name,
          avatar: profile.avatar_url,
          type: profile.type,
          isOnline,
        },
        messages: messages?.map(msg => ({
          id: msg.id,
          content: msg.content,
          isOwn: msg.sender_id === user.id,
          timestamp: msg.created_at,
          status: msg.status,
          attachments: msg.attachments
        })) || [],
        pagination: {
          nextCursor,
          hasMore,
          limit
        }
      }
    });
  } catch (error) {
    logger.error("Error in conversation API:", error);
    return NextResponse.json(
      { error: "Internal server error" },
      { status: 500 }
    );
  }
}