import { AppContext, IAppDB, IDatabaseAdapter, IDatabaseInfo, IDbResult, IModelRes, TQueryCb, IQueryData, IQuery } from '../../../index';
import { BasePlugin } from '../../Base';
/**
 * Базовый класс для создания адаптеров баз данных.
 * При наследовании вы ОБЯЗАНЫ реализовать следующие методы:
 *   - _select - Получение данных
 *   - _insert - Добавление данных
 *   - _update - Обновление данных
 *   - _remove - Удаление данных
 *   - isConnected - Проверка не то, есть ли подключение к базе или нет
 *
 * Эти методы вызываются внутренней логикой фреймворка и определяют, как именно выполняются операции с вашей БД.
 *
 * Рекомендуется наследоваться от этого класса при создании собственного адаптера, так как он уже реализует общую логику: интеграцию с контекстом приложения, сбор метрик, управление соединениями.
 *
 * Если по техническим причинам наследование невозможно — ваш класс должен в точности реализовывать интерфейс `IDatabaseAdapter`
 *
 * ⚠️ Важно: в приложении может быть активен только один адаптер БД.
 */
export declare abstract class Base<TDbInfo extends IDatabaseInfo = IDatabaseInfo> extends BasePlugin implements IDatabaseAdapter {
    /**
     * Формат базы данных
     */
    dbFormat: string;
    /**
     * Контекст приложения
     * @protected
     */
    protected _appContext: AppContext<TDbInfo>;
    /**
     * Дополнительные опции для работы базы данных
     */
    protected _dbOptions?: IAppDB;
    /**
     * Конструктор для адаптера базы данных
     * @param options Дополнительные опции для настройки БД.
     * Тут можно передать настройки для подключения к базе, либо дополнительную информацию, необходимую для работы.
     */
    constructor(options?: IAppDB);
    /**
     * Метод инициализации адаптера.
     * Вызывается один раз при подключении через `bot.use()`.
     * В данном методе можно произвести дополнительную настройку для подключения к базе
     * @param appContext Контекст приложения
     */
    init(appContext: AppContext<unknown>): void;
    /**
     * Устанавливает подключение к базе данных.
     * В случае успешного подключения возвращается true
     */
    connect(): Promise<boolean> | boolean;
    /**
     * Удобный метод для извлечения данных из результата запроса.
     * Проверяет `res.status` и возвращает `res.data` только при успехе.
     *
     * Используется в моделях и контроллерах для безопасного доступа к данным.
     * @param res Результат запроса. В случае успешного запроса вернутся данные, в противном случае null
     */
    getValue(res: IModelRes<IDbResult>): IDbResult | null;
    /**
     * Выполняет SELECT-запрос.
     *
     * Этот метод вызывается внутренней логикой фреймворка для получения данных.
     * Вы обязаны вернуть объект, совместимый с `IModelRes<IDbResult>`, где:
     * - `status: true` и `data` — при успешной выборке (даже если найдено 0 записей);
     * - `status: false` и опционально `error` — при ошибке подключения, синтаксиса и т.п.
     *
     * ⚠️ Не выбрасывайте исключения — обрабатывайте ошибки внутри и возвращайте `status: false`.
     * Метод может быть синхронным или асинхронным.
     *
     * Пример возвращаемого значения при успехе:
     * ```ts
     * { status: true, data: [{ id: 1, name: 'Alice' }] }
     * ```
     *
     * Пример при ошибке:
     * ```ts
     * { status: false, error: 'Connection timeout' }
     * ```
     *
     * @param selectData Дополнительная информация для запроса. Содержит информацию о таблице и структуре.
     * @param where Сам запрос
     * @param isOne Определяет нужно ли вернуть только 1 найденную запись, либо отдать все доступные данные.
     */
    abstract _select(selectData: IQuery, where: IQueryData | null, isOne: boolean): IModelRes | Promise<IModelRes>;
    /**
     * Выполняет INSERT-запрос.
     *
     * Этот метод вызывается внутренней логикой фреймворка для добавления данных.
     * Вы обязаны вернуть:
     *   - `true` — если запись успешно добавлена,
     *   - `false` — при любой ошибке (подключение, валидация и т.п.).
     *
     * ⚠️ Не выбрасывайте исключения — обрабатывайте ошибки внутри и возвращайте `false`.
     * Метод может быть синхронным или асинхронным.
     *
     * @param insertData Дополнительная информация для запроса. Содержит сам запроса, а также название таблицы и прочие данные.
     */
    abstract _insert(insertData: IQuery): boolean | Promise<boolean>;
    /**
     * Выполняет UPDATE-запрос.
     *
     * Этот метод вызывается внутренней логикой фреймворка для обновления данных.
     * Вы обязаны вернуть:
     *   - `true` — если запись успешно добавлена,
     *   - `false` — при любой ошибке (подключение, валидация и т.п.).
     *
     * ⚠️ Не выбрасывайте исключения — обрабатывайте ошибки внутри и возвращайте `false`.
     * Метод может быть синхронным или асинхронным.
     *
     * @param updateData Дополнительная информация для запроса. Содержит сам запроса, а также название таблицы и прочие данные.
     */
    abstract _update(updateData: IQuery): boolean | Promise<boolean>;
    /**
     * Выполняет DELETE-запрос.
     *
     * Этот метод вызывается внутренней логикой фреймворка для удаления данных.
     * Вы обязаны вернуть:
     *   - `true` — если запись успешно добавлена,
     *   - `false` — при любой ошибке (подключение, валидация и т.п.).
     *
     * ⚠️ Не выбрасывайте исключения — обрабатывайте ошибки внутри и возвращайте `false`.
     * Метод может быть синхронным или асинхронным.
     *
     * @param removeData Дополнительная информация для запроса. Содержит сам запроса, а также название таблицы и прочие данные.
     */
    abstract _remove(removeData: IQuery): boolean | Promise<boolean>;
    /**
     * Выполняет произвольный запрос через callback.
     * Если вы планируете использовать `query()`, обязательно переопределите `_query`. По умолчанию он возвращает null и не выполняет никаких действий.
     *
     * @param _callback функция обработчик
     */
    _query(_callback: TQueryCb): Promise<unknown> | unknown;
    /**
     * Выполняет SELECT-запрос.
     *
     * Внутри себя вызывает this._select, основное отличие в том, что в данном методе пишутся метрики.
     * @param selectData Дополнительная информация для запроса. Содержит информацию о таблице и структуре.
     * @param where Сам запрос
     * @param isOne Определяет нужно ли вернуть только 1 найденную запись, либо отдать все доступные данные.
     */
    select(selectData: IQuery, where: IQueryData | null, isOne: boolean): Promise<IModelRes>;
    /**
     * Выполняет INSERT-запрос.
     *
     * Внутри себя вызывает this._insert, основное отличие в том, что в данном методе пишутся метрики.
     * @param insertData Дополнительная информация для запроса. Содержит сам запроса, а также название таблицы и прочие данные.
     */
    insert(insertData: IQuery): Promise<boolean>;
    /**
     * Выполняет UPDATE-запрос.
     *
     * Внутри себя вызывает this._update, основное отличие в том, что в данном методе пишутся метрики.
     * @param updateData Дополнительная информация для запроса. Содержит сам запроса, а также название таблицы и прочие данные.
     */
    update(updateData: IQuery): Promise<boolean>;
    /**
     * Выполняет DELETE-запрос.
     *
     * Внутри себя вызывает this._remove, основное отличие в том, что в данном методе пишутся метрики.
     * @param removeData Дополнительная информация для запроса. Содержит сам запроса, а также название таблицы и прочие данные.
     */
    remove(removeData: IQuery): Promise<boolean>;
    /**
     * Выполняет произвольный запрос через callback.
     *
     * Внутри себя вызывает this._query, основное отличие в том, что в данном методе пишутся метрики.
     * @param callback функция обработчик
     */
    query(callback: TQueryCb): Promise<unknown> | unknown;
    /**
     * Сохраняет запись: вставляет новую или обновляет существующую.
     * Логика:
     * - Если `isNew === true` → вызывается `insert`
     * - Иначе → сначала делается `selectOne` по `saveData.query`,
     *   и если запись найдена — вызывается `update`, иначе — `insert`
     *  *
     * @param saveData Данные для запроса. Включает как запроса, так и сами данные
     * @param isNew Флаг, говорящий о том, что точно происходит добавление новой записи
     */
    save(saveData: IQuery, isNew: boolean): Promise<boolean>;
    /**
     * Выполняет SELECT с ограничением до одной записи.
     * @param selectData Дополнительные данные для запроса
     * @param where Сам запроса
     */
    selectOne(selectData: IQuery, where: IQueryData | null): Promise<IModelRes | null>;
    /**
     * Экранирует строку для безопасного использования в запросах.
     *
     * ⚠️ По умолчанию просто приводит значение к строке.
     * Если ваша БД требует экранирования (например, SQL), обязательно переопределите этот метод.
     * @param str Экранируемый запрос
     */
    escapeString(str: string | number): string;
    /**
     * Проверяет, установлено ли соединение с БД.
     */
    abstract isConnected(): Promise<boolean> | boolean;
    /**
     * Вызывается при завершении работы приложения или замене адаптера.
     * Используйте для закрытия соединений, сохранения данных и т.п.
     */
    destroy(): void | Promise<void>;
    /**
     * Вызывается при удалении модели или завершении сессии.
     * Может использоваться для освобождения ресурсов, связанных с таблицей.
     * @param _tableName Название таблицы, подключение к которой закрывается
     */
    close(_tableName: string): void | Promise<void>;
}
