/**
 * Agent 配置加载
 *
 * 从 agents.json 的 defaults.model 读取全局模型配置
 * 从 providers.json 读取 API Key 和 baseUrl
 */

import type { AgentConfig, ProviderType } from '../types/index.js';
import { providerRegistry, resolveApiKey } from '../provider/index.js';
import { agentRegistry } from '../agent/registry.js';
import type { AgentModelConfig } from '../agent/types.js';

/**
 * 配置错误异常
 *
 * 当配置缺失或无效时抛出，用于替代 process.exit()
 * 允许调用方优雅地处理错误并向用户显示友好提示
 */
export class ConfigurationError extends Error {
  constructor(
    message: string,
    public readonly provider: string,
    public readonly missingKey: 'apiKey' | 'provider'
  ) {
    super(message);
    this.name = 'ConfigurationError';
  }
}

// 默认模型配置
const DEFAULT_MODELS: Record<ProviderType, string> = {
  anthropic: 'claude-sonnet-4-20250514',
  deepseek: 'deepseek-chat',
  openai: 'gpt-4o',
};

// 默认系统提示词
const DEFAULT_SYSTEM_PROMPT = `你是一个运行在终端中的 AI 编程助手。你可以帮助用户：
- 读取和写入文件
- 执行 bash 命令
- 搜索代码和文件
- 回答编程问题

使用工具时请注意：
1. 在修改文件前，先读取文件内容
2. 执行可能有风险的命令前，先向用户确认
3. 给出清晰、简洁的回答

重要的工具使用规则：
- 创建或修改文件时，必须使用 write_file 或 edit_file 工具，不要使用 bash 命令（如 cat、echo 等）
- write_file 和 edit_file 工具集成了代码诊断功能，可以在写入后自动检查代码错误
- bash 工具仅用于运行命令、安装依赖、执行脚本等操作，不要用于文件内容的创建和修改

当前工作目录: ${process.cwd()}
操作系统: ${process.platform}`;

/**
 * 查找第一个已配置 API Key 的 Provider
 * 作为未配置 defaults.model 时的 fallback
 */
function findFirstConfiguredProvider(): ProviderType | null {
  const providers: ProviderType[] = ['anthropic', 'openai', 'deepseek'];

  for (const providerId of providers) {
    const config = providerRegistry.getConfig(providerId);
    const apiKey = resolveApiKey(config);
    if (apiKey) {
      return providerId;
    }
  }

  return null;
}

/**
 * 加载 Agent 配置
 *
 * 配置来源优先级：
 * 1. agents.json 的 defaults.model（用户配置的全局默认模型）
 * 2. 第一个已配置 API Key 的 Provider（fallback）
 * 3. 抛出 ConfigurationError（无可用配置）
 */
export function loadConfig(): AgentConfig {
  // 1. 从 AgentRegistry 获取 defaults.model 配置
  const globalConfig = agentRegistry.getGlobalConfig();
  const modelConfig = globalConfig?.model;

  // 2. 确定 provider（优先使用配置，否则使用第一个有 API Key 的 provider）
  let provider: ProviderType;
  let model: string;

  if (modelConfig?.provider) {
    // 用户配置了 defaults.model.provider
    provider = modelConfig.provider;
    model = modelConfig.model || DEFAULT_MODELS[provider];
  } else {
    // 未配置，尝试找第一个有 API Key 的 provider
    const fallbackProvider = findFirstConfiguredProvider();
    if (!fallbackProvider) {
      throw new ConfigurationError(
        '请先在 Providers 面板配置一个模型提供商的 API Key',
        'unknown',
        'apiKey'
      );
    }
    provider = fallbackProvider;
    model = DEFAULT_MODELS[provider];
  }

  // 3. 从 ProviderRegistry 获取 API Key 和 baseUrl
  const providerConfig = providerRegistry.getConfig(provider);
  const apiKey = resolveApiKey(providerConfig);

  if (!apiKey) {
    throw new ConfigurationError(
      `请在 Providers 面板配置 ${provider} 的 API Key`,
      provider,
      'apiKey'
    );
  }

  // 4. 获取模型的 contextWindow
  const modelInfo = providerRegistry.getModelInfo(provider, model);
  const contextWindow = modelInfo?.contextWindow;

  // 5. 获取 maxTokens（从 modelConfig 或默认值）
  const maxTokens = modelConfig?.maxTokens || 4096;

  return {
    provider,
    apiKey,
    model,
    maxTokens,
    systemPrompt: DEFAULT_SYSTEM_PROMPT,
    baseUrl: providerConfig?.baseUrl,
    contextWindow,
  };
}

// Vision 配置接口
export interface VisionConfig {
  provider: ProviderType;
  apiKey: string;
  model: string;
  baseUrl?: string;
}

/**
 * 加载 Vision 配置
 *
 * 从 agents.json 的 defaults.vision 读取配置
 * Vision 用于图片理解，当主模型不支持 vision 时使用
 */
export function loadVisionConfig(): VisionConfig | null {
  // 从 AgentRegistry 获取 defaults.vision 配置
  const globalConfig = agentRegistry.getGlobalConfig();
  const visionConfig = globalConfig?.vision;

  if (!visionConfig?.provider) {
    // 未配置 vision，返回 null
    return null;
  }

  // 从 ProviderRegistry 获取 API Key
  const providerConfig = providerRegistry.getConfig(visionConfig.provider);
  const apiKey = resolveApiKey(providerConfig);

  if (!apiKey) {
    // 没有 API Key，返回 null
    return null;
  }

  // 确定模型（使用配置的或默认值）
  const model = visionConfig.model || DEFAULT_MODELS[visionConfig.provider];

  return {
    provider: visionConfig.provider,
    apiKey,
    model,
    baseUrl: providerConfig?.baseUrl,
  };
}

/**
 * 从 AgentModelConfig 构建完整配置
 * 用于 Task 工具动态构建 Agent 配置
 */
export function buildConfigFromModelConfig(modelConfig: AgentModelConfig): AgentConfig | null {
  if (!modelConfig.provider) {
    return null;
  }

  const providerConfig = providerRegistry.getConfig(modelConfig.provider);
  const apiKey = resolveApiKey(providerConfig);

  if (!apiKey) {
    return null;
  }

  const model = modelConfig.model || DEFAULT_MODELS[modelConfig.provider];
  const modelInfo = providerRegistry.getModelInfo(modelConfig.provider, model);

  return {
    provider: modelConfig.provider,
    apiKey,
    model,
    maxTokens: modelConfig.maxTokens || 4096,
    systemPrompt: DEFAULT_SYSTEM_PROMPT,
    baseUrl: providerConfig?.baseUrl,
    contextWindow: modelInfo?.contextWindow,
  };
}
