import { EventEmitter } from "events";
import { LavalinkNode } from "./LavalinkNode";
import { Player } from "./Player";
import WebSocket from "ws";
import type { JoinData, VoiceServerUpdate, VoiceStateUpdate, DiscordPacket, ManagerOptions, JoinOptions, LavalinkNodeOptions } from "./Types";
/**
 * The class that handles everything to do with Lavalink. it is the hub of the library basically
 */
export declare class Manager extends EventEmitter {
    /**
     * A [**Map**](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map) of Lavalink Nodes
     */
    nodes: Map<string, LavalinkNode>;
    /**
     * A [**Map**](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map) of all the players
     */
    players: Map<string, Player>;
    /**
     * A [**Map**](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map) of all the VOICE_SERVER_UPDATE States
     */
    voiceServers: Map<string, VoiceServerUpdate>;
    /**
     * A [**Map**](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map) of all the VOICE_STATE_UPDATE States
     */
    voiceStates: Map<string, VoiceStateUpdate>;
    /**
     * The user id of the bot this Manager is managing
     */
    user: string;
    /**
     * The send function needs for the library to function
     */
    send?: (packet: DiscordPacket) => unknown;
    /**
     * The Player the manager will use when creating new Players
     */
    private readonly Player;
    /**
     * An Set of all the expecting connections guild id's
     */
    private readonly expecting;
    /**
     * The constructor of the Manager
     * @param nodes A Array of {@link LavalinkNodeOptions} that the Manager will connect to
     * @param options The options for the Manager {@link ManagerOptions}
     */
    constructor(nodes: Array<LavalinkNodeOptions>, options: ManagerOptions);
    /**
     * Connects all the {@link LavalinkNode} to the respective Lavalink instance
     */
    connect(): Promise<Array<WebSocket>>;
    /**
     * Disconnects everything, basically destorying the manager.
     * Stops all players, leaves all voice channels then disconnects all LavalinkNodes
     */
    disconnect(): Promise<Array<boolean>>;
    /**
     * Creating a {@link LavalinkNode} and adds it to the the nodes Map
     * @param options The node options of the node you're creating
     */
    createNode(options: LavalinkNodeOptions): LavalinkNode;
    /**
     * Disconnects and Deletes the specified node
     * @param id The id of the node you want to remove
     */
    removeNode(id: string): boolean;
    /**
     * Connects the bot to the selected voice channel
     * @param data The Join Data
     * @param joinOptions Selfmute and Selfdeaf options, if you want the bot to be deafen or muted upon joining
     */
    join(data: JoinData, joinOptions?: JoinOptions): Promise<Player>;
    /**
     * Leaves the specified voice channel
     * @param guild The guild you want the bot to leave the voice channel of
     */
    leave(guild: string): Promise<boolean>;
    /**
     * Switch a player from one node to another, this is to implement fallback
     * @param player The player you want to switch nodes with
     * @param node The node you want to switch to
     */
    switch(player: Player, node: LavalinkNode): Promise<Player>;
    /**
     * For handling voiceServerUpdate from the user's library of choice
     * @param data The data directly from discord
     */
    voiceServerUpdate(data: VoiceServerUpdate): Promise<boolean>;
    /**
     * For handling voiceStateUpdate from the user's library of choice
     * @param data The data directly from discord
     */
    voiceStateUpdate(data: VoiceStateUpdate): Promise<boolean>;
    /**
     * Just a utility method to easily send OPCode 4 websocket events to discord
     * @param guild The guild is
     * @param channel Voice channel id, or null to leave a voice channel
     * @param param2 Selfmute and Selfdeaf options, if you want the bot to be deafen or muted upon joining
     */
    sendWS(guild: string, channel: string | null, { selfmute, selfdeaf }?: JoinOptions): any;
    /**
     * Gets all connected nodes, sorts them by cou load of the node
     */
    get idealNodes(): Array<LavalinkNode>;
    /**
     * Handles the data of voiceServerUpdate & voiceStateUpdate to see if a connection is possible with the data we have and if it is then make the connection to lavalink
     * @param guildId The guild id that we're trying to attempt to connect to
     */
    private _attemptConnection;
    /**
     * This creates the {@link Player}
     * @param data The Join Data, this is called by {@link Manager.join}
     */
    private spawnPlayer;
}
export interface ManagerEvents {
    ready: [LavalinkNode];
    raw: [unknown, LavalinkNode];
    error: [unknown, LavalinkNode];
    disconnect: [number, string, LavalinkNode];
    reconnecting: [LavalinkNode];
}
export interface Manager {
    addListener<E extends keyof ManagerEvents>(event: E, listener: (...args: ManagerEvents[E]) => any): this;
    emit<E extends keyof ManagerEvents>(event: E, ...args: ManagerEvents[E]): boolean;
    eventNames(): Array<keyof ManagerEvents>;
    listenerCount(event: keyof ManagerEvents): number;
    listeners(event: keyof ManagerEvents): Array<(...args: Array<any>) => any>;
    off<E extends keyof ManagerEvents>(event: E, listener: (...args: ManagerEvents[E]) => any): this;
    on<E extends keyof ManagerEvents>(event: E, listener: (...args: ManagerEvents[E]) => any): this;
    once<E extends keyof ManagerEvents>(event: E, listener: (...args: ManagerEvents[E]) => any): this;
    prependListener<E extends keyof ManagerEvents>(event: E, listener: (...args: ManagerEvents[E]) => any): this;
    prependOnceListener<E extends keyof ManagerEvents>(event: E, listener: (...args: ManagerEvents[E]) => any): this;
    rawListeners(event: keyof ManagerEvents): Array<(...args: Array<any>) => any>;
    removeAllListeners(event?: keyof ManagerEvents): this;
    removeListener<E extends keyof ManagerEvents>(event: E, listener: (...args: ManagerEvents[E]) => any): this;
}
