import { Theme } from '@inquirer/core';
import { Prettify, PartialDeep } from '@inquirer/type';

/** Possible prompt statuses. */
declare const Status: {
    readonly Idle: "idle";
    readonly Done: "done";
    readonly Canceled: "canceled";
};
/** Enum of available item types. */
declare const ItemType: {
    readonly File: "file";
    readonly Directory: "directory";
};
/** Default keybinds used in the prompt. */
declare const defaultKeybinds: {
    up: string[];
    down: string[];
    back: string[];
    forward: string[];
    toggle: string[];
    confirm: string[];
    cancel: string[];
};

type Item = {
    name: string;
    path: string;
    /** Size in bytes. */
    size: number;
    /** Creation timestamp (milliseconds since POSIX Epoch). */
    createdMs: number;
    /** Last modification timestamp (milliseconds since POSIX Epoch). */
    lastModifiedMs: number;
    isDirectory: boolean;
};
type RawItem = Item & {
    displayName: string;
    isCwd: boolean;
    isSelected: boolean;
};
/** Type representing the types of items available. */
type ItemTypeUnion = (typeof ItemType)[keyof typeof ItemType];

/** Type representing possible prompt statuses. */
type StatusType = (typeof Status)[keyof typeof Status];

type HeaderHelpContext = {
    /** Indicates if multiple items can be selected. */
    multiple: boolean;
    /** Indicates if canceling is allowed. */
    allowCancel: boolean;
};
type InlineHelpContext = {
    /** Indicates the type of item expected. */
    type?: ItemTypeUnion;
    /** Indicates if multiple items can be selected. */
    multiple: boolean;
    /** The item associated with the help message. */
    item: RawItem;
};
type RenderHelpOptions = {
    type: 'header';
    context: HeaderHelpContext;
} | {
    type: 'inline';
    context: InlineHelpContext;
};
type RenderItemContext = {
    /** Items to render. */
    items: RawItem[];
    /** Indicates the type of item expected. */
    type?: ItemTypeUnion;
    /** Indicates if multiple items can be selected. */
    multiple: boolean;
    /** Indicates if the list is displayed in loop mode. */
    loop: boolean;
    /** Item index. */
    index: number;
    /** Indicates if the item is active. */
    isActive: boolean;
};
/**
 * Theme configuration for the prompt.
 *
 * Default values are defined internally by the prompt theme implementation.
 */
interface PromptTheme {
    /**
     * Prefix displayed before the prompt message.
     * Maps each `StatusType` to its corresponding prefix string.
     */
    prefix: Prettify<Record<StatusType, string>>;
    style: {
        /** Style applied to the active item. */
        active: (text: string) => string;
        /** Style applied to items of type `'directory'`. */
        directory: (text: string) => string;
        /** Style applied to items of type `'file'`. */
        file: (text: string) => string;
        /** Style applied to the current directory header. */
        currentDir: (text: string) => string;
        /** Style applied to the main message. */
        message: (text: string, status: StatusType) => string;
        /** Style applied to help messages. */
        help: (text: string) => string;
        /** Style applied to key labels used in hints. */
        key: (text: string) => string;
        messages: {
            /** Style applied to the cancel message. */
            cancel: (text: string) => string;
            /** Style applied to the empty directory message. */
            empty: (text: string) => string;
        };
    };
    labels: {
        /**
         * Labels corresponding to each keybind.
         * `style.key` is automatically applied to these values.
         */
        keys: Prettify<Record<keyof typeof defaultKeybinds, string>>;
        /**
         * Hint messages shown to the user, describing available actions.
         * Strings can contain placeholders like `{{up}}`, `{{down}}`, etc.,
         * which will be replaced by the corresponding values from `labels.keys`.
         */
        hints: {
            /** Hint for navigation actions. */
            navigate: string;
            /** Hint for going back. */
            goBack: string;
            /** Hint for going forward (open directory). */
            goForward: string;
            /** Hint for toggling selection. */
            toggle: string;
            /** Hint for confirming the selection. */
            confirm: string;
            /** Hint for canceling the prompt. */
            cancel: string;
        };
        /** Values are automatically styled using `style.messages`. */
        messages: {
            /** Message displayed when the prompt is canceled. */
            cancel: string;
            /** Message displayed when the directory is empty. */
            empty: string;
        };
    };
    hierarchySymbols: {
        /** Symbol representing a branch in the tree hierarchy. */
        branch: string;
        /** Symbol representing a leaf, marking the end of the tree hierarchy. */
        leaf: string;
    };
    /**
     * Renders the help message based on the provided options.
     * @param options - Options for rendering the help message.
     */
    renderHelp(options: RenderHelpOptions): string;
    /**
     * Renders a single item in the list.
     * @param item - The item to render.
     * @param context - Additional context about the item.
     */
    renderItem: (item: RawItem, context: RenderItemContext) => string;
}

/** Keybinds type based on the default keybinds. */
type Keybinds = typeof defaultKeybinds;
interface PromptConfig {
    /** Main message displayed in the prompt. */
    message: string;
    /**
     * Initial directory.
     * @default process.cwd()
     */
    basePath?: string;
    /**
     * Allowed item type.
     * If omitted, all items are valid.
     */
    type?: ItemTypeUnion;
    /**
     * Indicates if multiple items can be selected.
     * @default false
     */
    multiple?: boolean;
    /**
     * Max items displayed at once.
     * @default 10
     */
    pageSize?: number;
    /**
     * Indicates if navigation is looped from the last to the first element.
     * @default false
     */
    loop?: boolean;
    /**
     * Filters items in the list.
     * @param item - Item to evaluate.
     */
    filter?: (item: Readonly<Item>) => boolean;
    /**
     * Indicates if canceling is allowed.
     * @default false
     */
    allowCancel?: boolean;
    /**
     * Evaluates whether moving back into a directory is allowed.
     * @param backDir - Directory to move back to.
     */
    allowBack?: (backDir: string) => boolean;
    /**
     * Keybinds for actions.
     * If omitted, default keybinds are used.
     */
    keybinds?: Prettify<Partial<Keybinds>>;
    /** Theme applied to the file selector. */
    theme?: PartialDeep<Theme<PromptTheme>>;
}

declare function fileSelector(config: PromptConfig & {
    multiple?: false;
    allowCancel?: false;
}): Promise<Item>;
declare function fileSelector(config: PromptConfig & {
    multiple?: false;
    allowCancel: true;
}): Promise<Item | null>;
declare function fileSelector(config: PromptConfig & {
    multiple: true;
    allowCancel?: false;
}): Promise<Item[]>;
declare function fileSelector(config: PromptConfig & {
    multiple: true;
    allowCancel: true;
}): Promise<Item[] | null>;

export { ItemType, Status, fileSelector };
export type { HeaderHelpContext, InlineHelpContext, Item, ItemTypeUnion, Keybinds, PromptConfig, PromptTheme, RawItem, RenderHelpOptions, RenderItemContext, StatusType };
