import { BasePlugin } from '../../Base';
import { AppContext, IPlatformAdapter, BotController, IDatabaseInfo } from '../../../index';
/**
 * Тип ответа, который может вернуть адаптер после обработки запроса
 */
export type TContent = object | string | Promise<object | string>;
/**
 * Дополнительные опции, которые передаются в конструктор адаптера
 */
export interface IOptions {
    /**
     * Любое свойство в необходимо для работы формате
     */
    [key: string]: unknown;
}
export declare const EMPTY_QUERY_ERROR = "\u041F\u043E\u043B\u0443\u0447\u0435\u043D\u043E \u043F\u0443\u0441\u0442\u043E\u0435 \u0442\u0435\u043B\u043E \u0437\u0430\u043F\u0440\u043E\u0441\u0430 \u043E\u0442 \u043F\u043B\u0430\u0442\u0444\u043E\u0440\u043C\u044B, \u0434\u0430\u043B\u044C\u043D\u0435\u0439\u0448\u0430\u044F \u043A\u043E\u0440\u0440\u0435\u043A\u0442\u043D\u0430\u044F \u0440\u0430\u0431\u043E\u0442\u0430 \u043D\u0435\u0432\u043E\u0437\u043C\u043E\u0436\u043D\u0430. \u0421\u043A\u043E\u0440\u0435\u0435 \u0432\u0441\u0435\u0433\u043E \u0437\u0430\u043F\u0440\u043E\u0441 \u043F\u0440\u0438\u0448\u0435\u043B \u043D\u0435 \u043E\u0442 \u043F\u043B\u0430\u0442\u0444\u043E\u0440\u043C\u044B.";
export declare const EMPTY_CONTEXT_ERROR = "\u041D\u0435 \u0443\u043A\u0430\u0437\u0430\u043D \u043A\u043E\u043D\u0442\u0435\u043A\u0441\u0442 \u043F\u0440\u0438\u043B\u043E\u0436\u0435\u043D\u0438\u044F, \u0434\u0430\u043B\u044C\u043D\u0435\u0439\u0448\u0430\u044F \u0440\u0430\u0431\u043E\u0442\u0430 \u043F\u0440\u0438\u043B\u043E\u0436\u0435\u043D\u0438\u044F \u043D\u0435\u0432\u043E\u0437\u043C\u043E\u0436\u043D\u0430. \u041F\u0440\u043E\u0432\u0435\u0440\u044C\u0442\u0435 \u043A\u043E\u0440\u0440\u0435\u043A\u0442\u043D\u043E\u0441\u0442\u044C \u043D\u0430\u0441\u0442\u0440\u043E\u0439\u043A\u0438 \u043F\u0440\u0438\u043B\u043E\u0436\u0435\u043D\u0438\u044F.";
/**
 * Базовый адаптер для создания голосовых навыков и чат-ботов для собственной платформы (WeChat, WhatsApp, Slack и др.).
 *
 * Чтобы подключить другую платформу, которая не поставляется из коробки, унаследуйтесь от класса и реализуйте
 * все абстрактные методы. Адаптер автоматически зарегистрируется в системе
 * при подключении через `bot.use(new MyPlatformAdapter())`.
 *
 * === Обязательные методы ===
 * - {@link isPlatformOnQuery} — определяет, относится ли запрос к платформе или нет
 * - {@link setQueryData} — обрабатывает запрос и заполняет `controller` данными
 * - {@link getContent} — формирует ответ в формате платформы
 *
 * === Опциональные ===
 * - {@link getQueryExample} — генерирует пример запроса необходимого для тестов
 * - {@link isLocalStorage}, {@link getLocalStorage}, {@link setLocalStorage} — если платформа поддерживает сохранение локального состояния
 * - {@link soundProcessing} — кастомная обработка TTS/звуков (для голосовых платформ, или отправка аудиофайла в боте).
 *
 * @see Bot
 * @see BotController
 * @see BasePlatform
 */
export declare abstract class BasePlatform<TQuery = unknown> extends BasePlugin implements IPlatformAdapter<TQuery> {
    #private;
    /**
     * Время ответа навыка в миллисекундах при превышении этого времени, будет отправлено предупреждение
     */
    protected WARMING_TIME_REQUEST: number;
    /**
     * Максимальное время ответа навыка в миллисекундах при превышении этого времени, будет отправлена ошибка
     */
    protected MAX_TIME_REQUEST: number;
    protected _token?: string;
    protected _platformOptions?: IOptions;
    /**
     * Имя поля в заголовке запроса, по которому можно проверить корректность полученного запроса от платформы.
     */
    signatureName?: string;
    /**
     * Определяет лимит платформы.
     * В значение указывается количество запросов, которое можно отправить платформе за 1 секунду.
     * В случае если у платформы нет ограничений, можно указать 0 или null.
     * По умолчанию null
     */
    limit: number | null;
    /**
     * Контекст приложения
     */
    appContext?: AppContext<unknown, TQuery>;
    /**
     * Имя платформы
     */
    platformName: string;
    /**
     * Определяет тип платформы(голосовая или чат-бот)
     */
    isVoice: boolean;
    constructor(platformToken?: string, additionalPlatformOptions?: IOptions);
    /**
     * Инициализация адаптера.
     * Определять не обязательно. Стоит указывать в случаях, когда нужно выполнить доп логику, например указать токены или писать какую-то статистику по использованию.
     * @param appContext
     */
    init(appContext: AppContext<IDatabaseInfo, TQuery>): void;
    /**
     * Генерирует пример входящего запроса для локального тестирования вашего приложения.
     * Позволяет эмулировать запрос от платформы с заданным текстом, ID пользователя, номером сообщения и состоянием.
     * Необходимо указывать для того, чтобы можно было корректно проверить работоспособность приложения.
     *
     * Обязательно определите метод, если планируется тестирования приложения через инструменты предоставляемые платформой. Это существенно упростит процесс разработки приложения.
     * @param query Запрос пользователя
     * @param userId Идентификатор пользователя
     * @param count Порядковый номер запроса
     * @param state Данные из локального хранилища
     */
    getQueryExample(query: string, userId: string, count: number, state: Record<string, unknown> | string): Record<string, unknown>;
    /**
     * Возвращает признак того, соответствует ли запрос текущей платформе или нет
     *
     * @example Telegram
     * ```ts
     * isPlatformOnQuery(query, headers) {
     *   return headers?.['x-telegram-bot-api-secret-token'] === this._token;
     * }
     * ```
     *
     * @example Алиса (тело содержит "meta.session_id")
     * ```ts
     * isPlatformOnQuery(query) {
     *   return typeof query === 'object' && query.meta?.session_id;
     * }
     * ```
     * @param query Запрос, который пришел в приложение
     * @param headers Заголовок с которым был отправлен запрос
     * @returns `true`, если запрос относится к этой платформе, иначе `false`
     */
    abstract isPlatformOnQuery(query: TQuery, headers?: Record<string, unknown>): boolean;
    /**
     * Проверяет полученный запрос от платформы на корректность.
     * Из коробки проверка идет по sha256. Если по какой-то причине поведение по умолчанию не подходит, то просто переопределите метод.
     * @param query
     * @param headers
     */
    isCorrectQuery(query: TQuery, headers?: Record<string, unknown>): boolean;
    /**
     * Обрабатывает входящий запрос и заполняет контроллер данными.
     *
     * Обязательно установите:
     * - `controller.userCommand` и `controller.originalUserCommand` — текст сообщения пользователя
     * - `controller.userId` — уникальный ID пользователя
     * - `controller.appType` = this.platformName
     *
     * Опционально:
     * - `controller.userToken` — если платформа присылает токен авторизации
     * - `controller.userMeta` — если платформа присылает метаданные
     * - `controller.state` — если платформа поддерживает локальное хранилище
     * - `controller.nlu` — если платформа присылает NLU/интенты (через `controller.nlu.setNlu(...)`)
     *
     * @returns `false`, если запрос повреждён или не может быть обработан; иначе `true`
     * @param query Запрос от платформы
     * @param controller Контроллер приложения
     */
    abstract setQueryData(query: TQuery, controller: BotController): boolean | Promise<boolean>;
    /**
     * Формирует тело ответа для отправки пользователю.
     *
     * Возвращает платформо-специфичный ответ (например, JSON для Алисы).
     * Для платформ, которые отправляют ответ напрямую (например, Telegram через `sendMessage`),
     * метод может возвращать `{ ok: true }` или аналог.
     *
     * @param controller - контроллер с готовым ответом
     * @param stateData - данные для локального хранилища
     * @returns ответ в формате, понятном платформе
     */
    abstract getContent(controller: BotController, stateData?: Record<string, unknown> | null): TContent;
    /**
     * Формирует ответ с оценкой
     * @param controller - контроллер приложения
     */
    getRatingContext(controller: BotController): TContent;
    /**
     * Отправка текста пользователю
     * Этот метод используется для активных рассылок — когда голосовой навык или чат-бот инициирует диалог первым (например, уведомление).
     * В методе реализована механика преобразования текстового значения `controllerOrText` в контроллер, а также базовый механизм для отправки ответа.
     *
     * Переопределять данный метод не рекомендуется. Переопределить стоит только в том случае, если по каким-то технических условиям текущая реализация метода вам не подходит.
     *
     * Если платформа не поддерживает возможность начать диалог самостоятельно, то можно оставить метод пустым, либо вывести любую заглушку.
     * @param userId Ид пользователя, которому нужно отправить сообщение
     * @param controllerOrText Контроллер приложения или текст. Если необходимо отправить просто текст, можно передать строку, в случае, если необходимо передать картинку звук и тд, то необходимо корректно заполнить контроллер.
     */
    send(userId: string | number, controllerOrText: BotController | string): TContent | boolean;
    /**
     * Устанавливает время начала обработки запроса.
     * Используется для измерения времени выполнения
     */
    updateTimeStart(controller: BotController): void;
    /**
     * Получает время выполнения запроса в миллисекундах
     * @returns {number} Время выполнения запроса
     */
    getProcessingTime(controller: BotController): number;
    /**
     * При превышении установленного времени исполнения, пишет информацию в лог
     * После вызова getContent() автоматически проверяется время выполнения.
     * Если оно превышает 2000 мс — пишется warning, если >2900 мс — ошибка.
     */
    protected _timeLimitLog(controller: BotController): void;
    /**
     * Дополнительная обработка для звуков.
     * В данном методе стоит реализовать логику, с помощью которой будут наложены дополнительные эффекты для озвучивания текста пользователю
     * @param _controller
     */
    soundProcessing(_controller: BotController): void | Promise<void>;
    /**
     * Инициализирует TTS (Text-to-Speech) в контроллере.
     * Обрабатывает звуки и стандартные звуковые эффекты
     * @param controller Тип приложения
     * @protected
     */
    protected _initTTS(controller: BotController): void | Promise<void>;
    /**
     * Указывает, поддерживает ли платформа локальное хранилище.
     *
     * @param _controller - контроллер приложения
     * @returns `true`, если локальное хранилище доступно
     */
    isLocalStorage(_controller: BotController): boolean;
    /**
     * Получает данные из локального хранилища платформы.
     *
     * @param _controller - контроллер приложения
     * @returns данные, сохранённые ранее
     */
    getLocalStorage<TStorageResult = unknown>(_controller: BotController): TStorageResult | Promise<TStorageResult>;
    /**
     * Сохраняет данные в локальное хранилище платформы.
     *
     * @param _data - данные для сохранения
     * @param _controller - контроллер приложения
     */
    setLocalStorage<TStorageData>(_data: TStorageData, _controller: BotController): void | Promise<void>;
    /**
     * Флаг, указывающий, что платформа голосовая (например, Алиса, Маруся).
     */
    static isVoice(): boolean;
}
