import { Events, Game as GameTypes } from "../../types";
import { API } from "../../utils";
import { Game } from "../game";
import { Ribbon } from "../ribbon";
import { Room } from "../room";
import { Social } from "../social";
import { ClientUtils } from "../utils";
import { ClientOptions, ClientUser } from "./types";
export type * from "./types";
export declare class Client {
    /** User information */
    user: ClientUser;
    /** Whether the client has been disconnected. If true, the client needs to be reconnected with `.reconnect()` or destroyed */
    disconnected: boolean;
    /**
     * Utils for the client.
     * @deprecated - functionality has been moved to other sections. This may be removed in the future.
     */
    utils: ClientUtils;
    /** The client's token */
    token: string;
    /** @hidden */
    private _handling;
    /** Raw ribbon client, the backbone of TETR.IO multiplayer. You probably don't want to touch this unless you know what you are doing. */
    ribbon: Ribbon;
    /** A helpful manager for all things social on TETR.IO (friends, dms etc.) */
    social: Social;
    /** The room the client is in (if it is in a room). You can make it non-nullable with `client.room!` */
    room?: Room;
    /** The game the client is currently in if it is in a game. */
    game?: Game;
    /** Useful for connecting to the main game API when none of the client helpers have the request you want to send. You can use `client.api.get` and `client.api.post` to easily send GET and POST requests. */
    api: API;
    rooms: {
        list(): ReturnType<API["rooms"]>;
        join(id: string): Promise<Room>;
        create(type?: "public" | "private"): Promise<Room>;
    };
    /**
     * Raw ribbon handler.
     * @example
     * client.on('social.dm', () => console.log('DM received!'));
     */
    on: typeof this.ribbon.emitter.on;
    /** Raw ribbon handler. */
    off: typeof this.ribbon.emitter.off;
    /** Raw ribbon handler. You likely want to use `client.wait` instead. */
    once: typeof this.ribbon.emitter.once;
    /** Raw ribbon handler for sending messages. */
    emit: typeof this.ribbon.emit;
    /** @hideconstructor */
    private constructor();
    /**
     * Create a new client
     * @example
     * const client = await Client.connect({ token: 'your.jwt.token' });
     * @example
     * const client = await Client.connect({ username: 'halp', password: 'password' });
     * @example
     * // If playing games, pass in handling
     * const client = await Client.connect({
     *   // ...login info
     *   handling: {
     *     arr: 0,
     *     cancel: false,
     *     das: 5,
     *     dcd: 0,
     *     safelock: false,
     *     may20g: true,
     *     sdf: 41
     *   };
     * });
     * @example
     * // You can pass in a custom user agent
     * const client = await Client.connect({
     *   // ...login info
     *   userAgent: "v8/001"
     * });
     */
    static connect(options: ClientOptions): Promise<Client>;
    /**
     * Wait for an event to occur. Wraps `client.once` into a typed Promise.
     * @returns the data from the event
     * @example
     * // wait for a notification (although you probably want to use `client.on` for this instead)
     * console.log(await client.wait('social.notification'));
     */
    wait<T extends keyof Events.in.all>(event: T): Promise<Events.in.all[T]>;
    /**
     * Send a message and then wait for another message. Throws an error if a 'err' message is received before the response message
     * @param event - the `command` of the event to send
     * @param data - the data to send along with the command. For void (no) data, just pass in `undefined`
     * @param listen - the event to wait for before resolving.
     * @param error - a list of custom error events to listen for. Defaults to `[client.error]`.
     * @returns the data sent by the `listen` event
     * @throws an error if the error event provided (or `client.error`) is received from TETR.IO
     * @example
     * // This is just for example, use `client.room!.chat` instead
     * await client.wrap('room.chat', { content: 'Hello', pinned: false }, 'room.chat');
     */
    wrap<O extends keyof Events.out.all, I extends keyof Events.in.all>(event: O, data: Events.out.all[O], listen: I, error?: (keyof Events.in.all)[]): Promise<Events.in.all[I]>;
    /** @hidden */
    private init;
    /**
     * Reconnect the client to TETR.IO.
     * @throws {Error} if the client is already connected
     */
    reconnect(): Promise<void>;
    /** The client's current handling. */
    get handling(): GameTypes.Handling;
    /** Change the client's current handling (do not use while in a room) */
    set handling(handling: GameTypes.Handling);
    /** Clean up the client */
    destroy(): Promise<void>;
}
