/**
 * Chat 命令实现
 */

const path = require('path');
const dotenv = require('dotenv');
const { Framework } = require('../../../src');
const { ChatUI } = require('../ui/chat-ui');

// 加载 .env 文件
dotenv.config();

// 默认配置
const DEFAULT_CONFIG = {
  model: 'MiniMax-M2.7',
  provider: 'minimax',
  baseURL: 'https://api.minimaxi.com/v1',
  apiKey: null,
};

// Provider 默认配置
const PROVIDER_DEFAULTS = {
  minimax: {
    model: 'MiniMax-M2.7',
    baseURL: 'https://api.minimaxi.com/v1',
  },
  deepseek: {
    model: 'deepseek-chat',
    baseURL: 'https://api.deepseek.com/v1',
  },
};

/**
 * 获取环境变量配置
 */
function getEnvConfig() {
  const provider = process.env.FOLIKO_PROVIDER || DEFAULT_CONFIG.provider;
  const providerDefaults = PROVIDER_DEFAULTS[provider] || PROVIDER_DEFAULTS.minimax;

  // 支持多种 API key 环境变量名
  let apiKey = process.env.FOLIKO_API_KEY || null;
  if (!apiKey) {
    // 根据 provider 查找对应的 API key
    const upperProvider = provider.toUpperCase().replace(/-/g, '_');
    apiKey = process.env[`${upperProvider}_API_KEY`] || null;
  }

  return {
    model: process.env.FOLIKO_MODEL || providerDefaults.model,
    provider: provider,
    baseURL: process.env.FOLIKO_BASE_URL || providerDefaults.baseURL,
    apiKey: apiKey,
  };
}

/**
 * 解析命令行参数（命令行参数优先于环境变量）
 */
function parseArgs(args) {
  // 先获取环境变量配置（作为默认值）
  const envConfig = getEnvConfig();
  const options = { ...envConfig };

  for (let i = 0; i < args.length; i++) {
    const arg = args[i];
    if (arg === '-c' || arg === '--continue' || arg === '--continuous') {
      // 持续测试模式：传入 'sessionId:command1|command2|command3'
      // 或 command1|command2|command3 (使用默认 sessionId)
      options.continuous = true;
      options.commandSequence = args[++i] || '';
    } else if (arg === '--model' && args[i + 1]) {
      options.model = args[++i];
    } else if (arg === '--provider' && args[i + 1]) {
      options.provider = args[++i];
    } else if (arg === '--base-url' && args[i + 1]) {
      options.baseURL = args[++i];
    } else if (arg === '--api-key' && args[i + 1]) {
      options.apiKey = args[++i];
    } else if (arg === '--stream') {
      options.stream = true;
    } else if (arg === '--no-stream') {
      options.stream = false;
    } else if (arg === '--clear') {
      options.clearSession = true;
    } else if (arg === '--session' && args[i + 1]) {
      options.sessionId = args[++i];
    }
  }

  // 默认开启流式
  if (options.stream === undefined) {
    options.stream = true;
  }

  return options;
}

/**
 * 持续测试模式：自动发送多条消息进行测试
 */
async function runContinuousTest(agent, options) {
  const sessionId = options.sessionId || 'cli_default';
  const commands = options.commandSequence.split('|').filter((c) => c.trim());

  if (commands.length === 0) {
    console.log('错误：-c 参数需要提供命令序列，格式：command1|command2|command3');
    process.exit(1);
  }

  console.log('=== 持续测试模式 ===');
  console.log(`Session: ${sessionId}`);
  console.log(`命令数量: ${commands.length}`);
  console.log('');

  const runWithContext = agent.framework?.runWithContext.bind(agent.framework);

  for (let i = 0; i < commands.length; i++) {
    const cmd = commands[i];
    console.log(`\n[${i + 1}/${commands.length}] >>> ${cmd}`);
    console.log('-'.repeat(50));

    try {
      let fullResponse = '';
      await runWithContext({ sessionId }, async () => {
        for await (const chunk of agent.chatStream(cmd, { sessionId })) {
          if (chunk.type === 'text') {
            fullResponse += chunk.text;
            process.stdout.write(chunk.text);
          } else if (chunk.type === 'tool-call') {
            console.log(`\n[工具调用] ${chunk.toolName}  ${JSON.stringify(chunk.input)}`);
          } else if (chunk.type === 'error') {
            console.error(`\n[错误] ${chunk.error}`);
          }
        }
      });
      console.log('\n' + '-'.repeat(50));
      console.log(`[完成] 回复长度: ${fullResponse.length}`);
    } catch (err) {
      console.error(`\n[执行错误] ${err.message}`);
      // 继续执行下一条命令
    }

    // 命令间隔 1 秒
    await new Promise((r) => setTimeout(r, 1000));
  }

  console.log('\n=== 测试完成 ===');
  console.log(`共执行 ${commands.length} 条命令`);
}

/**
 * Chat 命令入口
 */
async function chatCommand(args) {
  const options = parseArgs(args);
  console.log('=== Foliko 持续对话 ===\n');
  console.log('输入 exit 或 quit 退出\n');
  // 初始化框架
  const framework = new Framework({ debug: false });
  await framework.bootstrap({
    agentDir: process.cwd() + '/.agent',
    aiConfig: {
      provider: options.provider,
      model: options.model,
      baseURL: options.baseURL,
      apiKey: options.apiKey,
      providerOptions: {
        maxOutputTokens: 8192,
      },
    },
  });

  // 使用框架的 _mainAgent（已注册 memory-context 等）
  const agent = framework._mainAgent;
  if (!agent) {
    console.error('错误：框架未正确初始化，请检查 AI 配置');
    process.exit(1);
  }

  // 更新 _mainAgent 的配置
  agent.setMetadata('WORK_DIR', process.cwd());
  agent.setSystemPrompt(`你是一个有帮助的助手，擅长回答问题和执行任务。
**重要:** 子Agent 匹配规则必须遵守：
- 根据【子 Agent 匹配表】，将任务委托给最匹配的子Agent处理
- 使用 subagent_call 工具并指定 agentName 来委托任务
- 只有当没有匹配的子Agent时，才直接调用工具
**命令执行规范：**
- 执行 npx skills add / npx skills remove / npx skills list 命令时，必须自动添加参数：-a openclaw -y
- 禁止添加 -g 参数
- 例如：npx skills add xxx 应该执行为 npx skills add xxx -a openclaw -y`);

  // 持续测试模式
  if (options.continuous) {
    await runContinuousTest(agent, options);
    return;
  }

  // 初始化 UI
  const ui = new ChatUI(agent, { stream: options.stream });

  // 监听通知事件，在 CLI 中显示
  // 显示当前会话的通知，以及没有指定 sessionId 的广播通知
  framework.on('notification', (data) => {
    const { title, message, source, timestamp, sessionId } = data;
    // 如果通知指定了 sessionId 且不匹配 CLI 会话，跳过
    if (sessionId && sessionId !== ui.sessionId) {
      return;
    }
    const time = timestamp ? new Date(timestamp).toLocaleTimeString('zh-CN') : '';
    console.log('\n' + '='.repeat(50));
    console.log(`🔔 [${source}] ${title}`);
    console.log(message);
    if (time) console.log(`时间: ${time}`);
    console.log('='.repeat(50) + '\n');
  });

  // 启动聊天
  ui.start();
}

module.exports = { chatCommand };
