interface CategoryData {
    code: CategoryCode;
    name: CategoryName;
}
/**
 * Any existing category code
 */
type CategoryCode = (typeof ALL_CATEGORY_CODES)[number];
/**
 * Any existing category name
 */
type CategoryName = (typeof ALL_CATEGORY_NAMES)[number];
/**
 * A record with category code as key and category name as value
 */
type CategoryList = Partial<Record<CategoryCode, CategoryName>>;

/**
 * All existing category codes
 */
declare const ALL_CATEGORY_CODES: ("VE" | "EA" | "PO" | "BE" | "MI" | "CA" | "JU" | "ES" | "SE" | "BB" | "MA" | "M0" | "M1" | "M2" | "M3" | "M4" | "M5" | "M6" | "M7" | "M8" | "M9" | "M10" | "V1" | "V2" | "V3" | "V4" | "V5")[];
/**
 * All existing category names
 */
declare const ALL_CATEGORY_NAMES: ("École d'Athlétisme" | "Poussins" | "Benjamins" | "Minimes" | "Cadets" | "Juniors" | "Espoirs" | "Seniors" | "Vétérans" | "Vétérans 1" | "Vétérans 2" | "Vétérans 3" | "Vétérans 4" | "Baby Athlé" | "Masters" | "Masters 1" | "Masters 2" | "Masters 3" | "Masters 4" | "Masters 5" | "Masters 0" | "Masters 6" | "Masters 7" | "Masters 8" | "Masters 9" | "Masters 10" | "Éveil Athlétique")[];

/**
 * Returns the year of the categories applicable at the date provided
 *
 * Over the years, the day and month on which the categories change has evolved
 * - Until 2012, the categories changed every January 1st
 * - Between 2013 and 2021, the categories changed every November 1st: from November 1 of year N, the categories of year N+1 are applied until October 31 of year N+1, and so on
 * - Since 2022, the categories changed every September 1st: from September 1 of year N, the categories of year N+1 are applied until August 31 of year N+1, and so on
 *
 * @param date - The date for which the categories' year should be retrieved
 * @returns The corresponding year
 *
 * @example
 * ```ts
 * getApplicableCategoriesYear(new Date("2000-01-01")) // Returns 2000
 * getApplicableCategoriesYear(new Date("2012-12-31")) // Returns 2012
 * getApplicableCategoriesYear(new Date("2013-10-31")) // Returns 2013
 * getApplicableCategoriesYear(new Date("2013-11-01")) // Returns 2014
 * getApplicableCategoriesYear(new Date("2014-10-31")) // Returns 2014
 * getApplicableCategoriesYear(new Date("2014-11-01")) // Returns 2015
 * getApplicableCategoriesYear(new Date("2022-08-31")) // Returns 2022
 * getApplicableCategoriesYear(new Date("2022-09-01")) // Returns 2023
 * getApplicableCategoriesYear(new Date("2023-08-31")) // Returns 2023
 * getApplicableCategoriesYear(new Date("2023-09-01")) // Returns 2024
 * ```
 */
declare function getApplicableCategoriesYear(date: Date): number;

/**
 * Returns list of categories existing at a given date
 * @param date - The date for which categories should be retrieved. Default: current date
 * @param detailed - Whether or not to return detailed list (with detailed "Vétérans" or "Masters" categories). Default: true
 * @returns The category list
 */
declare function getCategoryList(date?: Date, detailed?: boolean): CategoryList;

interface GetCategoryOptions {
    /**
     * The date for which the category code should be determined
     * Default: current date
     */
    date: Date;
    /**
     * Whether or not to return a detailed code when applicable (e.g. for category Master 2, return `"M2"` if `true`, `"MA"` if `false`).
     * Default: `true`
     */
    detailed: boolean;
}
/**
 * Computes the category code corresponding to the birth year provided on the date provided, or on the current date if no date is provided
 * @param birthYear - The birth year for which the category code should be determined
 * @param options - Additional options
 * @returns The category  corresponding to the birth year and date provided
 *
 * @example
 * ```ts
 * getCategory(2002, { date: new Date("2021-10-29") }); // Returns { code: "JU", name: "Juniors" }
 * getCategory(2002, { date: new Date("2021-11-01") }); // Returns { code: "ES", name: "Espoirs" }
 * getCategory(1970, { date: new Date("2025-01-01") }); // Returns { code: "M4", name: "Masters 4" }
 * getCategory(1970, { date: new Date("2025-01-01"), detailed: false }); // Returns { code: "MA", name: "Masters" }
 * getCategory(1970, { date: new Date("2015-01-01") }); // Returns { code: "V1", name: "Vétérans 1" }
 * getCategory(1970, { date: new Date("2015-01-01"), detailed: false }); // Returns { code: "VE", name: "Vétérans" }
 * ```
 */
declare function getCategory(birthYear: number, options?: Partial<GetCategoryOptions>): CategoryData;

/**
 * @param value The value to be checked
 * @returns True if value is a valid category code, false otherwise
 *
 * @example
 * ```ts
 * isCategoryCode("BB") // Returns true
 * isCategoryCode("SE") // Returns true
 * isCategoryCode("VE") // Returns true
 * isCategoryCode("V2") // Returns true
 * isCategoryCode("MA") // Returns true
 * isCategoryCode("M10") // Returns true
 * isCategoryCode("IN") // Returns false
 * isCategoryCode("any invalid string") // Returns false
 * ```
 */
declare function isCategoryCode(value: string): value is CategoryCode;

export { ALL_CATEGORY_CODES, ALL_CATEGORY_NAMES, type CategoryCode, type CategoryList, type CategoryName, getApplicableCategoriesYear, getCategory, getCategoryList, isCategoryCode };
