import { getRoomData } from "./store";
import { prisma } from "./prisma";
import type { RoomStatus, MatchType, UserProfile } from "@/types";

export async function buildRoomStatus(
  roomId: string,
): Promise<RoomStatus | null> {
  const data = await getRoomData(roomId);
  if (!data) return null;

  const total = data.restaurants.length;
  const allFinished =
    data.users.length > 0 &&
    data.users.every((u) => (data.swipeCounts[u] ?? 0) >= total);

  let match = data.match;
  let matchType: MatchType = null;
  let matchLikes = 0;
  let runnerUps: { id: string; likes: number }[] = [];

  if (match) {
    matchType = "unanimous";
    matchLikes = data.users.length;
  } else if (allFinished && data.restaurants.length > 0) {
    const ranked = rankRestaurants(data.likes, data.restaurants);
    if (ranked[0].likes > 0) {
      match = ranked[0].id;
      matchType = "best";
      matchLikes = ranked[0].likes;
      runnerUps = ranked.slice(1, 3).filter((r) => r.likes > 0);
    } else {
      match = ranked[0].id;
      matchType = "no_match";
      matchLikes = 0;
    }
  }

  const likeCounts: Record<string, number> = {};
  for (const [rid, users] of Object.entries(data.likes)) {
    if (users.length > 0) {
      likeCounts[rid] = users.length;
    }
  }

  const userProfiles: Record<string, UserProfile> = {};
  if (data.users.length > 0) {
    const dbUsers = await prisma.user.findMany({
      where: { id: { in: data.users } },
      select: { id: true, username: true, avatar: true },
    });
    for (const u of dbUsers) {
      userProfiles[u.id] = { id: u.id, username: u.username, avatar: u.avatar };
    }
  }

  return {
    roomId,
    userCount: data.users.length,
    match,
    matchType,
    matchLikes,
    runnerUps,
    likeCounts,
    swipeCounts: data.swipeCounts,
    restaurants: data.restaurants,
    creatorId: data.creatorId,
    locked: data.locked,
    users: data.users,
    userProfiles,
    scene: data.scene,
  };
}

function rankRestaurants(
  likes: Record<string, string[]>,
  restaurants: { id: string; rating: number }[],
): { id: string; likes: number }[] {
  return restaurants
    .map((r) => ({
      id: r.id,
      likes: likes[r.id]?.length ?? 0,
      rating: r.rating,
    }))
    .sort((a, b) => b.likes - a.likes || b.rating - a.rating)
    .map(({ id, likes: l }) => ({ id, likes: l }));
}
