/**
 * Модуль контроллера - основной компонент для обработки бизнес-логики вашего приложения
 */
import { Buttons, Card, Sound, Nlu } from '../components';
import { AppContext, IAppIntent, TAppType } from '../core';
/**
 * Тип статуса операции
 * Определяет результат выполнения операции
 *
 * @remarks
 * Возможные значения:
 * - true: операция выполнена успешно
 * - false: операция завершилась с ошибкой
 * - null: операция не выполнялась
 *
 * @example
 * ```ts
 * const status: TStatus = true; // операция успешна
 * const status: TStatus = false; // операция с ошибкой
 * const status: TStatus = null; // операция не выполнялась
 * ```
 */
export type TStatus = true | false | null;
/**
 * Интерфейс событий пользователя
 * Содержит информацию о различных действиях пользователя в приложении
 *
 * @remarks
 * События включают:
 * - Авторизацию пользователя
 * - Оценку приложения
 *
 * @example
 * ```ts
 * const userEvent: IUserEvent = {
 *   auth: { // Событие авторизации
 *     status: true // пользователь успешно авторизовался
 *   },
 *   rating: { // Событие с оценкой
 *     status: true,
 *     value: 5 // пользователь поставил оценку 5
 *   }
 * };
 * ```
 */
export interface IUserEvent {
    /**
     * Информация об авторизации пользователя.
     * Содержит статус авторизации и дополнительные данные
     */
    auth?: {
        /**
         * Статус авторизации
         * @remarks
         * - true: авторизация успешна
         * - false: авторизация не удалась
         * - null: авторизация не выполнялась
         */
        status: TStatus;
    };
    /**
     * Информация об оценке приложения пользователем.
     * Содержит статус оценки и её значение
     */
    rating?: {
        /**
         * Статус выставления оценки
         * @remarks
         * - true: оценка выставлена
         * - false: пользователь отказался от оценки
         * - null: оценка не запрашивалась
         */
        status: TStatus;
        /**
         * Числовое значение выставленной оценки
         * @remarks
         * Обычно от 1 до 5
         */
        value?: number;
    };
}
/**
 * Интерфейс для пользовательских данных
 * Расширяемый интерфейс для любых дополнительных данных, которые будут сохранены в БД/Локальное хранилище
 *
 * @remarks
 * Базовое поле:
 * - oldIntentName: название предыдущего интента. Актуально для случаев, когда в приложении есть какая-то последовательность действий.
 * Также данное значение можно использовать при регистрации обработчика на шаг(bot.step('...', ()=>{...})).
 *
 * Дополнительные поля могут быть добавлены через:
 * 1. Расширение интерфейса (extends)
 * 2. Индексную сигнатуру [key: string]: unknown. Не рекомендуется к использованию, так как в таком случае, теряются преимущества ts
 *
 * @example
 * ```ts
 * // Способ 1: Расширение интерфейса
 * interface MyUserData extends IUserData {
 *   name: string;
 *   preferences: {
 *     language: string;
 *     theme: string;
 *   };
 * }
 *
 * // Способ 2: Использование индексной сигнатуры
 * interface DynamicUserData extends IUserData {
 *   [key: string]: unknown;
 * }
 *
 * const userData: MyUserData = {
 *   oldIntentName: 'greeting',
 *   name: 'John',
 *   preferences: {
 *     language: 'ru',
 *     theme: 'dark'
 *   }
 * };
 *
 * const dynamicData: DynamicUserData = {
 *   oldIntentName: 'greeting',
 *   customField1: 'value1',
 *   customField2: 42,
 *   customObject: {
 *     nested: true
 *   }
 * };
 * ```
 */
export interface IUserData {
    /**
     * Название предыдущего интента.
     * Используется для отслеживания контекста диалога, и реализации механизма для последовательного прохождения сценария приложения.
     *
     * @example
     * ```ts
     * this.userData.oldIntentName = 'greeting';
     * ```
     */
    oldIntentName?: string | null;
    /**
     * Дополнительные пользовательские данные.
     * Может содержать любые поля, специфичные для приложения
     * Важно! Если вы хотите чтобы поле было удалено, то необходимо в значение передавать null. Подобное связано с ограничением Алисы.
     */
    [key: string]: unknown;
}
/**
 * Интерфейс для пользовательских данных, хранящихся в локальном хранилище
 * Расширяемый интерфейс для любых дополнительных данных, которые будут сохранены в Локальное хранилище
 */
export interface IPlatformData {
    /**
     * Дополнительные данные.
     * Может содержать любые поля, специфичные для приложения
     */
    [key: string]: unknown;
}
/**
 * Дополнительные опции для платформ
 */
export interface IPlatformOptions {
    /**
     * Текст ошибки
     */
    error?: string;
    /**
     * Время начало обработки запроса
     */
    timeStart?: number;
    /**
     * Флаг говорящий о том, что результат выполнения приложения бы получен при обработке запроса
     */
    sendInInit?: string | object | null;
    /**
     * Поле куда должны сохраниться пользовательские данные
     */
    stateName?: string;
    /**
     * Флаг, говорящий о том, что в приложении может использоваться локальное хранилище платформы
     */
    isState?: boolean;
    /**
     * Флаг, говорящий о том, что приложение использует локальное хранилище платформы
     */
    usedLocalStorage?: boolean;
    /**
     * Информация о сессии пользователя
     */
    session?: object;
    /**
     * Идентификатор приложения
     */
    appId?: string;
    /**
     * ID callback-запроса
     */
    callbackQueryId?: string;
}
/**
 * Контроллер приложения – главный класс для реализации единой бизнес-логики вашего приложения. Именно в этом классе обрабатывается вся логика вашего приложения, которая потом передается в саму платформу, будь то голосовой навык для Алисы, либо чат-бот для VK.
 *
 * Этот класс связывает входящие запросы от пользователя с вашей бизнес‑логикой.
 * Вы наследуетесь от `BotController`, переопределяете метод {@link action} и получаете доступ ко всем инструментам:
 * кнопкам, карточкам, состоянию диалога, пользовательским данным, NLU и многому другому.
 *
 * Адаптеры платформ (например, `AlisaAdapter`) автоматически наполняют контроллер данными,
 * вызывают внутренний метод `{@link run}` (он вызывает ваш `action()`), а затем формируют ответ на основе заполненных вами полей (`text`, `buttons`, `card` и т.д.).
 *
 * **Ключевая особенность:** вся логика вашего голосового навыка или бота описывается в одном месте – в методе `action()`.
 * Фреймворк сам позаботится о маршрутизации: команды, интенты, шаги диалога – всё придёт в `action` с соответствующим флагом.
 *
 * @remarks
 * Основные возможности:
 * - Обработка пользовательских команд и интентов
 * - Управление состоянием диалога
 * - Работа с UI компонентами (кнопки, карточки)
 * - Управление пользовательскими данными
 *
 * @example
 * ```ts
 * import { BotController } from 'umbot';
 * // Определение пользовательских данных
 * interface MyUserData extends IUserData {
 *   score: number;
 *   level: number;
 *   preferences: {
 *     language: string;
 *     theme: string;
 *   };
 * }
 *
 * class MyController extends BotController<MyUserData> {
 *   public action(intentName: string | null): void {
 *     try {
 *       // Обработка приветствия
 *       if (intentName === WELCOME_INTENT_NAME) {
 *         // Текстовый ответ
 *         this.text = 'Привет! Чем могу помочь?';
 *
 *         // Добавление кнопок
 *         this.buttons
 *           .addBtn('Помощь')
 *           .addBtn('Выход');
 *
 *         // Добавление карточки
 *         this.card
 *           .addImage('xxx', 'Добро пожаловать!', 'Выберите действие:')
 *           .addButton('Начать игру')
 *
 *         // Установка пользовательских данных
 *         this.userData = {
 *           score: 0,
 *           level: 1,
 *           preferences: {
 *             language: 'ru',
 *             theme: 'light'
 *           }
 *         };
 *         return;
 *       }
 *
 *       // Обработка команды помощи
 *       if (intentName === HELP_INTENT_NAME) {
 *         this.text = 'Я могу помочь вам с...';
 *         this.buttons.addBtn('Назад');
 *         return;
 *       }
 *
 *       // Обработка пользовательских событий
 *       if (this.userEvents?.auth?.status) {
 *         this.text = 'Вы успешно авторизовались!';
 *       }
 *
 *       // Обработка оценки
 *       if (this.userEvents?.rating?.status) {
 *         const rating = this.userEvents.rating.value;
 *         this.text = `Спасибо за оценку ${rating}!`;
 *       }
 *
 *     } catch (error) {
 *       // Обработка ошибки
 *       this.text = 'Произошла ошибка. Попробуйте позже.';
 *     }
 *   }
 * }
 * ```
 * @see {@link action} – переопределите этот метод, чтобы добавить свою логику.
 * @see Bot – основной класс приложения, управляющий адаптерами и контроллерами.
 */
export declare abstract class BotController<TUserData extends IUserData = IUserData, TPlatformState extends IPlatformData = IPlatformData> {
    #private;
    /**
     * Текст, который будет отображен пользователю.
     * Основной способ коммуникации с пользователем, так как именно этот текст пользователь увидит в интерфейсе.
     *
     * @example
     * ```ts
     * this.text = 'Привет! Чем могу помочь?';
     * ```
     */
    text: string;
    /**
     * Текст, который пользователь может услышать.
     * Для голосовых платформ, озвучка будет произведена силами самой платформы, для не голосовых платформ, поведение зависит непосредственно от реализации адаптера.
     * Так для некоторых стандартных адаптеров, в случае заполнения поля и указания токена yandex SpeechKit, будет отправлен запрос на преобразование текста в аудиофайл, после чего аудиофайл будет отправлен пользователю.
     *
     * @example
     * ```ts
     * this.tts = 'Привет! Я голосовой ассистент.';
     * ```
     */
    tts: string | null;
    /**
     * Уникальный идентификатор пользователя.
     *
     * @example
     * ```ts
     * this.userId = 'user_123';    // Telegram (string)
     * this.userId = 123456789;     // VK (number)
     * this.userId = null;          // не удалось получить информацию
     * ```
     */
    userId: string | number | null;
    /**
     * Пользовательский токен авторизации.
     * Используется для авторизованных запросов (например, в Алисе).
     *
     * @example
     * ```ts
     * this.userToken = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...';
     * ```
     */
    userToken: string | null;
    /**
     * Дополнительная информация о пользователе.
     *
     * @example
     * ```ts
     * this.userMeta = {
     *   timezone: 'Europe/Moscow',
     *   locale: 'ru-RU'
     * };
     * ```
     */
    userMeta: unknown | null;
    /**
     * ID сообщения.
     * Используется для определения начала нового диалога.
     *
     * @example
     * ```ts
     * this.messageId = 12345;
     * ```
     */
    messageId: number | string | null;
    /**
     * Запрос пользователя в нижнем регистре.
     *
     * @example
     * ```ts
     * this.userCommand = 'привет мир';
     * ```
     */
    userCommand: string | null;
    /**
     * Оригинальный запрос пользователя.
     * Текст запроса без изменений, включая регистр и знаки препинания.
     *
     * @example
     * ```ts
     * this.originalUserCommand = 'Привет, мир!';
     * ```
     */
    originalUserCommand: string | null;
    /**
     * Дополнительные параметры запроса.
     * Может содержать любые дополнительные данные полученные от платформы.
     *
     * @example
     * ```ts
     * this.payload = {
     *   source: 'mobile',
     *   version: '1.0'
     * };
     * ```
     */
    payload: Record<string, unknown> | string | null | undefined;
    /**
     * Пользовательские данные, который были сохранены.
     *
     * @example
     * ```ts
     * this.userData = {
     *   name: 'John',
     *   preferences: {
     *     language: 'ru'
     *   }
     * };
     * ```
     */
    userData: TUserData;
    /**
     * Флаг необходимости авторизации.
     * Определяет, требуется ли авторизация пользователя или нет.
     *
     * @example
     * ```ts
     * this.isAuth = true; // требуется авторизация
     * ```
     */
    isAuth: boolean;
    /**
     * Пользовательские событий.
     * Содержит информацию об авторизации или оценке.
     *
     * @see IUserEvent
     * @example
     * ```ts
     * this.userEvents = {
     *   auth: { status: true },
     *   rating: { status: true, value: 5 }
     * };
     * ```
     */
    userEvents: IUserEvent | null;
    /**
     * Пользовательское локальное хранилище.
     * Используется для временного хранения данных, специфичных для текущего диалога.
     * Работает только при включённой опции `isLocalStorage: true` в конфигурации.
     * bot.setAppConfig({
     *    isLocalStorage: true,
     * });
     *
     * **Правила синхронизации с базой данных (если подключена):**
     * - Если заполнены и `userData`, и `state`:
     *   - `userData` сохраняется в БД,
     *   - `state` сохраняется в локальное хранилище платформы.
     * - Если заполнен только `userData` (а `state` пуст или равен `userData`):
     *   - данные сохраняются только в БД (состояние платформы не обновляется).
     * - Если заполнен только `state`:
     *   - данные сохраняются только в локальное хранилище.
     *
     * **При загрузке данных:**
     * 1. Если есть данные из локального хранилища и из БД, они попадают соответственно в `state` и `userData`.
     * 2. Если есть только данные из хранилища, они копируются и в `userData`, и в `state` (для удобства).
     * 3. Если есть только данные из БД, они записываются в `userData`.
     *
     * @see {@link userData} — для постоянного хранения данных пользователя.
     *
     * @example
     * ```ts
     * this.state = {
     *   lastIntent: 'greeting',
     *   step: 1
     * };
     * ```
     */
    state: TPlatformState | null;
    /**
     * Определяет, с колонки пользователь запустил приложение или с устройства с экраном.
     *
     * @example
     * ```ts
     * this.isScreen = true; // экран доступен
     * ```
     */
    isScreen: boolean;
    /**
     * Флаг, определяющий необходимость завершения диалога. Актуально когда необходимо принудительно завершить диалог с пользователем.
     * Поддержка работы флага зависит от платформы.
     *
     * @example
     * ```ts
     * this.isEnd = true; // завершить диалог
     * ```
     */
    isEnd: boolean;
    /**
     * Флаг, указывающий, что ответ уже отправлен через API и не требуется автоматическая отправка. Как правило, данный флаг стоит использовать для платформ, которые не ждут ответ в виде возвращаемого содержимого, а ожидают что к самой платформе будет отправлен запрос. Например, чат-бот для Telegram, для отображения результата пользователю, отправляется запрос к платформе с нужным содержимым.
     *
     * @remarks
     * Если указано true, значит все необходимые запросы уже отправлены в логике приложения, и дополнительно пользователю ничего отправлять не нужно.
     *
     * @example
     * ```ts
     * this.skipAutoReply = true; // запросы уже отправлены
     * ```
     */
    skipAutoReply: boolean;
    /**
     * Полученный запрос от платформы.
     * Содержит оригинальный объект запроса.
     *
     * @example
     * ```ts
     * this.requestObject = {
     *   command: 'start',
     *   payload: { source: 'mobile' }
     * };
     * ```
     */
    requestObject: Record<string, unknown> | string | unknown | null;
    /**
     * Название текущего интента.
     * Определяет следующий шаг диалога.
     *
     * @example
     * ```ts
     * this.thisIntentName = 'help';
     * ```
     */
    thisIntentName: string | null;
    /**
     * Эмоция для голосового ответа.
     * Используется для платформ, которые поддерживают данное поведение.
     *
     * @example
     * ```ts
     * this.emotion = 'good';
     * ```
     */
    emotion: string | null;
    /**
     * Стиль обращения к пользователю.
     * Определяет формальность общения, используется для платформ, которые поддерживают данное поведение.
     *
     * @remarks
     * Возможные значения:
     * - 'official': официальное обращение
     * - 'no_official': неофициальное обращение
     * - null: стиль не определен
     *
     * @example
     * ```ts
     * this.appeal = 'official'; // официальное обращение
     * ```
     */
    appeal: 'official' | 'no_official' | null;
    /**
     * Флаг отправки запроса на оценку.
     * Определяет, нужно ли запросить оценку у пользователя.
     * Используется для платформ, которые поддерживают данное поведение.
     *
     * @example
     * ```ts
     * this.isSendRating = true; // запросить оценку
     * ```
     */
    isSendRating: boolean;
    /**
     * Название предыдущего интента/команды, полученное из `userData.oldIntentName`.
     * Используется для отслеживания контекста диалога.
     *
     * @remarks
     * **КАК ЭТО РАБОТАЕТ:**
     * 1. В конце обработки каждого запроса, `this.thisIntentName` сохраняется в `userData.oldIntentName`
     * 2. При следующем запросе это значение копируется в `this.oldIntentName`
     * 3. Используется для определения, с какого шага продолжить диалог
     *
     * **ТИПИЧНОЕ ИСПОЛЬЗОВАНИЕ:**
     * - Возврат к предыдущему шагу
     * - Многошаговые формы ("вернуться назад")
     * - Диалоги с контекстом
     * - Использование в шагах `bot.addStep()`
     *
     * @example
     * ```ts
     * // Пример: Многошаговая регистрация
     * class RegistrationBot extends BotController {
     *   public action(intentName: string | null): void {
     *     // Определяем на каком шаге находимся
     *     const previousStep = this.oldIntentName;
     *
     *     if (previousStep === 'enter_name') {
     *       // Пользователь только что ввел имя, спрашиваем email
     *       this.userData.name = this.userCommand;
     *       this.text = 'Отлично! Теперь введите ваш email:';
     *       this.thisIntentName = 'enter_email'; // Сохранится для следующего шага
     *     } else if (previousStep === 'enter_email') {
     *       // Пользователь ввел email, завершаем регистрацию
     *       this.userData.email = this.userCommand;
     *       this.text = 'Регистрация завершена!';
     *     }
     *   }
     * }
     *
     * // Пример: Кнопка "Назад"
     * if (intentName === 'back') {
     *   // Возвращаемся к предыдущему шагу
     *   switch(this.oldIntentName) {
     *     case 'product_list':
     *       this.text = 'Выберите категорию:';
     *       break;
     *     case 'category_list':
     *       this.text = 'Добро пожаловать!';
     *       break;
     *   }
     * }
     * ```
     */
    oldIntentName: string | null;
    /**
     * Контекст приложения.
     */
    appContext: AppContext;
    /**
     * Платформа от которой был получен запрос.
     */
    appType: TAppType | null;
    /**
     * Дополнительные опции платформы.
     * ⚠️ Внутреннее свойство. Заполняется адаптером платформы.
     * Не предназначено для прямого использования в пользовательском коде.
     */
    platformOptions: IPlatformOptions;
    /**
     * Создает новый экземпляр контроллера.
     * Инициализирует все необходимые компоненты.
     */
    constructor(appContext?: AppContext);
    /**
     * Компонент для отображения различных кнопок пользователю.
     * Позволяет создавать интерактивные элементы управления в приложении.
     *
     * @remarks
     * ## 🎯 ТИПИЧНОЕ ИСПОЛЬЗОВАНИЕ:
     * - Навигация по меню
     * - Быстрые ответы (Да/Нет)
     * - Выбор из вариантов
     * - Быстрое действие/команда
     *
     *
     * @see Buttons
     * @example
     * ```ts
     * this.buttons
     *   .addBtn('Помощь')
     *   .addBtn('Выход');
     * ```
     */
    get buttons(): Buttons;
    /**
     * Флаг возвращающий информацию о том, были ли инициализированы кнопки или нет
     * @returns
     */
    isButtonsInit(): boolean;
    /**
     * Компонент для отображения карточек пользователю.
     * Позволяет создавать визуальные элементы с изображениями и текстом.
     * Также при указании нескольких изображений, они автоматически преобразуются в карточку.
     *
     * @remarks
     * ## 🎯 КОГДА ИСПОЛЬЗОВАТЬ:
     * - Каталог товаров/услуг
     * - Галерея изображений
     * - Карточки статей/новостей
     * - Навигация
     *
     * @see Card
     * @example
     ```ts
     * // КАТАЛОГ ТОВАРОВ (интернет-магазин):
     * this.text = 'Популярные товары:';
     * this.card
     *   .addImage(
     *     'http://localhost/iphone.jpg',
     *     'iPhone 15 Pro',
     *     '99 990 ₽\nЭкран 6.1", процессор A17 Pro'
     *   )
     *   .addButton('Купить')
     *
     *   .addImage(
     *     'http://localhost/macbook.jpg',
     *     'MacBook Air M2',
     *     '124 990 ₽\n13.6", 8ГБ RAM, 256ГБ SSD'
     *   )
     *   .addButton('Купить');
     *
     * // ГАЛЕРЕЯ ФОТОГРАФИЙ:
     * this.text = 'Наши работы:';
     * this.card
     *   .addImage('photo1.jpg', 'Свадьба', 'Иван и Мария')
     *   .addImage('photo2.jpg', 'Выпускной', 'Школа №123')
     *   .addImage('photo3.jpg', 'Корпоратив', 'Компания "Рога и копыта"');
     *
     * // КАРТОЧКИ НОВОСТЕЙ:
     * this.card
     *   .addImage(
     *     'news1.jpg',
     *     'Новое обновление',
     *     'Добавлена оплата картой и доставка',
     *     {
     *         title: 'Перейти',
     *         url: 'http://localhost/news/1'
     *     }
     *   )
     * ```
     */
    get card(): Card;
    /**
     * Флаг возвращающий информацию о том, были ли инициализированы карточки или нет
     * @returns
     */
    isCardInit(): boolean;
    /**
     * Компонент для работы со звуками.
     * Позволяет добавлять звуковые эффекты и музыку. Используется вместе с tts.
     *
     * @see Sound
     */
    get sound(): Sound;
    /**
     * Флаг возвращающий информацию о том, были ли инициализированы звуки или нет
     * @returns
     */
    isSoundInit(): boolean;
    /**
     * Обработанный NLU (Natural Language Understanding).
     * Содержит результаты обработки естественного языка, как правило, данные заполняются самой платформой.
     *
     * @see Nlu
     */
    get nlu(): Nlu;
    /**
     * Флаг возвращающий информацию о том, были ли инициализирован nlu или нет
     * @returns
     */
    isNluInit(): boolean;
    /**
     * Устанавливает контекст приложения.
     * @param appContext
     */
    setAppContext(appContext: AppContext): this;
    /**
     * Очищает все временные данные необходимые для отправки ответа.
     */
    clearStoreData(): void;
    /**
     * Возвращает список всех зарегистрированных интентов.
     *
     * @returns {IAppIntent[]} Массив интентов
     */
    protected _intents(): IAppIntent[];
    /**
     * Находит нужный интент по тексту запроса.
     *
     * @param {string | null} text - Текст запроса
     * @returns {string | null} Название интента или null
     */
    protected _getIntent(text: string | null): string | null;
    /**
     * Извлекает нужную команду из запроса.
     *
     * @returns {string | null} найденная команда или null если не удалось найти команду
     */
    protected _getCommand(): void | null | Promise<void>;
    /**
     * Основной метод, в котором вы реализуете логику вашего голосового навыка или бота.
     *
     * Этот метод вызывается фреймворком автоматически после того, как запрос пользователя
     * был распознан как команда, интент или шаг диалога.
     * В параметр `intentName` передаётся имя команды.
     * Флаги `isCommand` и `isStep` позволяют различить источник вызова.
     * Используется для более глубокой логики приложения, например можно использовать в качестве логирования, если все обработчики реализованы через команды.
     * Либо использовать в качестве обработки команд, что не рекомендуется, так как из-за подобного подхода, размер метода может быть большим.
     *
     * Метод необходимо обязательно реализовать в дочерних классах.
     *
     * @param {string | null} intentName - Название интента или команды
     * @param {boolean} [isCommand=false] - Флаг, указывающий что это команда
     * @param {boolean} [isStep=false] - Флаг, указывающий что это шаг
     *
     * @example
     * ```ts
     * // Пример с обработкой интентов
     * class MyController extends BotController {
     *   public action(intentName: string | null): void {
     *     if (intentName === 'greeting') {
     *       this.text = 'Привет!';
     *     } else if (intentName === 'help') {
     *       this.text = 'Помощь:';
     *       this.buttons.addBtn('Назад');
     *     }
     *   }
     * }
     *
     * // Пример с логированием
     * class MyController extends BotController {
     *   public action(intentName: string | null, isCommand?: boolean, isStep?: boolean): void {
     *     console.log(`Прошли по ${isCommand ? 'команде' : isStep ? 'шагу' : 'интенту'} с именем: ${intentName}`);
     *   }
     * }
     * ```
     */
    abstract action(intentName: string | null, isCommand?: boolean, isStep?: boolean): void;
    /**
     * Запуск обработки пользовательских команд с учетом метрик.
     * @param commandName
     * @param isCommand
     * @param isStep
     */
    protected _actionMetric(commandName: string | null, isCommand?: boolean, isStep?: boolean): void;
    /**
     * Основной метод обработки запроса, вызываемый автоматически фреймворком.
     *
     * @remarks
     * **КРАТКИЙ ОБЗОР РАБОТЫ:**
     * 1. Пользователь отправляет сообщение → платформа → Bot.run()
     * 2. `run()` определяет тип запроса (команда/интент/шаг)
     * 3. Вызывается ваш метод `action()` с результатом
     * 4. Вы заполняете поля ответа (`text`, `buttons`, `card`)
     * 5. Bot отправляет ответ пользователю
     *
     * **ЧТО НЕ НУЖНО ДЕЛАТЬ:**
     * - ❌ Не вызывайте `run()` вручную в своем коде
     * - ❌ Не переопределяйте этот метод
     * - ✅ Переопределяйте только метод `action()` для своей логики
     *
     * **ПОСЛЕДОВАТЕЛЬНОСТЬ ОБРАБОТКИ ВНУТРИ run():**
     * ```
     * run()
     *   ├── Шаг 1: Проверяет есть ли активный шаг
     *   │     → Если есть → вызывает action(stepName, false, true)
     *   ├── Шаг 2: Ищет команду
     *   │     → Если нашел → вызывает action(commandName, true, false)
     *   ├── Шаг 3: Ищет интент
     *   │     → Если нашел → вызывает action(intentName, false, false)
     *   └── Шаг 4: Если ничего не нашел → Fallback команда
     * ```
     *
     * @example
     * ```ts
     * // ВАШ КОД (контроллер):
     * class MyController extends BotController {
     *   public action(intentName: string | null): void {
     *     // Ваша логика здесь
     *     this.text = "Ответ пользователю";
     *   }
     * }
     *
     * // КОД ФРЕЙМВОРКА (не ваш):
     * // Когда приходит запрос от пользователя:
     * const controller = new MyController();
     * {...}; // Наполняет контроллер данными. Как правило, этим занимается адаптер платформы
     * await controller.run(); // Автоматически вызывает ваш action()
     * const response = ...; // Адаптер формирует ответ в зависимости от состояния контроллера
     * ```
     *
     * @returns {void | Promise<void>} Может быть асинхронным
     */
    run(): void | Promise<void>;
}
