import { BanEntry, User } from '../../../../shared-kernel';

type BanAwareUser = Pick<User, 'id' | 'oderId'> | null | undefined;

/** Build the set of user identifiers that may appear in room ban entries. */
export function getRoomBanCandidateIds(user: BanAwareUser, persistedUserId?: string | null): string[] {
  const candidates = [
    user?.id,
    user?.oderId,
    persistedUserId
  ].filter((value): value is string => typeof value === 'string' && value.trim().length > 0);

  return Array.from(new Set(candidates));
}

/** Resolve the user identifier stored by a ban entry, with legacy fallback support. */
export function getRoomBanTargetId(ban: Pick<BanEntry, 'userId' | 'oderId'>): string {
  if (typeof ban.userId === 'string' && ban.userId.trim().length > 0) {
    return ban.userId;
  }

  return ban.oderId;
}

/** Return true when the given ban targets the provided user. */
export function isRoomBanMatch(
  ban: Pick<BanEntry, 'userId' | 'oderId'>,
  user: BanAwareUser,
  persistedUserId?: string | null
): boolean {
  const candidateIds = getRoomBanCandidateIds(user, persistedUserId);

  if (candidateIds.length === 0) {
    return false;
  }

  return candidateIds.includes(getRoomBanTargetId(ban));
}

/** Return true when any active ban entry targets the provided user. */
export function hasRoomBanForUser(
  bans: Pick<BanEntry, 'userId' | 'oderId'>[],
  user: BanAwareUser,
  persistedUserId?: string | null
): boolean {
  return bans.some((ban) => isRoomBanMatch(ban, user, persistedUserId));
}
