import { Session, App, Context, User, NextFunction, Argv } from 'koishi-core';
import { Observed, Awaitable } from 'koishi-utils';
declare module 'koishi-core' {
    interface App {
        teachHistory: Record<number, Dialogue>;
    }
    interface EventMap {
        'dialogue/permit'(argv: Dialogue.Argv, dialogue: Dialogue): boolean;
        'dialogue/flag'(flag: keyof typeof Dialogue.Flag): void;
        'dialogue/test'(test: DialogueTest, query: Query.Expr<Dialogue>): void;
    }
    interface Tables {
        dialogue: Dialogue;
    }
}
export interface Dialogue {
    id?: number;
    question: string;
    answer: string;
    original: string;
    flag: number;
    _weight?: number;
    _capture?: RegExpExecArray;
    _type?: Dialogue.ModifyType;
    _operator?: string;
    _timestamp?: number;
    _backup?: Readonly<Dialogue>;
}
export interface DialogueTest {
    original?: string;
    question?: string;
    answer?: string;
    regexp?: boolean;
    activated?: boolean;
    appellative?: boolean;
    noRecursive?: boolean;
}
export namespace Dialogue {
    type ModifyType = '添加' | '修改' | '删除';
    type Field = keyof Dialogue;
    interface AuthorityConfig {
        /** 可访问教学系统，默认值为 2 */
        base?: number;
        /** 可修改非自己创建的问答，默认值为 3 */
        admin?: number;
        /** 可修改上下文设置，默认值为 3 */
        context?: number;
        /** 可修改锁定的问答，默认值为 4 */
        frozen?: number;
        /** 可使用正则表达式，默认值为 3 */
        regExp?: number;
        /** 可设置作者或匿名，默认值为 2 */
        writer?: number;
        /** 可触发教学问答，默认值为 1 */
        receive?: number;
    }
    interface Config {
        prefix?: string;
        authority?: AuthorityConfig;
        historyAge?: number;
    }
    interface Stats {
        questions: number;
        dialogues: number;
    }
    enum Flag {
        /** 冻结：只有 4 级以上权限者可修改 */
        frozen = 1,
        /** 正则：使用正则表达式进行匹配 */
        regexp = 2,
        /** 上下文：后继问答可以被上下文内任何人触发 */
        context = 4,
        /** 代行者：由教学者完成回答的执行 */
        substitute = 8,
        /** 补集：上下文匹配时取补集 */
        complement = 16
    }
    function get(ctx: Context, test: DialogueTest): Promise<Dialogue[]>;
    function get<K extends Field>(ctx: Context, ids: number[], fields?: K[]): Promise<Pick<Dialogue, K>[]>;
    function update(dialogues: Observed<Dialogue>[], argv: Argv): Promise<void>;
    function stats(ctx: Context): Promise<Stats>;
    function remove(dialogues: Dialogue[], argv: Argv, revert?: boolean): Promise<number[]>;
    function revert(dialogues: Dialogue[], argv: Argv): Promise<string>;
    function recover(dialogues: Dialogue[], argv: Argv): Promise<void>;
    function addHistory(dialogue: Dialogue, type: ModifyType, argv: Argv, revert: boolean): boolean;
    interface Argv {
        app: App;
        session: Session<'authority' | 'id'>;
        args: string[];
        config: Config;
        target?: number[];
        options: Record<string, any>;
        dialogues?: Dialogue[];
        dialogueMap?: Record<number, Dialogue>;
        skipped?: number[];
        updated?: number[];
        unknown?: number[];
        uneditable?: number[];
    }
}
export function sendResult(argv: Dialogue.Argv, prefix?: string, suffix?: string): Promise<void>;
export function split(source: string): number[];
export function equal(array1: (string | number)[], array2: (string | number)[]): boolean;
export function prepareTargets(argv: Dialogue.Argv, dialogues?: Dialogue[]): Observed<Dialogue, void>[];
export function isPositiveInteger(source: string): number;
export function isZeroToOne(source: string): number;
export const RE_DIALOGUES: RegExp;
declare module 'koishi-core' {
    interface App {
        _dialogueStates: Record<number, SessionState>;
    }
    interface EventMap {
        'dialogue/state'(state: SessionState): void;
        'dialogue/receive'(state: SessionState): void | boolean;
        'dialogue/prepare'(state: SessionState): void;
        'dialogue/before-attach-user'(state: SessionState, userFields: Set<User.Field>): void;
        'dialogue/attach-user'(state: SessionState): void | boolean;
        'dialogue/before-send'(state: SessionState): Awaitable<void | boolean>;
        'dialogue/send'(state: SessionState): void;
    }
    interface Context {
        getSessionState(this: Context, session: Session): SessionState;
    }
    interface Session {
        _redirected?: number;
    }
}
interface Question {
    /** 被 unescape 处理后原本的句子 */
    original: string;
    /** 去除句首句尾标点符号，句中空格和句首称呼的句子 */
    parsed: string;
    /** 是否含有称呼 */
    appellative: boolean;
    /** 是否仅含有称呼 */
    activated: boolean;
}
export namespace Dialogue {
    interface Config {
        nickname?: string | string[];
        appellationTimeout?: number;
        maxRedirections?: number;
        _stripQuestion?(source: string): Question;
    }
}
export interface SessionState {
    userId?: string;
    channelId?: string;
    answer?: string;
    session?: Session<User.Field>;
    test?: DialogueTest;
    dialogue?: Dialogue;
    dialogues?: Dialogue[];
    next?: NextFunction;
    isSearch?: boolean;
}
export function escapeAnswer(message: string): string;
export function unescapeAnswer(message: string): string;
export function getTotalWeight(ctx: Context, state: SessionState): Promise<number>;
export class MessageBuffer {
    private session;
    private buffer;
    private original;
    hasData: boolean;
    send: Session['send'];
    sendQueued: Session['sendQueued'];
    constructor(session: Session);
    write(message: string): void;
    private _flush;
    flush(): Promise<void>;
    execute(argv: Argv): Promise<void>;
    end(message?: string): Promise<void>;
}
export function triggerDialogue(ctx: Context, session: Session, next?: NextFunction): Promise<void>;
export interface SearchDetails extends Array<string> {
    questionType?: string;
    answerType?: string;
}
declare module 'koishi-core' {
    interface EventMap {
        'dialogue/list'(dialogue: Dialogue, output: string[], prefix: string, argv: Dialogue.Argv): void;
        'dialogue/detail-short'(dialogue: Dialogue, output: SearchDetails, argv: Dialogue.Argv): void;
        'dialogue/before-search'(argv: Dialogue.Argv, test: DialogueTest): void | boolean;
        'dialogue/search'(argv: Dialogue.Argv, test: DialogueTest, dialogue: Dialogue[]): Promise<void>;
    }
}
interface Dialogue {
    _redirections: Dialogue[];
}
export namespace Dialogue {
    interface Config {
        itemsPerPage?: number;
        mergeThreshold?: number;
        maxAnswerLength?: number;
    }
    interface Argv {
        questionMap?: Record<string, Dialogue[]>;
    }
}
export function formatAnswer(source: string, { maxAnswerLength }: Dialogue.Config): string;
export function getDetails(argv: Dialogue.Argv, dialogue: Dialogue): SearchDetails;
export function formatDetails(dialogue: Dialogue, details: SearchDetails): string;
export function formatAnswers(argv: Dialogue.Argv, dialogues: Dialogue[], prefix?: string): string[];
export function formatQuestionAnswers(argv: Dialogue.Argv, dialogues: Dialogue[], prefix?: string): string[];
declare module 'koishi-core' {
    interface EventMap {
        'dialogue/before-modify'(argv: Dialogue.Argv): Awaitable<void | string>;
        'dialogue/modify'(argv: Dialogue.Argv, dialogue: Dialogue): void;
        'dialogue/after-modify'(argv: Dialogue.Argv): Awaitable<void>;
        'dialogue/before-detail'(argv: Dialogue.Argv): Awaitable<void>;
        'dialogue/detail'(dialogue: Dialogue, output: string[], argv: Dialogue.Argv): Awaitable<void>;
    }
}
export namespace Dialogue {
    interface Config {
        previewDelay?: number;
        maxPreviews?: number;
    }
}
export function update(argv: Dialogue.Argv): Promise<string | void>;
export function create(argv: Dialogue.Argv): Promise<string | void>;
declare module 'koishi-core' {
    namespace Command {
        interface Config {
            noInterp?: boolean;
        }
    }
}
interface DialogueTest {
    groups?: string[];
    reversed?: boolean;
    partial?: boolean;
}
interface Dialogue {
    groups: string[];
}
export namespace Dialogue {
    interface Config {
        useContext?: boolean;
    }
}
export const RE_GROUPS: RegExp;
export interface ThrottleConfig {
    interval: number;
    responses: number;
}
export interface LoopConfig {
    participants: number;
    length: number;
    debounce?: number;
}
export namespace Dialogue {
    interface Config {
        throttle?: ThrottleConfig | ThrottleConfig[];
        preventLoop?: number | LoopConfig | LoopConfig[];
    }
}
interface SessionState {
    counters?: Record<number, number>;
    initiators?: string[];
    loopTimestamp?: number;
}
interface Dialogue {
    probS: number;
    probA: number;
}
interface SessionState {
    activated?: Record<number, number>;
}
interface SessionState {
    predecessors?: Record<number, Record<number, number>>;
}
interface DialogueTest {
    stateful?: boolean;
    context?: boolean;
    predecessors?: (string | number)[];
}
interface Dialogue {
    predecessors: string[];
    successorTimeout: number;
    _predecessors: Dialogue[];
    _successors: Dialogue[];
}
export namespace Dialogue {
    interface Config {
        successorTimeout?: number;
    }
    interface Argv {
        predecessors?: number[];
        successors?: number[];
        predOverwrite?: boolean;
        succOverwrite?: boolean;
    }
}
interface DialogueTest {
    matchTime?: number;
    mismatchTime?: number;
}
interface Dialogue {
    startTime: number;
    endTime: number;
}
export namespace Dialogue {
    interface Config {
        useTime?: boolean;
    }
}
export function isHours(value: string): string;
interface DialogueTest {
    writer?: string;
    frozen?: boolean;
    substitute?: boolean;
}
interface Dialogue {
    writer: string;
}
export namespace Dialogue {
    interface Argv {
        writer?: string;
        nameMap?: Record<string, string>;
        /** 用于保存用户权限的键值对，键的范围包括目标问答列表的全体作者以及 -w 参数 */
        authMap?: Record<string, number>;
    }
    interface Config {
        useWriter?: boolean;
    }
}
export type Config = Dialogue.Config;
declare module 'koishi-core' {
    interface EventMap {
        'dialogue/validate'(argv: Dialogue.Argv): void | string;
        'dialogue/execute'(argv: Dialogue.Argv): void | Promise<void | string>;
    }
    namespace Plugin {
        interface Packages {
            'koishi-plugin-teach': typeof import(".");
        }
    }
}
declare module 'koishi-plugin-webui' {
    namespace Meta {
        interface Payload extends Dialogue.Stats {
        }
    }
    namespace Statistics {
        interface Payload {
            questions: QuestionData[];
        }
    }
}
interface QuestionData {
    name: string;
    value: number;
}
export const name = "teach";
export const disposable = true;
export function apply(ctx: Context, config?: Config): void;export default function apply(ctx: Context, config: Dialogue.Config): void;
