import EventEmitter from 'node:events';
import { OutgoingHttpHeaders, IncomingHttpHeaders, IncomingMessage } from 'node:http';
import { URL, URLSearchParams } from 'node:url';
import { APIClanWarLog, APIClan, APIRiverRaceLogEntry, APICurrentRiverRace, APIPlayer, APIChestList, APIBattleList, APIItem, APITournament, APIChallengeChain, APILadderTournament, APILeagueSeason, APILocation, APILadderTournamentRanking, APIArena, APIGameMode, APIChallenge, Path, ResponseType, ValueOf, APIChallengeChainsList, APIClanList, APIClanRanking, APIPlayerRankingClan, APIRiverRaceClan, APIClanMemberList, APIClanRankingList, APIItemList, APILadderTournamentRankingList, APILeagueSeasonList, APILocationList, APIClanMember, APIPlayerRanking, APIPlayerRankingList, APIRiverRaceLog, APITournamentHeaderList } from 'royale-api-types';
export * from 'royale-api-types';
import BaseCollection, { Comparator } from '@discordjs/collection';

/**
 * Events that can be emitted by the client
 */
interface ClientEvents {
    requestStart: [request: APIRequest];
    requestEnd: [request: APIRequest, response: Response];
    clanWarLogAdd: [warLog: APIClanWarLog];
    clanWarLogUpdate: [oldWarLog: APIClanWarLog, newWarLog: APIClanWarLog];
    clanAdd: [clan: APIClan];
    clanRemove: [clan: APIClan];
    clanUpdate: [oldClan: APIClan, newClan: APIClan];
    riverRaceLogEntryAdd: [entry: APIRiverRaceLogEntry];
    riverRaceLogEntryRemove: [entry: APIRiverRaceLogEntry];
    riverRaceLogEntryUpdate: [
        oldEntry: APIRiverRaceLogEntry,
        newEntry: APIRiverRaceLogEntry
    ];
    currentRiverRaceAdd: [race: APICurrentRiverRace];
    currentRiverRaceRemove: [race: APICurrentRiverRace];
    currentRiverRaceUpdate: [
        oldRace: APICurrentRiverRace,
        newRace: APICurrentRiverRace
    ];
    playerAdd: [player: APIPlayer];
    playerRemove: [player: APIPlayer];
    playerUpdate: [oldMember: APIPlayer, newMember: APIPlayer];
    chestListAdd: [chestList: APIChestList];
    chestListRemove: [chestList: APIChestList];
    chestListUpdate: [oldChestList: APIChestList, newChestList: APIChestList];
    battleListAdd: [battleList: APIBattleList];
    battleListRemove: [battleList: APIBattleList];
    battleListUpdate: [
        oldBattleList: APIBattleList,
        newBattleList: APIBattleList
    ];
    itemAdd: [item: APIItem];
    itemRemove: [item: APIItem];
    itemUpdate: [oldItem: APIItem, newItem: APIItem];
    tournamentAdd: [tournament: APITournament];
    tournamentRemove: [tournament: APITournament];
    tournamentUpdate: [
        oldTournament: APITournament,
        newTournament: APITournament
    ];
    challengeChainAdd: [challengeChain: APIChallengeChain];
    challengeChainRemove: [challengeChain: APIChallengeChain];
    challengeChainUpdate: [
        oldChallengeChain: APIChallengeChain,
        newChallengeChain: APIChallengeChain
    ];
    ladderTournamentAdd: [ladderTournament: APILadderTournament];
    ladderTournamentRemove: [ladderTournament: APILadderTournament];
    ladderTournamentUpdate: [
        oldLadderTournament: APILadderTournament,
        newLadderTournament: APILadderTournament
    ];
    leagueSeasonAdd: [leagueSeason: APILeagueSeason];
    leagueSeasonRemove: [leagueSeason: APILeagueSeason];
    leagueSeasonUpdate: [
        oldLeagueSeason: APILeagueSeason,
        newLeagueSeason: APILeagueSeason
    ];
    locationAdd: [location: APILocation];
    locationRemove: [location: APILocation];
    locationUpdate: [oldLocation: APILocation, newLocation: APILocation];
    ladderTournamentRankingAdd: [
        ladderTournamentRanking: APILadderTournamentRanking
    ];
    ladderTournamentRankingRemove: [
        ladderTournamentRanking: APILadderTournamentRanking
    ];
    ladderTournamentRankingUpdate: [
        oldLadderTournamentRanking: APILadderTournamentRanking,
        newLadderTournamentRanking: APILadderTournamentRanking
    ];
    arenaAdd: [arena: APIArena];
    arenaRemove: [arena: APIArena];
    arenaUpdate: [oldArena: APIArena, newArena: APIArena];
    gameModeAdd: [gameMode: APIGameMode];
    gameModeRemove: [gameMode: APIGameMode];
    gameModeUpdate: [oldGameMode: APIGameMode, newGameMode: APIGameMode];
    challengeAdd: [challenge: APIChallenge];
    challengeRemove: [challenge: APIChallenge];
    challengeUpdate: [oldChallenge: APIChallenge, newChallenge: APIChallenge];
}
/**
 * Options to instantiate a client
 */
declare type ClientOptions = CacheOptions & RestOptions;
declare const enum Constants {
    /**
     * The value to pass to the `Accept` header
     */
    acceptHeader = "application/json",
    /**
     * The prefix to use for the `Authorization` header
     */
    authorizationHeaderPrefix = "Bearer ",
    /**
     * The base URL for the API
     */
    baseURL = "https://api.clashroyale.com/v1",
    /**
     * Default maximum time in milliseconds before cancelling a REST request
     */
    defaultAbortTimeout = 10000,
    /**
     * Minimum number of characters in a clan name
     */
    minClanNameLength = 3,
    /**
     * Minimum number of characters in a tournament name
     */
    minTournamentNameLength = 3
}
/**
 * Cache options for the client
 */
interface CacheOptions {
    /**
     * Whether to cache a fetched structure
     */
    cache?: boolean;
    /**
     * Whether to cache the nested structures of a fetched structure
     */
    cacheNested?: boolean;
}
/**
 * Error messages
 */
declare const Errors: {
    readonly missingAfter: () => "The next page isn't available";
    readonly missingBefore: () => "The previous page isn't available";
    readonly missingQuery: () => "You didn't provide any query";
    readonly requestAborted: (path: Path, maxAge: number) => `Request to path /clans/${string}/warlog took more than ${number} milliseconds and was aborted before ending` | `Request to path /clans took more than ${number} milliseconds and was aborted before ending` | `Request to path /clans/${string}/riverracelog took more than ${number} milliseconds and was aborted before ending` | `Request to path /clans/${string} took more than ${number} milliseconds and was aborted before ending` | `Request to path /clans/${string}/members took more than ${number} milliseconds and was aborted before ending` | `Request to path /clans/${string}/currentriverrace took more than ${number} milliseconds and was aborted before ending` | `Request to path /players/${string} took more than ${number} milliseconds and was aborted before ending` | `Request to path /players/${string}/upcomingchests took more than ${number} milliseconds and was aborted before ending` | `Request to path /players/${string}/battlelog took more than ${number} milliseconds and was aborted before ending` | `Request to path /cards took more than ${number} milliseconds and was aborted before ending` | `Request to path /tournaments took more than ${number} milliseconds and was aborted before ending` | `Request to path /tournaments/${string} took more than ${number} milliseconds and was aborted before ending` | `Request to path /locations/${number}/rankings/clans took more than ${number} milliseconds and was aborted before ending` | `Request to path /locations/${number}/rankings/players took more than ${number} milliseconds and was aborted before ending` | `Request to path /locations/${number}/rankings/clanwars took more than ${number} milliseconds and was aborted before ending` | `Request to path /locations/global/seasons/${string} took more than ${number} milliseconds and was aborted before ending` | `Request to path /locations/global/seasons/${string}/rankings/players took more than ${number} milliseconds and was aborted before ending` | `Request to path /locations/global/seasons took more than ${number} milliseconds and was aborted before ending` | `Request to path /locations took more than ${number} milliseconds and was aborted before ending` | `Request to path /locations/${number} took more than ${number} milliseconds and was aborted before ending` | `Request to path /locations/global/rankings/tournaments/${string} took more than ${number} milliseconds and was aborted before ending` | `Request to path /challenges took more than ${number} milliseconds and was aborted before ending` | `Request to path /globaltournaments took more than ${number} milliseconds and was aborted before ending`;
    readonly requestError: (url: URL, error: Error) => `Request to ${string} failed with reason: ${string}`;
    readonly restRateLimited: () => "The rest is ratelimited so no other requests are allowed until you set the force option to true";
    readonly tokenMissing: () => "No token provided for the client";
    readonly clanMaxMembersTooLow: () => "The maximum number of members must be greater than or equal to the minimum and positive";
    readonly clanMinMembersNotPositive: () => "The minimum number of members must be a positive number";
    readonly clanMinScoreNotPositive: () => "The minimum score must be a positive number";
    readonly clanNameSearchTooShort: () => "The clan name must be at least 3 characters long";
    readonly tournamentNameSearchTooShort: () => "The tournament name must be at least 3 characters long";
};
/**
 * Options for fetching a clan's members
 */
interface FetchClanMembersOptions extends ListOptions {
    /**
     * The tag of the clan
     */
    tag: string;
}
/**
 * Options to fetch a structure
 */
interface FetchOptions extends CacheOptions {
    /**
     * Whether to skip the cache and fetch from the API
     */
    force?: boolean;
}
/**
 * Options for fetching a player's upcoming chests
 */
interface FetchPlayerUpcomingChestsOptions {
    /**
     * Whether to skip the cache and fetch from the API
     */
    force?: boolean;
    /**
     * The tag of the player
     */
    tag: string;
}
/**
 * Options for fetching a river race log
 */
interface FetchRiverRaceLogOptions extends ListOptions {
    /**
     * The tag of the clan
     */
    tag: string;
}
/**
 * Any JSON data
 */
declare type Json = Json[] | boolean | number | string | {
    [property: string]: Json;
} | null;
/**
 * Base options for fetching a list
 */
interface ListOptions extends CacheOptions {
    /**
     * Return only items that occur after this marker.
     * This marker can be found in the search results, inside the 'paging' property.
     * Note that only after or before can be specified for a request, not both
     */
    after?: string;
    /**
     * Return only items that occur before this marker.
     * This marker can be found in the search results, inside the 'paging' property.
     * Note that only after or before can be specified for a request, not both
     */
    before?: string;
    /**
     * Limit the number of items returned in the response
     */
    limit?: number;
}
/**
 * Options for creating a manager
 */
interface ManagerOptions<V> {
    /**
     * The event to emit when a new structure is added
     */
    addEvent?: StructureEvents<V>;
    /**
     * The event to emit when a structure is removed
     */
    removeEvent?: StructureEvents<V>;
    /**
     * The event to emit when a structure is updated
     */
    updateEvent?: StructureEvents<V>;
}
interface QueuePromise {
    /**
     * The promise to resolve
     */
    promise: Promise<void>;
    /**
     * The resolve function of the promise
     */
    resolve(): void;
}
/**
 * The options for a request
 */
interface RequestOptions {
    /**
     * Headers to be sent for this request
     */
    headers?: OutgoingHttpHeaders;
    /**
     * The query of this request
     */
    query?: Iterable<[string, string]> | Record<string, string | readonly string[]> | URLSearchParams | string | readonly [string, string][];
}
interface RestOptions {
    /**
     * The token of the rest
     * This defaults to `process.env.CLASH_ROYALE_TOKEN` if none is provided
     */
    token?: Token;
    /**
     * The base URL of the rest
     */
    baseURL?: string;
    /**
     * The maximum time in milliseconds before cancelling a REST request
     */
    abortTimeout?: number;
}
/**
 * The response returned by the rest
 */
interface RestResponse<T extends Path> {
    data: ResponseType<T>;
    maxAge: number;
}
/**
 * Options for searching a clan
 */
interface SearchClanOptions extends ListOptions {
    /**
     * Clan location identifier
     */
    location?: number;
    /**
     * Maximum number of clan members
     */
    maxMembers?: number;
    /**
     * Minimum number of clan members
     */
    minMembers?: number;
    /**
     * Minimum amount of clan score
     */
    minScore?: number;
    /**
     * The name of the clan.
     * It needs to be at least three characters long.
     * Name search parameter is interpreted as wild card search, so it may appear anywhere in the clan name
     */
    name?: string;
}
/**
 * Options for searching a tournament
 */
interface SearchTournamentOptions extends ListOptions {
    /**
     * The name of the tournament.
     * It needs to be at least three characters long.
     * Name search parameter is interpreted as wild card search, so it may appear anywhere in the clan name
     */
    name?: string;
}
/**
 * Client events for a structure
 */
declare type StructureEvents<V> = ValueOf<{
    [K in keyof ClientEvents]: V extends ClientEvents[K][0] ? ClientEvents[K][0] extends V ? K : never : never;
}>;
/**
 * Options for adding a structure to a manager
 */
interface StructureOptions extends CacheOptions {
    /**
     * When this structure should be considered outdated
     */
    maxAge?: number;
}
/**
 * A valid token for the API
 */
declare type Token = `${string}.${string}.${string}`;

/**
 * Convert a date returned from the API to a Date object.
 * @param date - The date to convert
 * @returns The converted date
 */
declare const APIDateToObject: (date: string) => Date;
/**
 * Convert a date object to an API date.
 * @param date - The date to convert
 * @returns The converted date
 */
declare const dateObjectToAPIDate: (date?: Date | null | undefined) => string;

/**
 * Cast a value to a type.
 * @param _value - The value to cast
 * @template T - The type to cast to
 */
declare function cast<T>(_value: unknown): asserts _value is T;

/**
 * A custom collection
 */
declare class Collection<K, V> extends BaseCollection<K, V> {
    /**
     * Creates an array with the values of this collection.
     */
    array(): V[];
    /**
     * Creates an identical shallow copy of this collection.
     * @returns The cloned collection
     */
    clone(): Collection<K, V>;
    /**
     * Combines this collection with others into a new collection. None of the source collections are modified.
     * @param collections - Collections to merge
     */
    concat<K2, V2>(...collections: Collection<K2, V2>[]): Collection<K | K2, V | V2>;
    /**
     * The difference method returns a new structure containing items where the key is present in one of the original structures but not the other.
     * @param other - The other Collection to filter against
     */
    difference<T>(other: Collection<K, T>): Collection<K, T | V>;
    /**
     * Check if this collection has all the items of another collection.
     * @param collection - The collection to check against
     * @returns Whether or not this collection has all the items of another collection
     */
    equals(collection: Collection<K, V>): collection is this;
    /**
     * Identical to
     * [Array.filter()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/filter),
     * but returns a Collection instead of an Array.
     * @param fn - The function to test with
     * @param thisArg - Value to use as `this` when executing function
     */
    filter<K2 extends K>(fn: (value: V, key: K, collection: this) => key is K2): Collection<K2, V>;
    filter<V2 extends V>(fn: (value: V, key: K, collection: this) => value is V2): Collection<K, V2>;
    filter(fn: (value: V, key: K, collection: this) => boolean): Collection<K, V>;
    filter<This, K2 extends K>(fn: (this: This, value: V, key: K, collection: this) => key is K2, thisArg: This): Collection<K2, V>;
    filter<This, V2 extends V>(fn: (this: This, value: V, key: K, collection: this) => value is V2, thisArg: This): Collection<K, V2>;
    filter<This>(fn: (this: This, value: V, key: K, collection: this) => boolean, thisArg: This): Collection<K, V>;
    /**
     * Maps each item into a Collection, then joins the results into a single Collection. Identical in behavior to
     * [Array.flatMap()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/flatMap).
     * @param fn - Function that produces a new Collection
     * @param thisArg - Value to use as `this` when executing function
     */
    flatMap<T>(fn: (value: V, key: K, collection: this) => Collection<K, T>): Collection<K, T>;
    flatMap<T, This>(fn: (this: This, value: V, key: K, collection: this) => Collection<K, T>, thisArg: This): Collection<K, T>;
    /**
     * Returns the index of the first occurrence of a value in the collection, or -1 if it is not present.
     * @param searchElement - The value to locate in the collection
     * @returns The index of the first occurrence of a value in the collection, or -1 if it is not present
     */
    indexOf(searchElement: V): number;
    /**
     * The intersect method returns a new structure containing items where the keys and values are present in both original structures.
     * @param other - The other Collection to filter against
     */
    intersect<T>(other: Collection<K, T>): Collection<K, T>;
    /**
     * Maps each item to another value into a collection. Identical in behavior to
     * [Array.map()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map).
     * @param fn - Function that produces an element of the new collection, taking three arguments
     * @param thisArg - Value to use as `this` when executing function
     */
    mapValues<T>(fn: (value: V, key: K, collection: this) => T): Collection<K, T>;
    mapValues<This, T>(fn: (this: This, value: V, key: K, collection: this) => T, thisArg: This): Collection<K, T>;
    /**
     * Partitions the collection into two collections where the first collection
     * contains the items that passed and the second contains the items that failed.
     * @param fn - Function used to test
     * @param thisArg - Value to use as `this` when executing function
     */
    partition<K2 extends K>(fn: (value: V, key: K, collection: this) => key is K2): [Collection<K2, V>, Collection<Exclude<K, K2>, V>];
    partition<V2 extends V>(fn: (value: V, key: K, collection: this) => value is V2): [Collection<K, V2>, Collection<K, Exclude<V, V2>>];
    partition(fn: (value: V, key: K, collection: this) => boolean): [Collection<K, V>, Collection<K, V>];
    partition<This, K2 extends K>(fn: (this: This, value: V, key: K, collection: this) => key is K2, thisArg: This): [Collection<K2, V>, Collection<Exclude<K, K2>, V>];
    partition<This, V2 extends V>(fn: (this: This, value: V, key: K, collection: this) => value is V2, thisArg: This): [Collection<K, V2>, Collection<K, Exclude<V, V2>>];
    partition<This>(fn: (this: This, value: V, key: K, collection: this) => boolean, thisArg: This): [Collection<K, V>, Collection<K, V>];
    /**
     * Returns a copy of a section of a collection.
     * Identical in behavior to [Array.slice()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/slice).
     * @param start - The beginning index of the specified portion of the array
     * @param end - The end index of the specified portion of the array
     */
    slice(start?: number, end?: number): Collection<K, V>;
    /**
     * The sorted method sorts the items of a collection and returns it.
     * The default sort order is according to string Unicode code points.
     * @param compareFunction - Specifies a function that defines the sort order
     */
    sorted(compareFunction?: Comparator<K, V>): Collection<K, V>;
    toJSON(): any;
    /**
     * * This method is not supported.
     * @throws This method is not supported.
     */
    protected merge(): never;
}

/**
 * A queue to wait for an action to be completed before continuing
 */
declare class Queue {
    /**
     * The promises in the queue
     */
    promises: QueuePromise[];
    /**
     * Waits for last promise to resolve and queues a new one.
     */
    wait(): Promise<void>;
    /**
     * Removes the last promise from the queue.
     */
    next(): void;
}

/**
 * Handle structures' data
 * @template T - The structure class this manager handles
 */
declare class Manager<K extends number | string | symbol, V> extends Collection<K, V> {
    /**
     * The client that instantiated this manager
     */
    readonly client: ClientRoyale;
    /**
     * The options for this manager
     */
    options: ManagerOptions<V>;
    /**
     * When each value should be considered outdated
     */
    maxAges: Partial<Record<K, number>>;
    /**
     * @param client - The client that instantiated this manager
     * @param items - The items to add
     */
    constructor(client: ClientRoyale, options: ManagerOptions<V>, ...items: (readonly [K, V])[]);
    /**
     * Adds a structure to this manager.
     * @param key - The key of the structure to add
     * @param value - The structure to add
     * @param options - Options for the structure
     * @returns The added structure
     */
    add<T extends V>(key: K, value: T, options?: StructureOptions): T;
    /**
     * Checks if a structure is outdated.
     * @param id - The key of the structure to check
     * @returns Whether the structure is outdated
     */
    isOutdated(id: K): boolean;
    /**
     * Removes a structure from this manager.
     * @param id - The id of the structure to remove
     * @returns The removed structure, if it exists
     */
    remove(id: K): V | undefined;
}

/**
 * A manager for arenas
 */
declare class ArenaManager extends Manager<number, APIArena> {
    /**
     * @param client - The client that instantiated this manager
     * @param data - The data to initialize this manager with
     */
    constructor(client: ClientRoyale, ...data: APIArena[]);
}

/**
 * A manager for battle lists
 */
declare class BattleListManager extends Manager<string, APIBattleList> {
    /**
     * @param client - The client that instantiated this manager
     */
    constructor(client: ClientRoyale);
    add<T extends APIBattleList>(key: string, value: T, options?: StructureOptions): T;
    /**
     * Get list of recent battles for a player.
     * @param playerTag - Tag of the player
     * @param options - Options for the request
     * @returns The battle list
     */
    fetch(playerTag: string, options?: FetchOptions): Promise<APIBattleList>;
}

/**
 * A manager for challenge chains
 */
declare class ChallengeChainManager extends Manager<APIChallengeChain["startTime"], APIChallengeChain> {
    /**
     * @param client - The client that instantiated this manager
     * @param data - The data to initialize this manager with
     */
    constructor(client: ClientRoyale, ...data: APIChallengeChain[]);
    add<T extends APIChallengeChain>(key: string, value: T, options?: StructureOptions): T;
    /**
     * Get current and upcoming challenges.
     * Challenges are returned as chains.
     * @param options - Options for the request
     * @returns The challenge chains
     */
    fetch(options: FetchOptions): Promise<APIChallengeChainsList>;
}

/**
 * A manager for challenges
 */
declare class ChallengeManager extends Manager<number, APIChallenge> {
    /**
     * @param client - The client that instantiated this manager
     * @param data - The data to initialize this manager with
     */
    constructor(client: ClientRoyale, ...data: APIChallenge[]);
    add<T extends APIChallenge>(key: number, value: T, options?: StructureOptions): T;
}

/**
 * A manager for chest lists
 */
declare class ChestListManager extends Manager<string, APIChestList> {
    /**
     * @param client - The client that instantiated this manager
     */
    constructor(client: ClientRoyale);
    /**
     * Get list of reward chests that the player will receive next in the game.
     * @param playerTag - Tag of the player
     * @param options - Options for the request
     * @returns The upcoming chests
     */
    fetch(playerTag: string, options?: FetchOptions): Promise<APIChestList>;
}

/**
 * A manager for clans
 */
declare class ClanManager extends Manager<APIClan["tag"], APIClan | APIClanList["items"][number] | APIClanRanking | APIPlayerRankingClan | APIRiverRaceClan> {
    /**
     * @param client - The client that instantiated this manager
     * @param data - The data to initialize this manager with
     */
    constructor(client: ClientRoyale, ...data: APIClan[]);
    add<T extends APIClan | APIClanRanking | APIPlayerRankingClan | APIRiverRaceClan | Omit<APIClan, "clanChestPoints" | "clanChestStatus" | "description" | "memberList">>(key: string, value: T, options?: StructureOptions): T;
    /**
     * Get information about a single clan by clan tag.
     * Clan tags can be found using clan search operation.
     * @param tag - Tag of the clan
     * @param options - Options for the request
     * @returns The clan
     */
    fetch(tag: string, options?: FetchOptions): Promise<APIClan>;
    /**
     * List clan members.
     * @param clanTag - Tag of the clan
     * @param options - Options for the request
     * @returns The clan members
     */
    fetchMembers(clanTag: string, options?: ListOptions): Promise<APIClanMemberList>;
    /**
     * Get clan rankings for a specific location.
     * @param locationId - Identifier of the location to retrieve
     * @param options - Options for the request
     * @returns The clan rankings
     */
    fetchRankings(locationId: number, options: ListOptions): Promise<APIClanRankingList>;
    /**
     * Get clan war rankings for a specific location.
     * @param locationId - Identifier of the location to retrieve
     * @param options - Options for the request
     * @returns The clan war rankings
     */
    fetchWarRankings(locationId: number, options: ListOptions): Promise<APIClanRankingList>;
    /**
     * Searches for a clan by name, location, members or score.
     * @param options - The options for the search
     * @returns The search results
     * @throws {@link Errors.clanNameSearchTooShort} if the clan name is too short
     * @throws {@link Errors.clanMinMembersNotPositive} if the the minimum number of members is not positive
     * @throws {@link Errors.clanMaxMembersTooLow} if the maximum number of members is less than the minimum or is not positive
     * @throws {@link Errors.clanMinScoreNotPositive} if the minimum score is not positive
     * @throws {@link Errors.missingQuery} if the query is missing
     */
    search(options: SearchClanOptions): Promise<APIClanList>;
}

/**
 * A manager for clan war logs
 * @deprecated **The WarLog API endpoint has been temporarily disabled, possibilities to bring it back are being investigated.
 * Use {@link RiverRaceLogEntryManager} instead**
 */
declare class ClanWarLogManager extends Manager<string, APIClanWarLog> {
    /**
     * @param client - The client that instantiated this manager
     */
    constructor(client: ClientRoyale);
    /**
     * Retrieve clan's clan war log.
     * @param _clanTag - Tag of the clan
     * @returns The clan war log
     * @throws {@link Error} - This API endpoint has been temporarily disabled, possibilities to bring it back are being investigated.
     */
    fetch(_clanTag: string): never;
}

/**
 * A manager for current river races
 */
declare class CurrentRiverRaceManager extends Manager<APICurrentRiverRace["clan"]["tag"], APICurrentRiverRace> {
    /**
     * @param client - The client that instantiated this manager
     * @param data - The data to initialize this manager with
     */
    constructor(client: ClientRoyale, ...data: APICurrentRiverRace[]);
    add<T extends APICurrentRiverRace>(key: string, value: T, options?: StructureOptions): T;
    /**
     * Retrieve information about clan's current river race.
     * @param clanTag - Tag of the clan
     * @param options - Options for the request
     * @returns The current river race
     */
    fetch(clanTag: string, options?: FetchOptions): Promise<APICurrentRiverRace>;
}

/**
 * A manager for game modes
 */
declare class GameModeManager extends Manager<number, APIGameMode> {
    /**
     * @param client - The client that instantiated this manager
     * @param data - The data to initialize this manager with
     */
    constructor(client: ClientRoyale, ...data: APIGameMode[]);
}

/**
 * A manager for items
 */
declare class ItemManager extends Manager<APIItem["id"], APIItem> {
    /**
     * @param client - The client that instantiated this manager
     * @param data - The data to initialize this manager with
     */
    constructor(client: ClientRoyale, ...data: APIItem[]);
    /**
     * Get list of available cards.
     * @param options - Options for the request
     * @returns The cards
     */
    fetch(options?: ListOptions): Promise<APIItemList>;
}

/**
 * A manager for ladder tournaments
 */
declare class LadderTournamentManager extends Manager<APILadderTournament["tag"], APILadderTournament> {
    /**
     * @param client - The client that instantiated this manager
     * @param data - The data to initialize this manager with
     */
    constructor(client: ClientRoyale, ...data: APILadderTournament[]);
    /**
     * Get list of global tournaments.
     * @param options - Options for the request
     * @returns The global tournaments
     */
    fetch(options: FetchOptions): Promise<APILadderTournament[]>;
}

/**
 * A manager for ladder tournament rankings
 */
declare class LadderTournamentRankingManager extends Manager<`${string}-${APILadderTournamentRanking["tag"]}`, APILadderTournamentRanking> {
    /**
     * @param client - The client that instantiated this manager
     */
    constructor(client: ClientRoyale);
    add<T extends APILadderTournamentRanking>(key: `${string}-${string}`, value: T, options?: StructureOptions): T;
    /**
     * Get global tournament rankings.
     * @param tournamentTag - Tag of the tournament to retrieve
     * @param options - Options for the request
     * @returns The ladder tournament rankings
     */
    fetch(tournamentTag: string, options?: ListOptions): Promise<APILadderTournamentRankingList>;
    /**
     * Filter the entries for a specific tournament from the cache.
     * @param tournamentTag - Tag of the tournament to retrieve
     * @returns The filtered entries
     */
    for(tournamentTag: string): Collection<`${string}-${APILadderTournamentRanking["tag"]}`, APILadderTournamentRanking>;
}

/**
 * A manager for league seasons
 */
declare class LeagueSeasonManager extends Manager<APILeagueSeason["id"], APILeagueSeason> {
    /**
     * @param client - The client that instantiated this manager
     * @param data - The data to initialize this manager with
     */
    constructor(client: ClientRoyale, ...data: APILeagueSeason[]);
    /**
     * Get top player league season.
     * @param id - Identifier of the season to retrieve
     * @param options - Options for the request
     * @returns The season
     */
    fetch(id: string, options?: FetchOptions): Promise<APILeagueSeason>;
    /**
     * Lists top player league seasons.
     * @param options - Options for the request
     * @returns The seasons
     */
    fetch(options?: ListOptions): Promise<APILeagueSeasonList>;
}

/**
 * A manager for locations
 */
declare class LocationManager extends Manager<APILocation["id"], APILocation> {
    /**
     * @param client - The client that instantiated this manager
     * @param data - The data to initialize this manager with
     */
    constructor(client: ClientRoyale, ...data: APILocation[]);
    /**
     * Get information about specific location.
     * @param id - Identifier of the location to retrieve
     * @param options - Options for the request
     * @returns The location
     */
    fetch(id: number, options?: FetchOptions): Promise<APILocation>;
    /**
     * List locations.
     * @param options - Options for the request
     * @returns The locations
     */
    fetch(options?: ListOptions): Promise<APILocationList>;
}

/**
 * A manager for players
 */
declare class PlayerManager extends Manager<APIPlayer["tag"], APIClanMember | APIPlayer | APIPlayerRanking> {
    /**
     * @param client - The client that instantiated this manager
     * @param data - The data to initialize this manager with
     */
    constructor(client: ClientRoyale, ...data: APIPlayer[]);
    add<T extends APIClanMember | APIPlayer | APIPlayerRanking>(key: string, value: T, options?: StructureOptions): T;
    /**
     * Get information about a single player by player tag.
     * Player tags can be found either in game or by from clan member lists.
     * @param tag - Tag of the player
     * @returns The player
     */
    fetch(tag: string, options?: FetchOptions): Promise<APIPlayer>;
    /**
     * Get player rankings for a specific location.
     * @param locationId - Identifier of the location to retrieve
     * @param options - Options for the request
     * @returns The player rankings
     */
    fetchRankings(locationId: number, options?: ListOptions): Promise<APIPlayerRankingList>;
    /**
     * Get top player rankings for a season.
     * @param seasonId - Identifier of the season to retrieve
     * @param options - Options for the request
     * @returns The player rankings
     */
    fetchSeasonRankings(seasonId: string, options?: ListOptions): Promise<APIPlayerRankingList>;
}

/**
 * A manager for river race log entries
 */
declare class RiverRaceLogEntryManager extends Manager<`${string}-${APIRiverRaceLogEntry["seasonId"]}-${APIRiverRaceLogEntry["sectionIndex"]}`, APIRiverRaceLogEntry> {
    /**
     * @param client - The client that instantiated this manager
     */
    constructor(client: ClientRoyale);
    /**
     * Retrieve clan's river race log.
     * @param clanTag - Tag of the clan
     * @param options - Options for the request
     * @returns The river race log
     */
    fetch(clanTag: string, options?: ListOptions): Promise<APIRiverRaceLog>;
    /**
     * Filter the entries for a specific clan from the cache.
     * @param clanTag - Tag of the clan
     * @returns The filtered entries
     */
    for(clanTag: string): Collection<`${string}-${number}-${number}`, APIRiverRaceLogEntry>;
}

/**
 * A manager for tournaments
 */
declare class TournamentManager extends Manager<APITournament["tag"], APITournament | APITournamentHeaderList["items"][number]> {
    /**
     * @param client - The client that instantiated this manager
     * @param data - The data to initialize this manager with
     */
    constructor(client: ClientRoyale, ...data: APITournament[]);
    /**
     * Get information about a single tournament by a tournament tag.
     * @param tag - Tag of the tournament to retrieve
     * @returns The tournament
     */
    fetch(tag: string, options?: FetchOptions): Promise<APITournament>;
    /**
     * Searches for a tournament by name, location, members or score.
     * @param options - The options for the search
     * @returns The search results
     * @throws {@link Errors.tournamentNameSearchTooShort} if the clan name is too short
     * @throws {@link Errors.missingQuery} if the query is missing
     */
    search(options: SearchTournamentOptions): Promise<APITournamentHeaderList>;
}

/**
 * A rest manager
 */
declare class Rest {
    /**
     * The client that instantiated this, if any
     */
    client?: ClientRoyale;
    /**
     * The options for this rest manager
     */
    options: Required<RestOptions>;
    /**
     * A queue for the requests
     */
    queue: Queue;
    /**
     * Whether or not the client is currently rate limited
     */
    rateLimited: boolean;
    /**
     * @param client - The client that instantiated this
     * @param options - The options for this rest manager
     */
    constructor(client?: ClientRoyale, options?: RestOptions);
    /**
     * Make a request to the API.
     * @param path - The path to the API endpoint
     * @param options - Other options for this request
     * @returns The raw JSON data received from the API or null if no data was received
     */
    get<T extends Path>(path: T, options?: RequestOptions & {
        retry?: boolean;
        force?: boolean;
    }): Promise<RestResponse<T>>;
}

/**
 * Represents a response from the API
 */
declare class Response {
    /**
     * The raw data from the response
     */
    data: string | null;
    /**
     * The status code of the response
     */
    statusCode: number;
    /**
     * The headers of the response
     */
    headers: IncomingHttpHeaders;
    /**
     * The status of the response
     */
    status: string;
    /**
     * @param data - The raw data from the response
     * @param res - The response object
     */
    constructor(data: string, res: IncomingMessage);
}

/**
 * A class representing a request to the API
 */
declare class APIRequest {
    /**
     * Headers to be sent in the request
     */
    headers: OutgoingHttpHeaders;
    /**
     * The path of this request
     */
    path: Path;
    /**
     * Query applied to the request
     */
    query: URLSearchParams;
    /**
     * The rest manager that instantiated this
     */
    rest: Rest;
    /**
     * @param rest - The rest that instantiated this
     * @param path - The path to request
     * @param options - Options for this request
     */
    constructor(rest: Rest, path: Path, { query, headers }?: RequestOptions);
    /**
     * The full URL of this request
     */
    get url(): URL;
    /**
     * Send the request to the api.
     * @returns A promise that resolves with the response
     */
    send(): Promise<Response>;
    /**
     * Make the request to the API.
     * @param resolve - A function to resolve the promise
     * @param reject - A function to reject the promise
     */
    private make;
}

/**
 * A class representing an error received from the API
 */
declare class ErrorRoyale extends Error {
    /**
     * Headers sent in the request
     */
    headers: OutgoingHttpHeaders;
    /**
     * Path of the request
     */
    path: Path;
    /**
     * The query of the request
     */
    query?: string;
    /**
     * The status message received from the API
     */
    status: string;
    /**
     * The status code received for this request
     */
    statusCode: number;
    /**
     * @param req - The request sent
     * @param res - The response received
     */
    constructor(req: APIRequest, res: Response);
}

/**
 * A class to connect to the Clash Royale API
 */
interface ClientRoyale extends EventEmitter {
    on: <T extends keyof ClientEvents>(event: T, listener: (...args: ClientEvents[T]) => any) => this;
    once: <T extends keyof ClientEvents>(event: T, listener: (...args: ClientEvents[T]) => any) => this;
    addListener: <T extends keyof ClientEvents>(event: T, listener: (...args: ClientEvents[T]) => any) => this;
    removeListener: <T extends keyof ClientEvents>(event: T, listener: (...args: ClientEvents[T]) => any) => this;
    off: <T extends keyof ClientEvents>(event: T, listener: (...args: ClientEvents[T]) => any) => this;
    prependOnListener: <T extends keyof ClientEvents>(event: T, listener: (...args: ClientEvents[T]) => any) => this;
    prependOnceListener: <T extends keyof ClientEvents>(event: T, listener: (...args: ClientEvents[T]) => any) => this;
    emit<T extends keyof ClientEvents>(event: T, ...args: ClientEvents[T]): boolean;
}
/**
 * A class to connect to the Clash Royale API
 */
declare class ClientRoyale extends EventEmitter {
    /**
     * The rest client
     */
    api: Rest;
    /**
     * Default cache options for the client
     */
    cacheOptions: Required<CacheOptions>;
    /**
     * A manager for arenas
     */
    arenas: ArenaManager;
    /**
     * A manager for battle logs
     */
    battleLogs: BattleListManager;
    /**
     * A manager for cards
     */
    cards: ItemManager;
    /**
     * A manager for challenges
     */
    challenges: ChallengeManager;
    /**
     * A manager for challenge chains
     */
    challengeChains: ChallengeChainManager;
    /**
     * A manager for clans
     */
    clans: ClanManager;
    /**
     * The cache of clan war logs
     * @deprecated **The WarLog API endpoint has been temporarily disabled, possibilities to bring it back are being investigated.
     * Use {@link RiverRaceLogEntryManager} instead**
     */
    clanWarLogs: ClanWarLogManager;
    /**
     * A manager for current river races
     */
    currentRiverRaces: CurrentRiverRaceManager;
    /**
     * A manager for game modes
     */
    gameModes: GameModeManager;
    /**
     * A manager for global tournament rankings
     */
    globalTournamentRankings: LadderTournamentRankingManager;
    /**
     * A manager for global tournaments
     */
    globalTournaments: LadderTournamentManager;
    /**
     * A manager for river race logs
     */
    riverRaceLogs: RiverRaceLogEntryManager;
    /**
     * A manager for tournaments
     */
    tournaments: TournamentManager;
    /**
     * A manager for upcoming chests
     */
    upcomingChests: ChestListManager;
    /**
     * A manager for seasons
     */
    seasons: LeagueSeasonManager;
    /**
     * A manager for locations
     */
    locations: LocationManager;
    /**
     * A manager for players
     */
    players: PlayerManager;
    /**
     * @param options - Options for the client
     */
    constructor(options?: ClientOptions);
}

export { APIDateToObject, APIRequest, ArenaManager, BattleListManager, CacheOptions, ChallengeChainManager, ChallengeManager, ChestListManager, ClanManager, ClanWarLogManager, ClientEvents, ClientOptions, ClientRoyale, Collection, Constants, CurrentRiverRaceManager, ErrorRoyale, Errors, FetchClanMembersOptions, FetchOptions, FetchPlayerUpcomingChestsOptions, FetchRiverRaceLogOptions, GameModeManager, ItemManager, Json, LadderTournamentManager, LadderTournamentRankingManager, LeagueSeasonManager, ListOptions, LocationManager, Manager, ManagerOptions, PlayerManager, Queue, QueuePromise, RequestOptions, Response, Rest, RestOptions, RestResponse, RiverRaceLogEntryManager, SearchClanOptions, SearchTournamentOptions, StructureEvents, StructureOptions, Token, TournamentManager, cast, dateObjectToAPIDate, ClientRoyale as default };
