import { prisma } from "@capakraken/db";

type PrismaClient = typeof prisma;

/**
 * Resolve recipient user IDs for a broadcast target.
 * Deduplicates results and optionally excludes the sender.
 */
export async function resolveRecipients(
  targetType: string,
  targetValue: string | null | undefined,
  db: PrismaClient,
  excludeUserId?: string,
): Promise<string[]> {
  let userIds: string[] = [];

  switch (targetType) {
    case "user":
      if (targetValue) userIds = [targetValue];
      break;

    case "role": {
      // Find all users with the given systemRole
      const roleUsers = await db.user.findMany({
        where: { systemRole: targetValue as "ADMIN" | "MANAGER" | "CONTROLLER" | "USER" | "VIEWER" },
        select: { id: true },
      });
      userIds = roleUsers.map((u) => u.id);
      break;
    }

    case "project": {
      // Find all resources with assignments on this project, then their linked users
      if (!targetValue) break;
      const assignments = await db.assignment.findMany({
        where: { projectId: targetValue, status: { not: "CANCELLED" } },
        select: { resource: { select: { userId: true } } },
      });
      userIds = assignments
        .map((a) => a.resource.userId)
        .filter((id): id is string => !!id);
      break;
    }

    case "orgUnit": {
      // Find all resources in this orgUnit, then their linked users
      if (!targetValue) break;
      const resources = await db.resource.findMany({
        where: { orgUnitId: targetValue, isActive: true },
        select: { userId: true },
      });
      userIds = resources
        .map((r) => r.userId)
        .filter((id): id is string => !!id);
      break;
    }

    case "all": {
      // User model has no isActive — get all users
      const allUsers = await db.user.findMany({
        select: { id: true },
      });
      userIds = allUsers.map((u) => u.id);
      break;
    }
  }

  // Deduplicate and exclude sender
  const unique = [...new Set(userIds)];
  return excludeUserId ? unique.filter((id) => id !== excludeUserId) : unique;
}
