import { DB, Selectable, Transaction } from "../generated/kysely-tailordb";

export const recomputeUserPermissions = async (
  db: DB | Transaction,
  userId: string,
): Promise<Selectable<"User">> => {
  // The User.status = ACTIVE join keeps permissions empty for PENDING/INACTIVE users.
  const roles = await db
    .selectFrom("UserRole")
    .innerJoin("Role", "Role.id", "UserRole.roleId")
    .innerJoin("User", "User.id", "UserRole.userId")
    .select("Role.permissions")
    .where("UserRole.userId", "=", userId)
    .where("Role.status", "=", "ACTIVE")
    .where("User.status", "=", "ACTIVE")
    .execute();

  // Flatten all permissions arrays, deduplicate, sort
  const permissions = [...new Set(roles.flatMap((r) => r.permissions ?? []))].sort();

  return db
    .updateTable("User")
    .set({ permissions })
    .where("id", "=", userId)
    .returningAll()
    .executeTakeFirstOrThrow();
};

export const recomputePermissionsForUsersWithRole = async (
  db: DB | Transaction,
  roleId: string,
): Promise<Selectable<"User">[]> => {
  const userRoles = await db
    .selectFrom("UserRole")
    .select("userId")
    .where("roleId", "=", roleId)
    .execute();

  const updatedUsers = [];
  for (const { userId } of userRoles) {
    updatedUsers.push(await recomputeUserPermissions(db, userId));
  }
  return updatedUsers;
};
