import { Room } from '../Room.ts';
import type { Client } from '../Transport.ts';
import type { IRoomCache } from '../matchmaker/driver.ts';
import * as matchMaker from '../MatchMaker.ts';
export interface QueueOptions {
    /**
     * number of players on each match
     */
    maxPlayers?: number;
    /**
     * name of the room to create
     */
    matchRoomName: string;
    /**
     * after these cycles, create a match with a bot
     */
    maxWaitingCycles?: number;
    /**
     * after this time, try to fit this client with a not-so-compatible group
     */
    maxWaitingCyclesForPriority?: number;
    /**
     * If set, teams must have the same size to be matched together
     */
    maxTeamSize?: number;
    /**
     * If `allowIncompleteGroups` is true, players inside an unmatched group (that
     * did not reached `maxPlayers`, and `maxWaitingCycles` has been
     * reached) will be matched together. Your room should fill the remaining
     * spots with "bots" on this case.
     */
    allowIncompleteGroups?: boolean;
    /**
     * Comparison function for matching clients to groups
     * Returns true if the client is compatible with the group
     */
    compare?: (client: QueueClientData, matchGroup: QueueMatchGroup) => boolean;
    /**
     *
     * When onGroupReady is set, the "roomNameToCreate" option is ignored.
     */
    onGroupReady?: (this: QueueRoom, group: QueueMatchGroup) => Promise<IRoomCache>;
}
export interface QueueMatchGroup {
    averageRank: number;
    clients: Array<Client<{
        userData: QueueClientData;
    }>>;
    ready?: boolean;
    confirmed?: number;
}
export interface QueueMatchTeam {
    averageRank: number;
    clients: Array<Client<{
        userData: QueueClientData;
    }>>;
    teamId: string | symbol;
}
export interface QueueClientData {
    /**
     * Rank of the client
     */
    rank: number;
    /**
     * Timestamp of when the client entered the queue
     */
    currentCycle?: number;
    /**
     * Optional: if matching with a team, the team ID
     */
    teamId?: string;
    /**
     * Additional options passed by the client when joining the room
     */
    options?: any;
    /**
     * Match group the client is currently in
     */
    group?: QueueMatchGroup;
    /**
     * Whether the client has confirmed the connection to the room
     */
    confirmed?: boolean;
    /**
     * Whether the client should be prioritized in the queue
     * (e.g. for players that are waiting for a long time)
     */
    highPriority?: boolean;
    /**
     * The last number of clients in the queue sent to the client
     */
    lastQueueClientCount?: number;
}
type QueueClient = Client<{
    userData: QueueClientData;
    messages: {
        clients: number;
        seat: matchMaker.ISeatReservation;
    };
}>;
export declare class QueueRoom extends Room {
    maxPlayers: number;
    maxTeamSize: number;
    allowIncompleteGroups: boolean;
    maxWaitingCycles: number;
    maxWaitingCyclesForPriority?: number;
    /**
     * Evaluate groups for each client at interval
     */
    cycleTickInterval: number;
    /**
     * Groups of players per iteration
     */
    groups: QueueMatchGroup[];
    highPriorityGroups: QueueMatchGroup[];
    matchRoomName: string;
    protected compare: (client: QueueClientData, matchGroup: QueueMatchGroup) => boolean;
    protected onGroupReady: (group: QueueMatchGroup) => Promise<IRoomCache<any>>;
    messages: {
        confirm: (client: Client, _: unknown) => void;
    };
    onCreate(options: QueueOptions): void;
    onJoin(client: QueueClient, options: any, auth?: unknown): void;
    addToQueue(client: QueueClient, queueData: QueueClientData): void;
    createMatchGroup(): QueueMatchGroup;
    reassignMatchGroups(): void;
    redistributeTeams(sortedClients: Client<{
        userData: QueueClientData;
    }>[]): void;
    redistributeClients(sortedClients: Client<{
        userData: QueueClientData;
    }>[], currentGroup?: QueueMatchGroup, totalRank?: number): QueueMatchGroup;
    evaluateHighPriorityGroups(): void;
    processGroupsReady(): void;
}
export {};
