import path from 'node:path';
import { promises as fs } from 'node:fs';
import { getAgentInitRoot, loadInstanceState, saveInstanceState } from './instance-state.js';
import { loadCcSwitchSdk, runCcSwitchAdapter, toSdkAppsFromEnabledTools } from './cc-switch-sdk.js';
import { ensureDir, installSkillPackageToSdk } from '../utils/file-utils.js';
import { buildMcpConfigContent, normalizeSdkMcpServerSpec, toLegacyMcpStateItem, toLegacySkillStateItem } from '../utils/mcp-utils.js';
import { ensureEnabledTools, parseBoolean } from '../utils/validation.js';
import { normalizeMcpPayload } from '../utils/mcp-utils.js';
import { detectToolStatuses, ensureToolsInstalled } from './tool-installer.js';
export async function syncLegacyStateFromSdk(agentId, sdk) {
    const state = await loadInstanceState(agentId);
    const mcpServers = sdk.getAllMcpServers().map((item) => toLegacyMcpStateItem(item));
    const skills = sdk.getAllSkills().map((item) => toLegacySkillStateItem(item));
    state.mcpServers = mcpServers;
    state.skills = skills;
    const initRoot = getAgentInitRoot(agentId);
    const mcpDir = await ensureDir(path.join(initRoot, 'mcp'));
    const mcpConfigPath = path.join(mcpDir, 'mcp-servers.json');
    await fs.writeFile(mcpConfigPath, buildMcpConfigContent(mcpServers), 'utf-8');
    const saved = await saveInstanceState(agentId, state);
    return {
        state: saved,
        configPath: mcpConfigPath,
        skills,
        mcpServers,
    };
}
export async function initInstance(agentId, workspacePath, options) {
    const normalizedWorkspace = path.resolve(workspacePath);
    const initRoot = getAgentInitRoot(agentId);
    const logs = [];
    function pushLog(step, status, message, details) {
        logs.push({
            step,
            status,
            message,
            timestamp: new Date().toISOString(),
            details,
        });
    }
    pushLog('prepare', 'running', '开始初始化实例', {
        agentId: String(agentId),
        workspacePath: normalizedWorkspace,
    });
    await ensureDir(initRoot);
    pushLog('prepare', 'success', '初始化目录已就绪', { initRoot });
    const tools = ensureEnabledTools(options.ccSwitchEnabledTools);
    pushLog('detect-tools', 'running', '开始检测工具安装状态', { tools });
    const detectedToolStatus = await detectToolStatuses(tools);
    pushLog('detect-tools', 'success', '工具安装状态检测完成', {
        installedTools: Object.values(detectedToolStatus).filter((item) => item.installed).map((item) => item.tool),
        missingTools: Object.values(detectedToolStatus).filter((item) => !item.installed).map((item) => item.tool),
    });
    const initResult = {
        ok: true,
        agentId: String(agentId),
        workspacePath: normalizedWorkspace,
        initRoot,
        enabledTools: tools,
        toolStatus: detectedToolStatus,
        logs,
        skill: {
            enabled: parseBoolean(options.skillEnabled, true),
            packagePresent: false,
        },
        mcp: {
            enabled: parseBoolean(options.mcpEnabled, true),
            configPath: null,
        },
    };
    const state = await loadInstanceState(agentId);
    pushLog('install-tools', 'running', '开始自动安装缺失工具', { tools });
    const ensuredToolStatus = await ensureToolsInstalled(tools);
    initResult.toolStatus = ensuredToolStatus;
    const failedTools = Object.values(ensuredToolStatus).filter((item) => !item.installed);
    if (failedTools.length > 0) {
        pushLog('install-tools', 'error', '部分工具自动安装失败', {
            failedTools: failedTools.map((item) => ({ tool: item.tool, error: item.error })),
        });
    }
    else {
        pushLog('install-tools', 'success', '工具安装步骤完成', {
            installedTools: Object.values(ensuredToolStatus).map((item) => ({ tool: item.tool, version: item.version })),
        });
    }
    pushLog('load-sdk', 'running', '开始加载 CC Switch SDK');
    const sdk = await loadCcSwitchSdk(agentId);
    const sdkApps = toSdkAppsFromEnabledTools(tools);
    pushLog('load-sdk', 'success', 'CC Switch SDK 加载完成', { sdkApps });
    if (initResult.skill.enabled) {
        pushLog('install-skills', 'running', '开始安装技能包', {
            count: Array.isArray(options.skillPackages) ? options.skillPackages.length : (options.skillPackage ? 1 : 0),
        });
        const skillDir = await ensureDir(path.join(initRoot, 'skills'));
        const skillCandidates = Array.isArray(options.skillPackages) && options.skillPackages.length > 0
            ? options.skillPackages
            : (options.skillPackage ? [options.skillPackage] : []);
        const installedSkills = [];
        for (const candidate of skillCandidates) {
            const installed = await installSkillPackageToSdk(sdk, candidate, skillDir, sdkApps);
            if (!installed) {
                continue;
            }
            installedSkills.push(toLegacySkillStateItem(installed));
        }
        if (installedSkills.length > 0) {
            initResult.skill.packagePresent = true;
            initResult.skill.installedCount = installedSkills.length;
            initResult.skill.installed = installedSkills;
            pushLog('install-skills', 'success', '技能包安装完成', {
                installedCount: installedSkills.length,
                skills: installedSkills.map((item) => item.name),
            });
        }
        else {
            pushLog('install-skills', 'skipped', '没有可安装的技能包');
        }
    }
    else {
        pushLog('install-skills', 'skipped', '已跳过技能包安装（skillEnabled=false）');
    }
    if (initResult.mcp.enabled) {
        pushLog('install-mcp', 'running', '开始写入 MCP 配置', {
            count: Array.isArray(options.mcpServers) ? options.mcpServers.length : 0,
        });
        const normalizedMcpServers = (Array.isArray(options.mcpServers) ? options.mcpServers : [])
            .map((item) => normalizeMcpPayload(item))
            .filter((item) => item != null);
        const appliedMcp = [];
        for (const item of normalizedMcpServers) {
            const allMcps = sdk.getAllMcpServers();
            const existing = allMcps.find((server) => String(server?.name || '').trim() === item.name);
            const mcpInput = {
                name: item.name,
                server: normalizeSdkMcpServerSpec(item),
                apps: sdkApps,
            };
            const existingId = String(existing?.id || '').trim();
            const upserted = existingId
                ? await sdk.updateMcpServer(existingId, mcpInput)
                : await sdk.createMcpServer(mcpInput);
            appliedMcp.push(toLegacyMcpStateItem(upserted));
        }
        initResult.mcp.installedCount = appliedMcp.length;
        pushLog('install-mcp', 'success', 'MCP 配置写入完成', {
            installedCount: appliedMcp.length,
            mcpServers: appliedMcp.map((item) => item.name),
        });
    }
    else {
        pushLog('install-mcp', 'skipped', '已跳过 MCP 配置（mcpEnabled=false）');
    }
    pushLog('persist-state', 'running', '开始保存实例状态');
    state.initialized = true;
    state.enabledTools = tools;
    state.toolStatus = ensuredToolStatus;
    state.skillEnabled = initResult.skill.enabled;
    state.mcpEnabled = initResult.mcp.enabled;
    await saveInstanceState(agentId, state);
    pushLog('persist-state', 'success', '实例状态保存完成');
    pushLog('sync-state', 'running', '开始同步 CC Switch 状态快照');
    const synced = await syncLegacyStateFromSdk(agentId, sdk);
    const savedState = synced.state;
    initResult.mcp.configPath = synced.configPath;
    pushLog('sync-state', 'success', 'CC Switch 状态同步完成', {
        skillCount: savedState.skills.length,
        mcpCount: savedState.mcpServers.length,
        configPath: synced.configPath,
    });
    pushLog('adapter', 'running', '开始执行适配器回写');
    const adapterResult = await runCcSwitchAdapter('init-instance', agentId, {
        enabledTools: savedState.enabledTools,
        skillEnabled: savedState.skillEnabled,
        mcpEnabled: savedState.mcpEnabled,
        skillCount: savedState.skills.length,
        mcpCount: savedState.mcpServers.length,
    }, sdk);
    pushLog('adapter', 'success', '适配器回写完成', {
        snapshot: adapterResult.snapshot,
    });
    pushLog('complete', failedTools.length > 0 ? 'error' : 'success', failedTools.length > 0 ? '实例初始化完成，但存在工具安装失败项' : '实例初始化完成');
    return {
        ...initResult,
        adapterResult,
        installed: {
            skills: savedState.skills,
            mcpServers: savedState.mcpServers,
        },
    };
}
