import { PrismaService } from 'src/prisma/prisma.service';

/**
 * Qué módulos y privilegios tiene un usuario, resuelto una sola vez para filtrar
 * una lista de alertas en memoria. Mismo criterio que `PermissionGuard`:
 *
 * - Holding / reseller: sin suscripción propia, ven todos los módulos.
 * - Superadmin: todos los privilegios, pero sólo sobre los módulos del plan.
 * - Resto: módulos activos de la suscripción + privilegios de sus perfiles.
 */
export interface ContextoPermisos {
  /** Holding o reseller: no se filtra por módulo. */
  todosLosModulos: boolean;
  /** Superadmin (o holding/reseller): no se filtra por privilegio. */
  todosLosPrivilegios: boolean;
  modulos: Set<string>;
  privilegios: Set<string>;
}

export async function contextoPermisosUsuario(
  prisma: PrismaService,
  usuarioId: string,
  empresaId: string,
): Promise<ContextoPermisos> {
  const [usuario, empresa] = await Promise.all([
    prisma.usuario.findUnique({ where: { id: usuarioId }, select: { is_superadmin: true } }),
    prisma.empresas.findUnique({ where: { id: empresaId }, select: { type: true } }),
  ]);
  const holdingOReseller = empresa?.type === 'holding' || empresa?.type === 'reseller';
  const superadmin = usuario?.is_superadmin ?? false;

  const [modulosActivos, privilegiosPerfil] = await Promise.all([
    holdingOReseller
      ? Promise.resolve([])
      : prisma.suscripcion_modulos.findMany({
          where: {
            activo: true,
            suscripciones: { empresa_id: empresaId, estado: { in: ['Activo', 'EnGracia'] } },
            modulos: { active: true },
          },
          select: { modulos: { select: { codigo: true } } },
        }),
    superadmin || holdingOReseller
      ? Promise.resolve([])
      : prisma.perfiles_privilegios.findMany({
          where: { active: true, perfiles: { usuario_perfiles: { some: { user_id: usuarioId } } } },
          select: { privilegios: { select: { codigo: true } } },
        }),
  ]);

  return {
    todosLosModulos: holdingOReseller,
    todosLosPrivilegios: superadmin || holdingOReseller,
    modulos: new Set(modulosActivos.map((m) => m.modulos?.codigo).filter((c): c is string => !!c)),
    privilegios: new Set(privilegiosPerfil.map((p) => p.privilegios?.codigo).filter((c): c is string => !!c)),
  };
}

export function puedeVerAlerta(
  ctx: ContextoPermisos,
  alerta: { modulo: string | null; privilegio_requerido: string | null },
): boolean {
  if (alerta.modulo && !ctx.todosLosModulos && !ctx.modulos.has(alerta.modulo)) return false;
  if (alerta.privilegio_requerido && !ctx.todosLosPrivilegios && !ctx.privilegios.has(alerta.privilegio_requerido)) {
    return false;
  }
  return true;
}
