/**
 * MonSQLize 内置插件类型定义
 *
 * 定义 MonSQLizeConnection（连接对象）和 MonSQLizeDatabaseConfig（数据库配置）。
 * 通过 declare module 'vextjs' 扩展 VextApp 和 VextConfig 接口，
 * 使用户在 app.db / app.monsqlize / app.config.database 上获得完整类型提示。
 *
 * @module lib/plugins/monsqlize/types
 * @see 13-monsqlize-plugin.md §2.1（类型扩展）
 */
declare module "../../../types/app.js" {
    interface VextApp {
        /** MonSQLize 连接对象（已连接，提供 collection / db / model 快捷方法） */
        db?: MonSQLizeConnection;
        /**
         * 原始 MonSQLize 实例
         * 用于高级场景（事务、底层操作、事件监听等）
         */
        monsqlize?: import("monsqlize").MonSQLize;
    }
    interface VextConfig {
        /** MonSQLize 数据库配置 */
        database?: MonSQLizeDatabaseConfig;
    }
}
/**
 * MonSQLize 连接对象
 *
 * 由插件在 setup 阶段创建并挂载到 app.db。
 * 封装 MonSQLize 实例的常用方法，提供简洁的 API。
 */
/**
 * 连接池访问器
 *
 * 通过 app.db.pool(name) 获取，提供与 app.db 对称的访问接口。
 * 所有方法均将操作路由到指定连接池。
 */
export interface PoolAccessor {
    /** 获取指定池上的 Model 实例 */
    model: (key: string) => ReturnType<import("monsqlize").MonSQLize["model"]>;
    /** 获取指定池上的原生 Collection */
    collection: (name: string) => ReturnType<import("monsqlize").MonSQLize["collection"]>;
    /** 切换数据库，返回限定池+库的访问器 */
    use: (dbName: string) => {
        model: (key: string) => ReturnType<import("monsqlize").MonSQLize["model"]>;
        collection: (name: string) => ReturnType<import("monsqlize").MonSQLize["collection"]>;
    };
}
export interface MonSQLizeConnection {
    /** 获取集合操作对象 */
    collection: (name: string) => ReturnType<import("monsqlize").MonSQLize["collection"]>;
    /** 获取 Model 操作对象（需先定义 Model） */
    model: (name: string) => ReturnType<import("monsqlize").MonSQLize["model"]>;
    /**
     * 切换数据库作用域（R1 补全 collection，R2 改为单参数）
     *
     * `use('billing').model('Invoice')`     → key=BillingInvoice，默认池 billing库
     * `use('billing').collection('orders')` → 默认池 billing库 orders集合
     */
    use: (dbName: string) => {
        model: (key: string) => ReturnType<import("monsqlize").MonSQLize["model"]>;
        collection: (name: string) => ReturnType<import("monsqlize").MonSQLize["collection"]>;
    };
    /** 切换连接池（R3 新增） */
    pool: (name: string) => PoolAccessor;
    /** 原始 MongoDB Client（事务等高级场景） */
    readonly client: any;
}
/**
 * Vext Model 定义对象类型
 *
 * 在 src/models/ 下的 Model 文件中 export default 此对象。
 */
export interface VextModelDefinition {
    /**
     * 自定义注册别名（R5 新增）
     *
     * 为 Model 额外添加一个短名（如将 billing/invoice.ts 额外注册为 'Invoice'），
     * 路径推断名 'BillingInvoice' 同时保留，两者均可访问同一 Model（双重注册）。
     * 只影响 `app.db.model(key)` 的查找名，不影响 MongoDB 集合名。
     *
     * 建议仅在需要跨模块短名访问时使用，注意避免与其他 Model 的推断名冲突。
     */
    key?: string;
    /** @deprecated 用 key 控制注册名；用 collection 控制集合名 */
    name?: string;
    /** MongoDB 集合名（不填则使用文件名/name/key） */
    collection?: string;
    /**
     * 数据源绑定（N4 目录路由自动注入，也可手动指定）
     *
     * 子目录模型文件会根据目录层级自动推断并注入此字段：
     *   - `models/a/order.ts`     → `{ database: 'a' }`
     *   - `models/c/a/order.ts`   → `{ pool: 'c', database: 'a' }`
     *
     * 手动显式配置会覆盖自动推断值。
     */
    connection?: {
        /** 连接池名称（对应 config.database.pools[].name） */
        pool?: string;
        /** 数据库名称（对应 MonSQLize 实例的 databaseName） */
        database?: string;
    };
    schema?: (dsl: unknown) => unknown;
    relations?: Record<string, unknown>;
    hooks?: (model: unknown) => Record<string, unknown>;
    methods?: (model: unknown) => {
        instance?: Record<string, unknown>;
        static?: Record<string, unknown>;
    };
    indexes?: Array<Record<string, unknown>>;
    enums?: Record<string, unknown>;
}
/**
 * MonSQLize 数据库配置
 *
 * 用户在 src/config/default.ts 中通过 database 字段配置。
 * 插件在 setup 阶段读取此配置创建 MonSQLize 实例。
 */
export interface MonSQLizeDatabaseConfig {
    /**
     * MongoDB 连接类型
     * @default 'url'
     */
    type?: "url" | "replica" | "srv";
    /**
     * 数据库名称（N2 新增）
     *
     * 默认从 uri/url 中自动解析（如 `mongodb://host/mydb` → `'mydb'`）。
     * 显式配置时优先使用，用于 URI 不包含数据库名的场景。
     */
    databaseName?: string;
    /**
     * 连接配置
     * - type='url' 时：{ url: string }
     * - type='replica' 时：{ hosts: string[], replicaSet: string }
     * - type='srv' 时：{ host: string }
     */
    config: {
        /**
         * MongoDB 连接 URI（主要字段，N1 新增）
         * @example 'mongodb://localhost:27017/mydb'
         */
        uri?: string;
        /**
         * MongoDB 连接 URL（已废弃，请使用 uri）
         * @deprecated 使用 uri 替代
         */
        url?: string;
        host?: string;
        hosts?: string[];
        port?: number;
        database?: string;
        replicaSet?: string;
        username?: string;
        password?: string;
        authSource?: string;
        options?: Record<string, unknown>;
        /**
         * SSH 隧道配置（v1.3.0+）
         * 配置后将通过 SSH 跳板机连接数据库，uri 中的 host:port 作为隧道目标地址
         */
        ssh?: {
            /** SSH 服务器地址 */
            host: string;
            /** SSH 端口（默认 22） */
            port?: number;
            /** SSH 用户名 */
            username: string;
            /** SSH 密码（与 privateKey 二选一） */
            password?: string;
            /** SSH 私钥内容（与 password 二选一） */
            privateKey?: string | Buffer;
            /** 私钥密码 */
            passphrase?: string;
            /** 连接超时（毫秒，默认 20000） */
            readyTimeout?: number;
            /** 心跳间隔（毫秒，默认 30000） */
            keepaliveInterval?: number;
        };
    };
    /**
     * 缓存配置
     * L1 = 内存 LRU，L2 = Redis（可选）
     */
    cache?: {
        /** L1 内存缓存（默认开启） */
        memory?: {
            enabled?: boolean;
            /** 最大缓存条数（默认 1000） */
            maxSize?: number;
            /** 默认 TTL 秒数（默认 300） */
            ttl?: number;
        };
        /** L2 Redis 缓存（可选） */
        redis?: {
            enabled?: boolean;
            url?: string;
            /** 缓存 key 前缀 */
            prefix?: string;
            /** 默认 TTL 秒数 */
            ttl?: number;
        };
    };
    /**
     * 多连接池配置
     * 微服务场景中用于读写分离或多库访问
     *
     * 注：vext 接收两种 uri 写法（uri / url），平铺时统一映射为 monSQLize 要求的扁平 { name, uri }。
     */
    pools?: Array<{
        name: string;
        config: {
            uri?: string;
            url?: string;
            useMemoryServer?: boolean;
            memoryServerOptions?: Record<string, unknown>;
        } & Record<string, unknown>;
        options?: Record<string, unknown>;
        role?: "primary" | "secondary" | "analytics" | "custom";
        weight?: number;
        tags?: string[];
        healthCheck?: {
            enabled?: boolean;
            interval?: number;
            timeout?: number;
            retries?: number;
        };
    }>;
    /**
     * 连接池选择策略
     * @default 'auto'
     */
    poolStrategy?: "auto" | "round-robin" | "random" | "least-connections";
    /**
     * 全局查询超时（毫秒）
     * @default 2000
     */
    maxTimeMS?: number;
    /**
     * find 默认返回条数上限
     * @default 10
     */
    findLimit?: number;
    /**
     * 分页最大 limit
     * @default 500
     */
    findPageMaxLimit?: number;
    /**
     * 慢查询阈值（毫秒，-1 禁用）
     * @default 500
     */
    slowQueryMs?: number;
    /**
     * 慢查询持久化存储配置
     */
    slowQueryLog?: {
        enabled?: boolean;
        /** 存储集合名 */
        collection?: string;
    };
    /**
     * 自动 ObjectId 转换
     */
    autoConvertObjectId?: boolean | {
        fields?: string[];
    };
    /**
     * Model 自动加载配置
     */
    models?: {
        /**
         * Model 定义文件目录（相对于 src/）
         * @default 'models'
         */
        dir?: string;
        /**
         * 外部 shared Model 包名
         * 微服务场景中使用，从 npm 包加载 Model 定义
         * @example '@project/models'
         */
        sharedPackage?: string;
        /**
         * 是否自动注册（扫描目录后自动 Model.define）
         * @default true
         */
        autoRegister?: boolean;
    };
    /**
     * 命名空间（缓存隔离用）
     * @default { scope: 'database' }
     */
    namespace?: {
        scope?: string;
    };
    /**
     * 深分页游标加密密钥
     */
    cursorSecret?: string;
    /**
     * 内存数据库（测试用）
     * 启用后使用 mongodb-memory-server 创建临时实例
     * @default false
     */
    useMemoryServer?: boolean;
    /**
     * 日志器配置
     * - 'app': 使用 app.logger（默认）
     * - false: 禁用日志
     */
    logger?: "app" | false;
}
