import CacheInterface from '@cachex/core';

declare class Query {
    params: Array<{
        key: string;
        value: string | number | boolean;
    }>;
    not: {
        equal: (key: string, value: string) => Query;
        contains: (key: string, value: string) => Query;
        includes: (key: string, value: string) => Query;
        like: (key: string, value: string) => Query;
        isNull: (key: string) => Query;
    };
    static create(): Query;
    includes(key: string, value: string): this;
    like(key: string, value: string): this;
    contains(key: string, value: string): this;
    equal(key: string, value: string): this;
    sort(key: string, order: 'ASC' | 'DESC'): this;
    greaterOrEqualThan(key: string, value: number): this;
    lesserOrEqualThan(key: string, value: number): this;
    greaterThan(key: string, value: number): this;
    lesserThan(key: string, value: number): this;
    isNull(key: string): this;
    paginate(page: number, itemsPerPage: number): this;
}

type SupportedLanguages = 'en' | 'fr' | 'es' | 'it' | 'pt' | 'de'

/**
 * @deprecated This is not used anymore in the API V2
 */
type Languages<T = string> = Partial<Record<SupportedLanguages, T>>

interface SerieResume$1 {
	id: string
	name: string
	logo?: string
}

interface Serie$1 extends SerieResume$1 {
	sets: SetList
}

interface variants {
	normal?: boolean
	reverse?: boolean
	holo?: boolean
	firstEdition?: boolean
}

type SetList = Array<SetResume$1>
type SerieList = Array<SerieResume$1>
type CardList = Array<CardResume$1>

interface SetResume$1 {
	id: string
	name: string
	logo?: string
	symbol?: string
	cardCount: {

		/**
		 * total of number of cards
		 */
		total: number

		/**
		  * number of cards officialy (on the bottom of each cards)
		  */
		official: number
	}
}

interface Set$1 extends SetResume$1 {
	serie: SerieResume$1
	tcgOnline?: string
	variants?: variants

	releaseDate: string

	/**
	 * Designate if the set is usable in tournaments
	 *
	 * Note: this is specific to the set and if a
	 * card is banned from the set it will still be true
	 */
	legal: {

		/**
		 * Ability to play in standard tournaments
		 */
		standard: boolean

		/**
		 * Ability to play in expanded tournaments
		 */
		expanded: boolean
	}

	cardCount: {

		/**
		 * total of number of cards
		 */
		total: number

		/**
		 * number of cards officialy (on the bottom of each cards)
		 */
		official: number

		/**
		 * number of cards having a normal version
		 */
		normal: number

		/**
		 * number of cards having an reverse version
		 */
		reverse: number

		/**
		 * number of cards having an holo version
		 */
		holo: number

		/**
		 * Number of possible cards
		 */
		firstEd?: number
	}

	cards: CardList
}

interface CardResume$1 {
	id: string
	localId: string

	/**
	 * Card Name (Including the suffix if next to card name)
	 */
	name: string
	image?: string
}

interface Card$1<SetType extends SetResume$1 = SetResume$1> extends CardResume$1 {

	/**
	 * Card illustrator
	 */
	illustrator?: string

	/**
	 * Card Rarity
	 *
	 * - None https://www.tcgdex.net/database/sm/smp/SM01
	 * - Common https://www.tcgdex.net/database/xy/xy9/1
	 * - Uncommon https://www.tcgdex.net/database/xy/xy9/2
	 * - Rare https://www.tcgdex.net/database/xy/xy9/3
	 * - Ultra Rare
	 * - Secret Rare
	 */
	rarity: string

	/**
	 * Card Category
	 *
	 * - Pokemon
	 * - Trainer
	 * - Energy
	 */
	category: string

	/**
	 * Card Variants (Override Set Variants)
	 */
	variants?: variants

	/**
	 * Card Set
	 */
	set: SetType

	/**
	 * Pokemon only elements
	 */

	/**
	 * Pokemon Pokedex ID
	 */
	dexId?: Array<number>

	/**
	 * Pokemon HP
	 */
	hp?: number

	/**
	 * Pokemon Types
	 * ex for multiple https://www.tcgdex.net/database/ex/ex13/17
	 */
	types?: Array<string>

	/**
	 * Pokemon Sub Evolution
	 */
	evolveFrom?: string

	/**
	 * Pokemon Weight
	 */
	weight?: string

	/**
	 * Pokemon Description
	 */
	description?: string

	/**
	 * Level of the Pokemon
	 *
	 * NOTE: can be equal to 'X' when the pokemon is a LEVEL-UP one
	 */
	level?: number | string

	/**
	 * Pokemon Stage
	 *
	 * - Basic https://www.tcgdex.net/database/xy/xy9/1
	 * - BREAK https://www.tcgdex.net/database/xy/xy9/18
	 * - LEVEL-UP https://www.tcgdex.net/database/dp/dp1/121
	 * - MEGA https://www.tcgdex.net/database/xy/xy1/2
	 * - RESTORED https://www.tcgdex.net/database/bw/bw5/53
	 * - Stage1 https://www.tcgdex.net/database/xy/xy9/2
	 * - Stage2 https://www.tcgdex.net/database/xy/xy9/3
	 * - VMAX https://www.tcgdex.net/database/swsh/swsh1/50
	 */
	stage?: string

	/**
	 * Card Suffix
	 *
	 * - EX https://www.tcgdex.net/database/ex/ex2/94
	 * - GX https://www.tcgdex.net/database/sm/sm12/4
	 * - V https://www.tcgdex.net/database/swsh/swsh1/1
	 * - Legend https://www.tcgdex.net/database/hgss/hgss1/114
	 * - Prime https://www.tcgdex.net/database/hgss/hgss2/85
	 * - SP https://www.tcgdex.net/database/pl/pl1/7
	 * - TAG TEAM-GX https://www.tcgdex.net/database/sm/sm12/226
	 */
	suffix?: string

	/**
	 * Pokemon Held Item
	 *
	 * ex https://www.tcgdex.net/database/dp/dp2/75
	 */
	item?: {
		name: string
		effect: string
	}

	/**
	 * Pokemon Abilities
	 *
	 * multi abilities ex https://www.tcgdex.net/database/ex/ex15/10
	 */
	abilities?: Array<{
		type: string
		name: string
		effect: string
	}>

	/**
	 * Pokemon Attacks
	 */
	attacks?: Array<{
		cost?: Array<string>
		name: string
		effect?: string
		damage?: string | number
	}>

	/**
	 * Pokemon Weaknesses
	 */
	weaknesses?: Array<{
		type: string
		value?: string
	}>

	resistances?: Array<{
		type: string
		value?: string
	}>

	retreat?: number

	// Trainer/Energy
	effect?: string

	// Trainer Only
	trainerType?: string

	// Energy Only
	energyType?: string

	/**
	 * Define the rotation mark on cards >= Sword & Shield
	 */
	regulationMark?: string

	/**
	 * Card ability to be played in official tournaments
	 *
	 * Note: all cards are avaialable to play in unlimited tournaments
	 */
	legal: {

		/**
		 * Ability to play in standard tournaments
		 */
		standard: boolean

		/**
		 * Ability to play in expanded tournaments
		 */
		expanded: boolean
	}
}

type StringEndpointList = Array<string>

interface StringEndpoint$1 {
	name: string
	cards: Array<CardResume$1>
}

type Quality = 'low' | 'high'

type Extension = 'jpg' | 'webp' | 'png'

type Endpoints = 'cards' | 'categories' | 'dex-ids' | 'energy-types' |
	'hp' | 'illustrators' | 'rarities' | 'regulation-marks' |
	'retreats' | 'series' | 'sets' | 'stages' | 'suffixes' |
	'trainer-types' | 'types' | 'variants' | 'random'

declare abstract class Model {
    protected readonly sdk: TCGdex;
    constructor(sdk: TCGdex);
    /**
     * build a model depending on the data given
     * @param model the model to build
     * @param data the data to fill it with
     */
    static build<T extends Model>(model: T, data?: object): T;
    protected fill(obj: object): void;
}

declare class Endpoint<Item extends Model, List extends Model> {
    protected readonly tcgdex: TCGdex;
    protected readonly itemModel: new (sdk: TCGdex) => Item;
    protected readonly listModel: new (sdk: TCGdex) => List;
    protected readonly endpoint: Endpoints;
    constructor(tcgdex: TCGdex, itemModel: new (sdk: TCGdex) => Item, listModel: new (sdk: TCGdex) => List, endpoint: Endpoints);
    get(id: string | number): Promise<Item | null>;
    list(query?: Query): Promise<Array<List>>;
}

declare class SimpleEndpoint<Item extends Model, List extends string | number> {
    protected readonly tcgdex: TCGdex;
    protected readonly itemModel: new (sdk: TCGdex) => Item;
    protected readonly endpoint: Endpoints;
    constructor(tcgdex: TCGdex, itemModel: new (sdk: TCGdex) => Item, endpoint: Endpoints);
    get(id: string | number): Promise<Item | null>;
    list(query?: Query): Promise<Array<List>>;
}

declare class CardResume extends Model {
    /**
     * Globally unique card ID based on the set ID and the cards ID within the set
     */
    id: string;
    /**
     * Card image url without the extension and quality
     *
     * @see {@link getImageURL}
     */
    image?: string;
    /**
     * ID indexing this card within its set, usually just its number
     */
    localId: string;
    /**
     * Card Name (Including the suffix if next to card name)
     */
    name: string;
    /**
     * the the Card Image full URL
     *
     * @param {Quality} quality the quality you want your image to be in
     * @param {Extension} extension extension you want you image to be
     * @return the full card URL
     */
    getImageURL(quality?: Quality, extension?: Extension): string;
    /**
     * Get the full Card
     *
     * @return the full card if available
     */
    getCard(): Promise<Card>;
}

interface Variants {
	normal?: boolean
	reverse?: boolean
	holo?: boolean
	firstEdition?: boolean
}

declare class SerieResume extends Model {
    id: string;
    name: string;
    logo?: string;
    /**
     * the the Card Image full URL
     *
     * @param {Quality} quality the quality you want your image to be in
     * @param {Extension} extension extension you want you image to be
     * @return the full card URL
     */
    getImageURL(extension?: Extension): string;
    getSerie(): Promise<Serie>;
}

declare class SetResume extends Model {
    id: string;
    name: string;
    logo?: string;
    symbol?: string;
    cardCount: {
        /**
         * total of number of cards
         */
        total: number;
        /**
          * number of cards officialy (on the bottom of each cards)
          */
        official: number;
    };
    getSet(): Promise<Set>;
}

declare class Serie extends SerieResume {
    sets: Array<SetResume>;
    protected fill(obj: object): void;
}

declare class Set extends Model {
    id: string;
    name: string;
    logo?: string;
    symbol?: string;
    serie: SerieResume;
    tcgOnline?: string;
    variants?: Variants;
    releaseDate: string;
    /**
     * Designate if the set is usable in tournaments
     *
     * Note: this is specific to the set and if a
     * card is banned from the set it will still be true
     */
    legal: {
        /**
         * Ability to play in standard tournaments
         */
        standard: boolean;
        /**
         * Ability to play in expanded tournaments
         */
        expanded: boolean;
    };
    cardCount: {
        /**
         * total of number of cards
         */
        total: number;
        /**
         * number of cards officialy (on the bottom of each cards)
         */
        official: number;
        /**
         * number of cards having a normal version
         */
        normal: number;
        /**
         * number of cards having an reverse version
         */
        reverse: number;
        /**
         * number of cards having an holo version
         */
        holo: number;
        /**
         * Number of possible cards
         */
        firstEd?: number;
    };
    cards: Array<CardResume>;
    getSerie(): Promise<Serie | null>;
    protected fill(obj: object): void;
}

declare class Card extends CardResume {
    /**
     * Card illustrator
     */
    illustrator?: string;
    /**
     * Card Rarity
     *
     * - None https://www.tcgdex.net/database/sm/smp/SM01
     * - Common https://www.tcgdex.net/database/xy/xy9/1
     * - Uncommon https://www.tcgdex.net/database/xy/xy9/2
     * - Rare https://www.tcgdex.net/database/xy/xy9/3
     * - Ultra Rare
     * - Secret Rare
     */
    rarity: string;
    /**
     * Card Category
     *
     * - Pokemon
     * - Trainer
     * - Energy
     */
    category: string;
    /**
     * Card Variants (Override Set Variants)
     */
    variants?: Variants;
    /**
     * Card Set
     */
    set: SetResume;
    /**
     * Pokemon only elements
     */
    /**
     * Pokemon Pokedex ID
     */
    dexId?: Array<number>;
    /**
     * Pokemon HP
     */
    hp?: number;
    /**
     * Pokemon Types
     * ex for multiple https://www.tcgdex.net/database/ex/ex13/17
     */
    types?: Array<string>;
    /**
     * Pokemon Sub Evolution
     */
    evolveFrom?: string;
    /**
     * Pokemon Weight
     */
    weight?: string;
    /**
     * Pokemon Description
     */
    description?: string;
    /**
     * Level of the Pokemon
     *
     * NOTE: can be equal to 'X' when the pokemon is a LEVEL-UP one
     */
    level?: number | string;
    /**
     * Pokemon Stage
     *
     * - Basic https://www.tcgdex.net/database/xy/xy9/1
     * - BREAK https://www.tcgdex.net/database/xy/xy9/18
     * - LEVEL-UP https://www.tcgdex.net/database/dp/dp1/121
     * - MEGA https://www.tcgdex.net/database/xy/xy1/2
     * - RESTORED https://www.tcgdex.net/database/bw/bw5/53
     * - Stage1 https://www.tcgdex.net/database/xy/xy9/2
     * - Stage2 https://www.tcgdex.net/database/xy/xy9/3
     * - VMAX https://www.tcgdex.net/database/swsh/swsh1/50
     */
    stage?: string;
    /**
     * Card Suffix
     *
     * - EX https://www.tcgdex.net/database/ex/ex2/94
     * - GX https://www.tcgdex.net/database/sm/sm12/4
     * - V https://www.tcgdex.net/database/swsh/swsh1/1
     * - Legend https://www.tcgdex.net/database/hgss/hgss1/114
     * - Prime https://www.tcgdex.net/database/hgss/hgss2/85
     * - SP https://www.tcgdex.net/database/pl/pl1/7
     * - TAG TEAM-GX https://www.tcgdex.net/database/sm/sm12/226
     */
    suffix?: string;
    /**
     * Pokemon Held Item
     *
     * ex https://www.tcgdex.net/database/dp/dp2/75
     */
    item?: {
        name: string;
        effect: string;
    };
    /**
     * Pokemon Abilities
     *
     * multi abilities ex https://www.tcgdex.net/database/ex/ex15/10
     */
    abilities?: Array<{
        type: string;
        name: string;
        effect: string;
    }>;
    /**
     * Pokemon Attacks
     */
    attacks?: Array<{
        cost?: Array<string>;
        name: string;
        effect?: string;
        damage?: string | number;
    }>;
    /**
     * Pokemon Weaknesses
     */
    weaknesses?: Array<{
        type: string;
        value?: string;
    }>;
    resistances?: Array<{
        type: string;
        value?: string;
    }>;
    retreat?: number;
    effect?: string;
    trainerType?: string;
    energyType?: string;
    /**
     * Define the rotation mark on cards >= Sword & Shield
     */
    regulationMark?: string;
    /**
     * Card ability to be played in official tournaments
     *
     * Note: all cards are avaialable to play in unlimited tournaments
     */
    legal: {
        /**
         * Ability to play in standard tournaments
         */
        standard: boolean;
        /**
         * Ability to play in expanded tournaments
         */
        expanded: boolean;
    };
    getCard(): Promise<Card>;
    getSet(): Promise<Set>;
}

declare class StringEndpoint extends Model {
    name: string;
    cards: Array<CardResume>;
    protected fill(obj: object): void;
}

declare class TCGdex {
    /**
     * How the remote data is going to be fetched
     */
    static fetch: typeof fetch;
    /**
     * @deprecated to change the lang use {@link TCGdex.getLang} and {@link TCGdex.setLang}
     */
    static defaultLang: SupportedLanguages;
    /**
     * the previously hidden caching system used by TCGdex to not kill the API
     */
    cache: CacheInterface;
    /**
     * the default cache TTL, only subsequent requests will have their ttl changed
     */
    cacheTTL: number;
    readonly random: {
        card: () => Promise<Card>;
        set: () => Promise<Set>;
        serie: () => Promise<Serie>;
    };
    readonly card: Endpoint<Card, CardResume>;
    readonly set: Endpoint<Set, SetResume>;
    readonly serie: Endpoint<Serie, SerieResume>;
    readonly type: SimpleEndpoint<StringEndpoint, string | number>;
    readonly retreat: SimpleEndpoint<StringEndpoint, string | number>;
    readonly rarity: SimpleEndpoint<StringEndpoint, string | number>;
    readonly illustrator: SimpleEndpoint<StringEndpoint, string | number>;
    readonly hp: SimpleEndpoint<StringEndpoint, string | number>;
    readonly categorie: SimpleEndpoint<StringEndpoint, string | number>;
    readonly dexID: SimpleEndpoint<StringEndpoint, string | number>;
    readonly energyType: SimpleEndpoint<StringEndpoint, string | number>;
    readonly regulationMark: SimpleEndpoint<StringEndpoint, string | number>;
    readonly stage: SimpleEndpoint<StringEndpoint, string | number>;
    readonly suffixe: SimpleEndpoint<StringEndpoint, string | number>;
    readonly trainerType: SimpleEndpoint<StringEndpoint, string | number>;
    readonly variant: SimpleEndpoint<StringEndpoint, string | number>;
    private lang;
    private endpointURL;
    constructor(lang?: SupportedLanguages);
    /**
     * @deprecated use the constructor parameter or {@link TCGdex.setLang} when in an instance
     */
    static setDefaultLang(lang: SupportedLanguages): void;
    /**
     * @deprecated use {@link TCGdex.setLang} when in an instance
     */
    static getDefaultLang(): SupportedLanguages;
    /**
     * the endpoint URL
     * ex: `https://api.tcgdex.net/v2`
     * @param endpoint the url
     */
    setEndpoint(endpoint: string): void;
    getEndpoint(): string;
    /**
     * set the current cache methodology
     * @param cache the cache to use
     */
    setCache(cache: CacheInterface): void;
    /**
     * get the current cache methodology
     * @param cache the cache to use
     */
    getCache(): CacheInterface;
    /**
     * the endpoint URL
     * ex: `https://api.tcgdex.net/v2`
     * @param endpoint the url
     */
    setCacheTTL(seconds: number): void;
    /**
     * get the current useed cache ttl in seconds
     * @returns the cache ttl in seconds
     */
    getCacheTTL(): number;
    getLang(): SupportedLanguages;
    setLang(lang: SupportedLanguages): void;
    /**
     * Shortcut to easily fetch a card using both it's global id and it's local ID
     * @param id the card global/local ID
     * @param set the card set name/ID (optionnal)
     * @returns the card object
     */
    fetchCard(id: string | number, set?: string): Promise<Card$1 | undefined>;
    /**
     * Shortcut to easily fetch cards using an optionnal set name/ID
     * @param set the card set name/ID (optionnal)
     * @returns a card list
     */
    fetchCards(set?: string): Promise<Array<CardResume$1> | undefined>;
    /**
     * @deprecated use `this.fetch('sets', set)`
     */
    fetchSet(set: string): Promise<Set$1 | undefined>;
    /**
     * @deprecated use `this.fetch('series', serie)`
     */
    fetchSerie(serie: string): Promise<Serie$1 | undefined>;
    /**
     * @deprecated use `this.fetch('series')`
     */
    fetchSeries(): Promise<SerieList | undefined>;
    /**
     * Shortcut to easily fetch sets using an optionnal serie name/ID
     * @param serie the card set name/ID (optionnal)
     * @returns a card list
     */
    fetchSets(serie?: string): Promise<SetList | undefined>;
    /**
     * Fetch a card using its global id
     * @param endpoint_0 'cards'
     * @param endpoint_1 {string} the card global ID
     */
    fetch(...type: ['cards', string]): Promise<Card$1 | undefined>;
    /**
     * Fetch every cards in the database
     * @param endpoint_0 'cards'
     */
    fetch(type: 'cards'): Promise<Array<CardResume$1> | undefined>;
    /**
     * Fetch a card using its local id and its set
     * @param endpoint_0 'sets'
     * @param endpoint_1 {string} the set name or ID
     * @param endpoint_2 {string} the card local ID
     */
    fetch(...endpoint: ['sets', string, string]): Promise<Card$1 | undefined>;
    /**
     * Fetch a set
     * @param endpoint_0 'sets'
     * @param endpoint_1 {string} the set name or ID
     */
    fetch(...endpoint: ['sets', string]): Promise<Set$1 | undefined>;
    /**
     * Fetch a random element
     * @param endpoint_0 'random'
     * @param endpoint_1 {'set' | 'card' | 'serie'} the type of random element you want to get
     */
    fetch(...endpoint: ['random', 'set' | 'card' | 'serie']): Promise<Card$1 | Set$1 | Serie$1 | undefined>;
    /**
     * Fetch every sets
     * @param endpoint_0 'sets'
     */
    fetch(endpoint: 'sets'): Promise<SetList | undefined>;
    /**
     * Fetch a serie
     * @param endpoint_0 'series'
     * @param endpoint_1 {string} the serie name or ID
     */
    fetch(...endpoint: ['series', string]): Promise<Serie$1 | undefined>;
    /**
     * Fetch every series
     * @param endpoint_0 'series'
     */
    fetch(endpoint: 'series'): Promise<SerieList | undefined>;
    /**
     * Fetch cards depending on a specific filter
     * @param endpoint_0 {'categories' | 'dex-ids' | 'energy-types' | 'hp' | 'illustrators' | 'rarities' | 'regulation-marks' | 'retreats' | 'stages' | 'suffixes' | 'trainer-types' | 'types' | 'variants'}
     * Possible value 'categories' | 'dex-ids' | 'energy-types' | 'hp' | 'illustrators' | 'rarities' | 'regulation-marks' | 'retreats' | 'stages' | 'suffixes' | 'trainer-types' | 'types' | 'variants'
     * @param endpoint_1 {string} the value set while fetching the index
     */
    fetch(...endpoint: ['categories' | 'dex-ids' | 'energy-types' | 'hp' | 'illustrators' | 'rarities' | 'regulation-marks' | 'retreats' | 'stages' | 'suffixes' | 'trainer-types' | 'types' | 'variants', string]): Promise<StringEndpoint$1 | undefined>;
    /**
     * Fetch cards depending on a specific filter
     * @param endpoint_0 {'categories' | 'dex-ids' | 'energy-types' | 'hp' | 'illustrators' | 'rarities' | 'regulation-marks' | 'retreats' | 'stages' | 'suffixes' | 'trainer-types' | 'types' | 'variants'}
     * Possible value 'categories' | 'dex-ids' | 'energy-types' | 'hp' | 'illustrators' | 'rarities' | 'regulation-marks' | 'retreats' | 'stages' | 'suffixes' | 'trainer-types' | 'types' | 'variants'
     * @param endpoint_1 {string} Fetch the possible values to use depending on the endpoint
     */
    fetch(endpoint: 'categories' | 'dex-ids' | 'energy-types' | 'hp' | 'illustrators' | 'rarities' | 'regulation-marks' | 'retreats' | 'stages' | 'suffixes' | 'trainer-types' | 'types' | 'variants'): Promise<Array<string> | undefined>;
    /**
     * @param endpoint the endpoint to fetch
     * @param query the query
     */
    fetchWithQuery<T = object>(endpoint: [Endpoints, ...Array<string>], query?: Array<{
        key: string;
        value: string | number | boolean;
    }>): Promise<T | undefined>;
    /**
     * format the final URL
     */
    private getFullURL;
    private actualFetch;
    /**
     * encode a string to be used in an url
     * @param str the string to encode to URL
     * @returns the encoded string
     */
    private encode;
}

export { Card$1 as Card, CardList, Card as CardModel, CardResume$1 as CardResume, CardResume as CardResumeModel, Endpoint, Endpoints, Extension, Languages, Model, Quality, Query, Serie$1 as Serie, SerieList, Serie as SerieModel, SerieResume$1 as SerieResume, SerieResume as SerieResumeModel, Set$1 as Set, SetList, Set as SetModel, SetResume$1 as SetResume, SetResume as SetResumeModel, SimpleEndpoint, StringEndpoint$1 as StringEndpoint, StringEndpointList, SupportedLanguages, TCGdex as default };
