import { SelectOptions, Option, TextOptions } from '@clack/prompts';

type ParsedFn<V> = (parsed: Record<string, string>) => Promise<V> | V;
interface PromptSelect extends Omit<SelectOptions<string>, 'options' | 'message'> {
    type: 'select';
    key: string;
    message?: string;
    options: ParsedFn<Option<string>[]> | Option<string>[];
}
interface PromptText extends Omit<TextOptions, 'message'> {
    type: 'text';
    key: string;
    message?: string;
}
interface PromptHandler {
    type: 'handler';
    key: string;
    handler: ParsedFn<string>;
}
type Prompt = PromptSelect | PromptText | PromptHandler;
interface Environment {
    [key: string]: string;
}
interface EnvironmentOptions {
    entries?: string[];
    before?: Environment;
    after?: Environment;
    depth?: boolean;
}
interface Command extends Omit<SelectOptions<string>, 'message' | 'options'>, EnvironmentOptions {
    message?: string;
    prompts?: Prompt[];
    command: string | Option<string>[];
}
type Script = Command | string;
interface UserConfig {
    injects?: EnvironmentOptions;
    scripts?: {
        [command: string]: Script | string;
    };
}
interface LoadEnvironmentOptions {
    /**
     * set environment variables entry
     *
     * @example
     * // load .env, .env.local
     * entry: ['env', 'local']
     */
    entries?: string[];
    /**
     * set environment variables
     *
     * @example
     * // set environment variables
     * values: {
     *   NODE_ENV: 'production',
     *   PORT: '3000'
     * }
     */
    env?: Record<string, string>;
    /**
     * set environment variables to .env file
     */
    write?: boolean;
    /**
     * command to run
     */
    run?: string | string[];
    /**
     * deep load and merge environment variables
     */
    depth?: boolean;
}

export type { Command, Environment, EnvironmentOptions, LoadEnvironmentOptions, ParsedFn, Prompt, PromptHandler, PromptSelect, PromptText, Script, UserConfig };
