import * as fs from 'fs';
import * as path from 'path';
import * as os from 'os';
import type { AgentConfig, ProviderType } from '../types/index.js';
import { providerRegistry, resolveApiKey } from '../provider/index.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 CONFIG_DIR = path.join(os.homedir(), '.ai-terminal-assistant');
const CONFIG_FILE = path.join(CONFIG_DIR, 'config.json');

interface StoredConfig {
  provider?: ProviderType;
  model?: string;
  maxTokens?: number;
  tavilyApiKey?: string;
  /** 自定义 API 基础 URL（用于 OpenAI 兼容服务，如阿里云百炼） */
  baseUrl?: string;
  // Vision 配置
  visionProvider?: ProviderType;
  visionModel?: string;
  /** Vision 专用的 Base URL（用于 OpenAI 兼容的 Vision 服务） */
  visionBaseUrl?: string;
}

// Vision 配置接口
export interface VisionConfig {
  provider: ProviderType;
  apiKey: string;
  model: string;
  /** 自定义 Base URL（用于 OpenAI 兼容的 Vision 服务） */
  baseUrl?: string;
}

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

// 默认 Vision 模型（需要支持图片理解）
const DEFAULT_VISION_MODELS: Record<ProviderType, string> = {
  anthropic: 'claude-sonnet-4-20250514',
  deepseek: 'deepseek-chat', // DeepSeek 暂不支持 vision，占位用
  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}`;

// 获取原始配置（包含所有字段）
export function getConfig(): StoredConfig {
  if (fs.existsSync(CONFIG_FILE)) {
    try {
      const content = fs.readFileSync(CONFIG_FILE, 'utf-8');
      return JSON.parse(content);
    } catch {
      return {};
    }
  }
  return {};
}

// 加载配置
export function loadConfig(): AgentConfig {
  // 从配置文件读取
  const storedConfig = getConfig();

  // 检查是否配置了 provider
  const hasProviderConfig = !!storedConfig.provider;
  const finalProvider = storedConfig.provider || 'anthropic';

  // 通过 ProviderRegistry 获取 API Key
  const providerConfig = providerRegistry.getConfig(finalProvider);
  const finalApiKey = resolveApiKey(providerConfig);

  if (!finalApiKey) {
    // 根据是否已选择 provider 给出不同的提示
    const message = hasProviderConfig
      ? `请在 Providers 面板配置 ${finalProvider} 的 API Key`
      : '请先在 Providers 面板选择并配置一个模型提供商';
    throw new ConfigurationError(message, finalProvider, 'apiKey');
  }

  // 确定模型
  const finalModel = storedConfig.model || DEFAULT_MODELS[finalProvider];

  // 确定 baseUrl
  const finalBaseUrl = storedConfig.baseUrl || providerConfig?.baseUrl;

  // 获取模型的 contextWindow（从 ProviderRegistry 查询）
  const modelInfo = providerRegistry.getModelInfo(finalProvider, finalModel);
  const contextWindow = modelInfo?.contextWindow;

  return {
    provider: finalProvider,
    apiKey: finalApiKey,
    model: finalModel,
    maxTokens: storedConfig.maxTokens || 4096,
    systemPrompt: DEFAULT_SYSTEM_PROMPT,
    baseUrl: finalBaseUrl,
    contextWindow,
  };
}

/**
 * 加载 Vision 配置
 * Vision 用于图片理解，当主模型不支持 vision 时使用
 * 通过 ProviderRegistry 获取 API Key
 */
export function loadVisionConfig(): VisionConfig | null {
  // 从配置文件读取
  const storedConfig = getConfig();

  // 确定 vision provider（默认使用 anthropic，因为 Claude 支持 vision）
  const finalProvider = storedConfig.visionProvider || 'anthropic';

  // 通过 ProviderRegistry 获取 API Key
  const providerConfig = providerRegistry.getConfig(finalProvider);
  const finalApiKey = resolveApiKey(providerConfig);

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

  // 确定模型
  const finalModel = storedConfig.visionModel || DEFAULT_VISION_MODELS[finalProvider];

  // 确定 baseUrl
  const finalBaseUrl = storedConfig.visionBaseUrl || providerConfig?.baseUrl;

  return {
    provider: finalProvider,
    apiKey: finalApiKey,
    model: finalModel,
    baseUrl: finalBaseUrl,
  };
}

// 保存配置
export function saveConfig(config: Partial<StoredConfig>): void {
  // 确保目录存在
  if (!fs.existsSync(CONFIG_DIR)) {
    fs.mkdirSync(CONFIG_DIR, { recursive: true });
  }

  // 读取现有配置
  let existingConfig: StoredConfig = {};
  if (fs.existsSync(CONFIG_FILE)) {
    try {
      const content = fs.readFileSync(CONFIG_FILE, 'utf-8');
      existingConfig = JSON.parse(content);
    } catch {
      // 忽略
    }
  }

  // 合并并保存
  const newConfig = { ...existingConfig, ...config };
  fs.writeFileSync(CONFIG_FILE, JSON.stringify(newConfig, null, 2));
}

