import { HelperDelegate } from 'handlebars';
import Metalsmith from 'metalsmith';
import inquirer from 'inquirer';
import { ApiItem } from '../common/bridge/types';
import { AppType } from './commonData';
export interface AskHoc {
    (prompts: Prompts, metalsmith: Metalsmith): (files: string[], metalsmith: Metalsmith, done: Metalsmith.Callback) => void;
}
export interface GenerateOpt {
    name: string;
    tmpPath: string;
    to: string;
    ask: AskHoc;
    templateName?: string;
    helpers?: object;
    useDefault?: boolean;
}
export type GenerateRes = {
    data: object;
    stdout: string;
    stderr: string;
} | null;
export interface GitTemplateInfo {
    repo: string;
    git: string;
    type: string;
    _id?: string;
    name?: string;
    header?: {
        [k: string]: string;
    };
}
export interface TemplateInfo {
    id: string;
    isLocal: boolean;
    name?: GitTemplateInfo['name'];
    gitInfo: GitTemplateInfo | null;
}
export interface LoadBaseInfo {
    repo: string;
    name: string;
    branch: string;
    header: GitTemplateInfo['header'];
}
export interface TemplateConfItem {
    type: string;
    fetch: (repo: string, opt?: any) => string | string[] | Promise<string | string[]>;
    fetchInfo: (respo: string, opt?: any) => string | Promise<string>;
    filter: (data: any) => string[];
    load: (template: string, base: LoadBaseInfo) => GitTemplateInfo | void;
}
export interface FullTemplateItem {
    type: string;
    fetch: TemplateConfItem['fetch'];
    fetchInfo: TemplateConfItem['fetchInfo'];
    filter: TemplateConfItem['filter'];
    repo: string;
    name?: string;
    option?: any;
}
export type TemplateItem = {
    [k in keyof FullTemplateItem]?: FullTemplateItem[k];
} & {
    repo: FullTemplateItem['repo'];
    option?: any;
};
export interface Prompts {
    [k: string]: inquirer.DistinctQuestion;
}
interface MetaItemLocale {
    'zh-CN': string;
    'en-US': string;
}
export interface TemplateDesc {
    name: string;
    description: string;
    appType: AppType;
    meta: {
        name: MetaItemLocale;
        desc: MetaItemLocale;
        className: MetaItemLocale;
        img?: MetaItemLocale;
    };
}
export interface Filters {
    [k: string]: string;
}
export interface MetaData {
    helpers?: {
        [k: string]: HelperDelegate;
    };
    prompts?: Prompts;
    schema?: Prompts;
    filters?: Filters;
    completeMessage?: string;
    [k: string]: any;
}
export declare enum MsgSchema {
    PROMETS = 4,
    CHOOSE_FOLDER = 8,
    RESET = 16,
    SUBMIT = 32,
    CANCEL = 64,
    INFO = 128
}
export interface QuestionMap<T extends inquirer.Answers = inquirer.Answers> extends inquirer.QuestionMap<T> {
    folder: {
        type: 'folder';
    } & inquirer.Question<T>;
}
export type DistinctQuestion<T extends inquirer.Answers = inquirer.Answers> = QuestionMap<T>[keyof QuestionMap<T>] & {
    [k: string]: any;
};
interface Button {
    when?: string;
    type: typeof MsgSchema.CANCEL | typeof MsgSchema.SUBMIT;
    loading: boolean | string;
    disabled: boolean | null;
    text: string;
}
export interface FormData<T extends inquirer.Answers = inquirer.Answers> {
    formId: string;
    formType: 'base' | 'finish';
    form: DistinctQuestion<T>[];
    data: T;
    buttons: Button[];
    title?: string;
}
export interface SubmitData {
    id: FormData['formId'];
    type: FormData['formType'];
    data: FormData['data'];
}
export interface FolderInfo {
    type: FormData['formType'];
    id: FormData['formId'];
    name: string;
    data: FormData['data'];
}
export interface ApiMap {
    fetch: ApiItem<{}, FormData, {}>;
    chooseFolder: ApiItem<FolderInfo, {
        folder: string;
    }, {}>;
    check: ApiItem<{
        name: string;
        data: FormData['data'];
    }, {}, {}>;
}
export interface EventMap {
    update: (data: FormData) => void;
    submit: (data: SubmitData) => void;
    cancel: (data: FormData['data']) => void;
    reset: () => void;
}
export interface BaseAnswer {
    templateType: string;
    templatePath: string;
    tempplateName?: string;
    projectFolder: string;
    projectName: string;
    appId?: string;
}
export interface InjectApi {
    confirm: (str: string) => Promise<void>;
    message: (str: string, type: 'warn' | 'error' | 'info') => void;
    update: (data: FormData) => void;
}
export {};
