import { Breadc } from 'breadc';

interface AnimeSystem {
    space: AnimeSpace;
    /**
     * Refresh the media library
     */
    refresh(): Promise<void>;
    /**
     * Sync with the modified anime config
     */
    introspect(): Promise<void>;
}
declare function createAnimeSystem(space: AnimeSpace): Promise<AnimeSystem>;

interface Plugin {
    name: string;
    prepare?: (space: AnimeSpace) => Promise<void>;
    command?: (space: AnimeSystem, cli: Breadc<{}>) => Promise<void>;
    introspect?: (space: AnimeSystem, anime: string) => Promise<void>;
    refresh?: (space: AnimeSystem, anime: string) => Promise<void>;
}

interface RawAnimeSpace {
    readonly root: string;
    readonly storage: string;
    readonly preference: Preference;
    readonly plans: string[];
    readonly plugins: PluginEntry[];
}
interface AnimeSpace {
    readonly root: string;
    readonly storage: string;
    readonly preference: Preference;
    readonly plans: () => Promise<Plan[]>;
    readonly plugins: Plugin[];
}
interface Preference {
    readonly format: {
        readonly anime: string;
        readonly episode: string;
    };
    readonly extension: {
        readonly include: string[];
        readonly exclude: string[];
    };
    readonly keyword: {
        readonly order: Record<string, string[]>;
        readonly exclude: string[];
    };
    readonly fansub: {
        readonly order: string[];
        readonly exclude: string[];
    };
}
interface PluginEntry extends Record<string, any> {
    name: string;
}
type PlanState = 'onair' | 'finish';
type AnimePlanType = '番剧' | '电影' | 'OVA';
interface Plan {
    readonly name: string;
    readonly date: Date;
    readonly state: PlanState;
    readonly onair: AnimePlan[];
}
interface AnimePlan {
    readonly title: string;
    readonly type: AnimePlanType;
    readonly state: PlanState;
    readonly bgmId: string;
    readonly season: number;
    readonly date: Date;
    readonly keywords: KeywordsParams;
}
interface KeywordsParams {
    include: string[][];
    exclude: string[];
}

declare function loadPlan(patterns: string[]): Promise<Plan[]>;

declare function loadSpace(_root: string, importPlugin?: (entry: PluginEntry) => Plugin | undefined | Promise<Plugin | undefined>): Promise<AnimeSpace>;

declare class AnimeSystemError extends Error {
    readonly detail: string;
    constructor(detail: string);
}

declare function formatStringArray(arr: string | string[] | undefined | null): string[];

export { AnimePlan, AnimePlanType, AnimeSpace, AnimeSystem, AnimeSystemError, KeywordsParams, Plan, PlanState, Plugin, PluginEntry, Preference, RawAnimeSpace, createAnimeSystem, formatStringArray, loadPlan, loadSpace };
