import { existsSync } from 'node:fs';
import { mkdir, readFile, readdir, unlink, writeFile } from 'node:fs/promises';
import { homedir } from 'node:os';
import { join } from 'node:path';
import { setTomlValue } from './toml.js';
/**
 * 内置模式。复制粘贴就能让用户写自己的。
 */
export const BUILTIN_MODES = {
    code: {
        id: 'code',
        name: '写代码',
        description: '深度思考开启 / 高强度推理 — 适合写代码、调 bug、重构',
        claude: { thinkingEnabled: true, thinkingBudget: 16384 },
        codex: { effort: 'high' },
    },
    chat: {
        id: 'chat',
        name: '日常对话',
        description: '思考关闭 / 中等推理 — 答疑、解释概念、随便聊',
        claude: { thinkingEnabled: false },
        codex: { effort: 'medium' },
    },
    fast: {
        id: 'fast',
        name: '快速响应',
        description: '思考关闭 / 低推理 — 简单查询、小修改、想要立刻拿到结果',
        claude: { thinkingEnabled: false },
        codex: { effort: 'low' },
    },
    deep: {
        id: 'deep',
        name: '深度思考',
        description: '深度思考开启 / 大 budget — 架构设计、复杂 debug、需要多角度推理',
        claude: { thinkingEnabled: true, thinkingBudget: 32768 },
        codex: { effort: 'high' },
    },
};
export const MODES_DIR = join(homedir(), '.ccjk', 'modes');
export const MODE_STATE_FILE = join(homedir(), '.ccjk', 'mode-state.json');
const NAME_RE = /^[a-zA-Z0-9][a-zA-Z0-9_-]{0,31}$/;
export function validateModeName(name) {
    if (!NAME_RE.test(name)) {
        throw new Error(`mode 名称非法: "${name}"（仅允许字母数字 _ - ，1-32 字符）`);
    }
}
/**
 * 读取所有可用 modes：内置 + 用户自定义（用户同名优先）。
 * 这样用户可以"覆盖"内置的 code 模式而不破坏其它用户的 ccjk。
 */
export async function listModes(dir = MODES_DIR) {
    const out = new Map();
    for (const m of Object.values(BUILTIN_MODES))
        out.set(m.id, m);
    if (existsSync(dir)) {
        const files = await readdir(dir);
        for (const f of files) {
            if (!f.endsWith('.json'))
                continue;
            try {
                const raw = await readFile(join(dir, f), 'utf-8');
                const def = JSON.parse(raw);
                validateModeName(def.id);
                out.set(def.id, def);
            }
            catch {
                // 跳过损坏文件
            }
        }
    }
    return [...out.values()].sort((a, b) => a.id.localeCompare(b.id));
}
export async function readMode(id, dir = MODES_DIR) {
    validateModeName(id);
    if (existsSync(join(dir, `${id}.json`))) {
        const raw = await readFile(join(dir, `${id}.json`), 'utf-8');
        return JSON.parse(raw);
    }
    return BUILTIN_MODES[id] ?? null;
}
export async function writeMode(mode, dir = MODES_DIR) {
    validateModeName(mode.id);
    await mkdir(dir, { recursive: true });
    await writeFile(join(dir, `${mode.id}.json`), `${JSON.stringify(mode, null, 2)}\n`, 'utf-8');
}
export async function removeMode(id, dir = MODES_DIR) {
    validateModeName(id);
    const p = join(dir, `${id}.json`);
    if (!existsSync(p))
        return false;
    await unlink(p);
    return true;
}
export async function readModeState(file = MODE_STATE_FILE) {
    if (!existsSync(file))
        return {};
    try {
        return JSON.parse(await readFile(file, 'utf-8'));
    }
    catch {
        return {};
    }
}
export async function writeModeState(state, file = MODE_STATE_FILE) {
    await mkdir(join(file, '..'), { recursive: true });
    await writeFile(file, `${JSON.stringify(state, null, 2)}\n`, 'utf-8');
}
/**
 * 应用 mode 到 Claude/Clavue settings.json（in-place 修改）。
 * 写到 settings.thinking 而不是 env，因为 thinking 是 Claude Code 原生支持的字段。
 */
export function applyModeToClaudeSettings(settings, mode) {
    const obj = settings;
    const thinking = {
        enabled: mode.claude.thinkingEnabled,
    };
    if (mode.claude.thinkingBudget !== undefined) {
        thinking.budgetTokens = mode.claude.thinkingBudget;
    }
    obj.thinking = thinking;
}
/**
 * 应用 mode 到 Codex config.toml。
 */
export function applyModeToCodexConfig(doc, mode) {
    setTomlValue(doc, 'model_reasoning_effort', mode.codex.effort);
}
//# sourceMappingURL=modes.js.map