/**
 * API endpoint to fetch users who reacted with a specific emoji on a message
 */
import sql from '../../../utils/db.ts';
import { requireApiAuth } from '../../../utils/apiAuth.ts';
import {
  checkRateLimit,
  recordRequest,
} from '../../../utils/rateLimit.ts';
import { signImageId } from './cached-image.ts';

export async function GET({ request }) {
  // Rate limit check
  const rateCheck = checkRateLimit(request, {
    limit: 20,
    windowMs: 1000,
    burstLimit: 100,
    burstWindowMs: 10_000,
  });

  if (!rateCheck.allowed) {
    return new Response(JSON.stringify({ 
      error: rateCheck.isFlooding ? 'Too many requests - please slow down' : 'Rate limit exceeded' 
    }), {
      status: 429,
      headers: { 'Content-Type': 'application/json', 'Retry-After': '1' },
    });
  }

  recordRequest(request, 1000);

  // Check authentication
  const { user, error: authError, setCookieHeader } = await requireApiAuth(request);
  if (authError) return authError;
  
  // Helper to create responses with optional Set-Cookie header
  const createResponse = (data, status = 200) => {
    const headers = new Headers({ 'Content-Type': 'application/json' });
    if (setCookieHeader) {
      const cookies = Array.isArray(setCookieHeader) ? setCookieHeader : [setCookieHeader];
      for (const c of cookies) if (c) headers.append('Set-Cookie', c.trim());
    }
    return new Response(JSON.stringify(data), { status, headers });
  };

  // Helper to validate Discord snowflake IDs (17-20 digit strings)
  const isValidSnowflake = (id) => !id || /^\d{17,20}$/.test(id);

  try {
    const url = new URL(request.url);
    const messageId = url.searchParams.get('messageId');
    const emojiName = url.searchParams.get('emojiName');
    const emojiId = url.searchParams.get('emojiId'); // null for unicode emoji

    if (!messageId || !emojiName) {
      return createResponse({ error: 'messageId and emojiName are required' }, 400);
    }

    // Validate snowflake formats
    if (!isValidSnowflake(messageId) || !isValidSnowflake(emojiId)) {
      return createResponse({ error: 'Invalid ID format' }, 400);
    }

    // Get the guild_id from the message's channel for proper display names
    const messageInfo = await sql`
      SELECT c.guild_id 
      FROM messages m
      JOIN channels c ON m.channel_id = c.channel_id
      WHERE m.message_id = ${messageId}
    `;
    const guildId = messageInfo[0]?.guild_id;

    // Fetch users who reacted with this emoji
    let users;
    if (emojiId) {
      users = await sql`
        SELECT DISTINCT ON (u.user_id)
          u.user_id,
          u.username,
          u.avatar_url,
          u.cached_avatar_id,
          COALESCE(gm.nickname, u.global_name, u.username) as display_name,
          COALESCE(gm.guild_avatar_url, u.avatar_url) as guild_avatar,
          gm.cached_guild_avatar_id,
          r.added_at
        FROM reactions r
        JOIN users u ON r.user_id = u.user_id
        LEFT JOIN guild_members gm ON u.user_id = gm.user_id AND gm.guild_id = ${guildId}
        WHERE r.message_id = ${messageId}
          AND r.emoji_name = ${emojiName}
          AND r.emoji_id = ${emojiId}
          AND r.is_removed = FALSE
        ORDER BY u.user_id, r.added_at ASC
      `;
    } else {
      users = await sql`
        SELECT DISTINCT ON (u.user_id)
          u.user_id,
          u.username,
          u.avatar_url,
          u.cached_avatar_id,
          COALESCE(gm.nickname, u.global_name, u.username) as display_name,
          COALESCE(gm.guild_avatar_url, u.avatar_url) as guild_avatar,
          gm.cached_guild_avatar_id,
          r.added_at
        FROM reactions r
        JOIN users u ON r.user_id = u.user_id
        LEFT JOIN guild_members gm ON u.user_id = gm.user_id AND gm.guild_id = ${guildId}
        WHERE r.message_id = ${messageId}
          AND r.emoji_name = ${emojiName}
          AND r.emoji_id IS NULL
          AND r.is_removed = FALSE
        ORDER BY u.user_id, r.added_at ASC
      `;
    }

    const formattedUsers = users.map(u => {
      // Prefer cached avatar
      const cachedAvatarId = u.cached_guild_avatar_id || u.cached_avatar_id;
      let avatar;
      if (cachedAvatarId) {
        const sig = signImageId(cachedAvatarId);
        avatar = `/api/discord/cached-image?id=${cachedAvatarId}&sig=${sig}`;
      } else {
        avatar = u.guild_avatar || u.avatar_url;
      }
      
      return {
        id: u.user_id.toString(),
        username: u.username,
        displayName: u.display_name,
        avatar,
      };
    });

    return createResponse(formattedUsers);
  } catch (error) {
    console.error('Error fetching reaction users:', error);
    return createResponse({ error: 'Failed to fetch reaction users' }, 500);
  }
}
