/**
 * ============================================================
 *  config.ts —— 全局配置加载（从 .env 读取）
 * ------------------------------------------------------------
 *  只从环境变量读取，集中管理所有配置。
 *
 *  必需的环境变量：
 *    MINIMAL_AGENT_BASE_URL   - API 地址，如 https://api.minimax.chat/v1
 *    MINIMAL_AGENT_API_KEY    - API key
 *    MINIMAL_AGENT_MODEL      - 模型名，如 MiniMax-M2.7
 *
 *  可选的环境变量：
 *    MINIMAL_AGENT_PROVIDER   - 友好名称，默认 "env"
 *    MINIMAL_AGENT_CONTEXT_WINDOW - 上下文窗口，默认 128000
 * ============================================================
 */
import { readSavedConfig } from './config/configFile.js';
const DEFAULT_CONTEXT_WINDOW = 128_000;
/**
 * 解析压缩阈值比例（0~1 小数）。
 * 非法值（NaN、0、负数、>1）返回 undefined，由调用方决定是否用默认值 0.85。
 */
function parseCompactRatio(raw) {
    if (!raw)
        return undefined;
    const n = parseFloat(raw);
    if (Number.isNaN(n) || n <= 0 || n > 1)
        return undefined;
    return n;
}
/**
 * 加载 Provider 配置（从环境变量）。
 * 缺少必需变量时抛出明确错误。
 */
export async function loadProvider() {
    const baseURL = process.env.MINIMAL_AGENT_BASE_URL;
    const apiKey = process.env.MINIMAL_AGENT_API_KEY;
    const model = process.env.MINIMAL_AGENT_MODEL;
    if (!baseURL || !apiKey || !model) {
        const missing = [];
        if (!baseURL)
            missing.push('MINIMAL_AGENT_BASE_URL');
        if (!apiKey)
            missing.push('MINIMAL_AGENT_API_KEY');
        if (!model)
            missing.push('MINIMAL_AGENT_MODEL');
        throw new Error(`缺少必需的环境变量：${missing.join(', ')}\n\n` +
            `请在 .env 中配置：\n` +
            `  MINIMAL_AGENT_BASE_URL=https://api.example.com/v1\n` +
            `  MINIMAL_AGENT_API_KEY=your-api-key\n` +
            `  MINIMAL_AGENT_MODEL=your-model\n\n` +
            `参考 .env.example`);
    }
    const contextWindowRaw = process.env.MINIMAL_AGENT_CONTEXT_WINDOW;
    let contextWindow = DEFAULT_CONTEXT_WINDOW;
    if (contextWindowRaw) {
        const n = parseInt(contextWindowRaw, 10);
        if (!Number.isNaN(n) && n > 0) {
            contextWindow = n;
        }
    }
    const compactRatio = parseCompactRatio(process.env.MINIMAL_AGENT_COMPACT_RATIO);
    return {
        name: process.env.MINIMAL_AGENT_PROVIDER ?? 'env',
        baseURL,
        apiKey,
        model,
        contextWindow,
        ...(compactRatio !== undefined ? { compactRatio } : {}),
    };
}
/**
 * 层级加载：env 优先（模式 A），不全则回退到 ~/.minimal-agent/config.json（模式 B）。
 * 都没有时返回 null —— 调用方决定是触发向导还是直接退出。
 *
 * 与 loadProvider() 的区别：
 *   - loadProvider() 只读 env，全缺则抛错（给 -p 模式用，明确告知"先做配置"）
 *   - 本函数静默 fallback 到 JSON，全缺则返回 null（给 TUI 模式用，可触发向导）
 *
 * env 字段优先级是逐项的：只要 env 里有 BASE_URL 就用 env 的 BASE_URL，
 * 其它字段从 JSON 补；这样用户可以临时用 env 覆盖单个字段做调试。
 */
export async function loadProviderLayered() {
    const envBaseURL = process.env.MINIMAL_AGENT_BASE_URL;
    const envApiKey = process.env.MINIMAL_AGENT_API_KEY;
    const envModel = process.env.MINIMAL_AGENT_MODEL;
    const envName = process.env.MINIMAL_AGENT_PROVIDER;
    const envContextRaw = process.env.MINIMAL_AGENT_CONTEXT_WINDOW;
    let saved = null;
    if (!envBaseURL || !envApiKey || !envModel) {
        saved = await readSavedConfig();
    }
    const baseURL = envBaseURL ?? saved?.baseURL;
    const apiKey = envApiKey ?? saved?.apiKey;
    const model = envModel ?? saved?.model;
    if (!baseURL || !apiKey || !model)
        return null;
    let contextWindow = DEFAULT_CONTEXT_WINDOW;
    if (envContextRaw) {
        const n = parseInt(envContextRaw, 10);
        if (!Number.isNaN(n) && n > 0)
            contextWindow = n;
    }
    else if (saved?.contextWindow) {
        contextWindow = saved.contextWindow;
    }
    // compactRatio：env 优先（测试时临时 MINIMAL_AGENT_COMPACT_RATIO=0.2 即可），否则取 saved。
    const envRatio = parseCompactRatio(process.env.MINIMAL_AGENT_COMPACT_RATIO);
    const compactRatio = envRatio ??
        (typeof saved?.compactRatio === 'number' ? saved.compactRatio : undefined);
    return {
        name: envName ?? saved?.provider ?? 'env',
        baseURL,
        apiKey,
        model,
        contextWindow,
        ...(compactRatio !== undefined ? { compactRatio } : {}),
    };
}
/**
 * 把 saved config 里的工具 key 注入 process.env（env 已设则不覆盖）。
 *
 * 解决 npm 全局安装场景：`node dist/main.js` 不会自动加载 .env，
 * Tavily 之类的工具 key 只能从 ~/.minimal-agent/config.json 取出再写回 env，
 * websearch.ts 才能在 call() 里读到。
 *
 * 应在 main() 最早期调用（initWorkingDir 之后即可），保证 ALL_TOOLS
 * 任何 call() 触发前 env 已就位。
 */
export async function applyToolKeysToEnv() {
    const saved = await readSavedConfig();
    if (!saved)
        return;
    if (!process.env.TAVILY_API_KEY && saved.tavilyApiKey) {
        process.env.TAVILY_API_KEY = saved.tavilyApiKey;
    }
}
