'use strict';

const { createConversation, loadConversation, listConversations, updateConversation } = require('../storage/conversation_store');
const { formatRelativeTime } = require('../utils/time');
const { maskKey, getModelByKey } = require('../config');
const { runSelect } = require('../ui/select_prompt');
const { runResumeMenu } = require('../ui/resume_menu');
const { buildFinalLine, formatResultLines, printResultLines } = require('../ui/tool_display');
const { renderBox } = require('../ui/banner');
const { createIndentedWriter } = require('../ui/indented_writer');
const { cyan, green } = require('../utils/colors');
const { Spinner } = require('../ui/spinner');
const { normalizeTokenUsage } = require('../utils/token_usage');

function printHelp() {
  console.log('/new 创建新对话');
  console.log('/resume 加载旧对话');
  console.log('/allow 切换运行模式（只读/无限制）');
  console.log('/model 切换模型和思考模式');
  console.log('/status 查看当前对话状态');
  console.log('/compact 压缩当前对话');
  console.log('/config 查看当前配置');
  console.log('/exit 退出程序');
  console.log('/help 显示指令列表');
}

function printNotice(message) {
  console.log('');
  console.log(message);
  console.log('');
}

function applyModelState(state, config, modelKey, preferredThinking) {
  const model = getModelByKey(config, modelKey);
  if (!model || !model.valid) return false;
  state.modelKey = model.key;
  state.modelId = model.model_id || model.name || model.key;
  if (model.modes === 'fast') state.thinkingMode = false;
  else if (model.modes === 'thinking') state.thinkingMode = true;
  else state.thinkingMode = !!preferredThinking;
  return true;
}

async function handleCommand(input, ctx) {
  const { rl, state, config, workspace, statusBar } = ctx;
  const persist = () => {
    if (!state.conversation) return;
    state.conversation = updateConversation(workspace, state.conversation, state.messages || [], {
      model_key: state.modelKey,
      model_id: state.modelId,
      thinking_mode: state.thinkingMode,
      allow_mode: state.allowMode,
      token_usage: state.tokenUsage,
      cwd: workspace,
    });
  };
  const [cmd, ...rest] = input.split(/\s+/);
  const arg = rest.join(' ').trim();

  if (cmd === '/exit') {
    rl.close();
    return { exit: true };
  }

  if (cmd === '/help') {
    printHelp();
    return { exit: false };
  }

  if (cmd === '/new') {
    state.tokenUsage = normalizeTokenUsage({ prompt: 0, completion: 0, total: 0 });
    const conv = createConversation(workspace, {
      model_key: state.modelKey,
      model_id: state.modelId,
      thinking_mode: state.thinkingMode,
      allow_mode: state.allowMode,
      token_usage: state.tokenUsage,
      cwd: workspace,
    });
    state.conversation = conv;
    state.messages = [];
    printNotice(`已创建新对话: ${conv.id}`);
    persist();
    if (statusBar) statusBar.render();
    return { exit: false };
  }

  if (cmd === '/resume') {
    if (arg) {
      const conv = loadConversation(workspace, arg);
      if (!conv) {
        printNotice('未找到对话');
        return { exit: false };
      }
      state.conversation = conv;
      state.messages = conv.messages || [];
      const ok = applyModelState(state, config, conv.metadata?.model_key || state.modelKey, !!conv.metadata?.thinking_mode);
      if (!ok) {
        printNotice('对话中的模型不可用，已保留当前模型');
      }
      state.allowMode = conv.metadata?.allow_mode || state.allowMode;
      state.tokenUsage = normalizeTokenUsage(conv.metadata?.token_usage);
      printNotice(`已加载对话: ${conv.id}`);
      renderConversation(state.messages);
      persist();
      return { exit: false };
    }

    const items = listConversations(workspace);
    if (!items.length) {
      printNotice('暂无对话记录');
      return { exit: false };
    }

    const filtered = items.filter((it) => it.id !== state.conversation?.id);
    if (!filtered.length) {
      printNotice('暂无可恢复的对话');
      return { exit: false };
    }
    const displayItems = filtered.map((item) => {
      const rel = formatRelativeTime(item.updated_at || item.created_at);
      const title = item.title || '新对话';
      return { id: item.id, time: rel, title };
    });

    const result = await runResumeMenu({ rl, items: displayItems });
    if (!result) return { exit: false };
    if (result.type === 'new') {
      const convNew = createConversation(workspace, {
        model_key: state.modelKey,
        model_id: state.modelId,
        thinking_mode: state.thinkingMode,
        allow_mode: state.allowMode,
        token_usage: state.tokenUsage,
        cwd: workspace,
      });
      state.conversation = convNew;
      state.messages = [];
      printNotice(`已创建新对话: ${convNew.id}`);
      persist();
      return { exit: false };
    }
    const conv = loadConversation(workspace, result.id);
    if (!conv) {
      printNotice('未找到对话');
      return { exit: false };
    }
    state.conversation = conv;
    state.messages = conv.messages || [];
    const ok = applyModelState(state, config, conv.metadata?.model_key || state.modelKey, !!conv.metadata?.thinking_mode);
    if (!ok) {
      printNotice('对话中的模型不可用，已保留当前模型');
    }
    state.allowMode = conv.metadata?.allow_mode || state.allowMode;
    state.tokenUsage = normalizeTokenUsage(conv.metadata?.token_usage);
    printNotice(`已加载对话: ${conv.id}`);
    renderConversation(state.messages);
    persist();
    return { exit: false };
  }

  if (cmd === '/allow') {
    const choices = [
      {
        name: `1. Read Only${state.allowMode === 'read_only' ? ' (current)' : ''}  只能读取文件与搜索，不能修改和运行指令`,
        value: 'read_only',
      },
      {
        name: `2. Full Access${state.allowMode === 'full_access' ? ' (current)' : ''}  可修改/执行，允许工作区外文件与网络`,
        value: 'full_access',
      },
    ];
    const selected = await runSelect({ rl, message: '', choices, pageSize: 6 });
    if (selected) {
      state.allowMode = selected;
      printNotice(`运行模式已切换为: ${state.allowMode}`);
      persist();
    }
    return { exit: false };
  }

  if (cmd === '/model') {
    const models = config.valid_models || [];
    if (!models.length) {
      printNotice('未找到可用模型，请先完善 models.json');
      return { exit: false };
    }
    const modelChoices = models.map((model, idx) => ({
      name: `${idx + 1}. ${model.name}${state.modelKey === model.key ? ' (current)' : ''}`,
      value: model.key,
    }));
    const modelKey = await runSelect({ rl, message: '', choices: modelChoices, pageSize: 6 });
    if (!modelKey) return { exit: false };
    const selected = getModelByKey(config, modelKey);
    if (!selected || !selected.valid) {
      printNotice('模型配置无效');
      return { exit: false };
    }
    state.modelKey = selected.key;
    state.modelId = selected.model_id || selected.name || selected.key;
    printNotice(`模型已切换为: ${state.modelKey}`);

    if (selected.modes === 'fast') {
      state.thinkingMode = false;
      printNotice('思考模式: fast');
      persist();
      return { exit: false };
    }
    if (selected.modes === 'thinking') {
      state.thinkingMode = true;
      printNotice('思考模式: thinking');
      persist();
      return { exit: false };
    }

    const thinkingChoices = [
      { name: `1. Fast${!state.thinkingMode ? ' (current)' : ''}`, value: 'fast' },
      { name: `2. Thinking${state.thinkingMode ? ' (current)' : ''}`, value: 'thinking' },
    ];
    const mode = await runSelect({ rl, message: '', choices: thinkingChoices, pageSize: 6 });
    if (mode) {
      state.thinkingMode = mode === 'thinking';
      printNotice(`思考模式: ${mode}`);
      persist();
    }
    return { exit: false };
  }

  if (cmd === '/status') {
    const usage = normalizeTokenUsage(state.tokenUsage);
    const model = getModelByKey(config, state.modelKey);
    const title = 'Status';
    const maxContext = model && model.max_context ? model.max_context : '';
    const maxOutput = model && model.max_output ? model.max_output : '';
    const lines = [
      `model: ${state.modelKey}`,
      `thinking: ${state.thinkingMode ? 'thinking' : 'fast'}`,
      `workspace: ${workspace}`,
      `allow: ${state.allowMode}`,
      `conversation: ${state.conversation?.id || 'none'}`,
      `tokens(in): ${usage.prompt}`,
      `tokens(out): ${usage.completion}`,
      `tokens(total): ${usage.total}`,
      `max_context: ${maxContext}`,
      `max_output: ${maxOutput}`,
    ];
    renderBox({ title, lines });
    return { exit: false };
  }

  if (cmd === '/config') {
    const model = getModelByKey(config, state.modelKey);
    console.log('');
    console.log(`config: ${config.path || ''}`);
    if (model) {
      console.log(`base_url: ${model.base_url || ''}`);
      console.log(`modelname: ${model.model_id || model.name || ''}`);
      console.log(`apikey: ${maskKey(model.api_key)}`);
      console.log(`modes: ${model.modes || ''}`);
      console.log(`multimodal: ${model.multimodal || ''}`);
      console.log(`max_output: ${model.max_output || ''}`);
      console.log(`max_context: ${model.max_context || ''}`);
    }
    console.log(`tavily_api_key: ${maskKey(config.tavily_api_key)}`);
    console.log('');
    return { exit: false };
  }

  if (cmd === '/compact') {
    if (!state.conversation) return { exit: false };
    const oldId = state.conversation.id;
    const spinner = new Spinner();
    spinner.start(() => '');
    const messages = (state.messages || []).filter((msg) => msg.role === 'user' || msg.role === 'assistant');
    const cleaned = messages.map((msg) => {
      if (msg.role === 'assistant') {
        const copy = { ...msg };
        delete copy.tool_calls;
        delete copy.tool_raw;
        return copy;
      }
      return msg;
    });
    const newConv = createConversation(workspace, {
      model_key: state.modelKey,
      model_id: state.modelId,
      thinking_mode: state.thinkingMode,
      allow_mode: state.allowMode,
      token_usage: state.tokenUsage,
      cwd: workspace,
    });
    const updated = updateConversation(workspace, newConv, cleaned, {
      model_key: state.modelKey,
      model_id: state.modelId,
      thinking_mode: state.thinkingMode,
      allow_mode: state.allowMode,
      token_usage: state.tokenUsage,
      cwd: workspace,
    });
    state.conversation = updated;
    state.messages = cleaned;
    spinner.stopSilent();
    printNotice(`压缩完成：${oldId} -> ${state.conversation.id}`);
    persist();
    return { exit: false };
  }

  printNotice(`未知指令: ${cmd}，使用 /help 查看指令列表。`);
  return { exit: false };
}

function renderConversation(messages) {
  if (!Array.isArray(messages) || messages.length === 0) return;
  const toolCallMap = new Map();

  for (const msg of messages) {
    if (msg.role === 'user') {
      console.log('');
      const w = createIndentedWriter('   ');
      w.write(`${cyan('用户：')}${msg.content || ''}`);
      console.log('');
      console.log('');
      continue;
    }

    if (msg.role === 'assistant') {
      if (Array.isArray(msg.tool_calls)) {
        msg.tool_calls.forEach((tc) => {
          if (tc && tc.id) toolCallMap.set(tc.id, tc);
        });
      }
      if (msg.content) {
        console.log('');
        const w = createIndentedWriter('   ');
        w.write(`${green('Eagent：')}`);
        if (msg.content) w.write(msg.content);
        console.log('');
        console.log('');
      }
      continue;
    }

    if (msg.role === 'tool') {
      const toolCall = toolCallMap.get(msg.tool_call_id) || {};
      const name = toolCall.function?.name || 'tool';
      let args = {};
      try {
        args = JSON.parse(toolCall.function?.arguments || '{}');
      } catch (_) {
        args = {};
      }
      const line = buildFinalLine(name, args);
      // 静态回放：直接输出完成态
      process.stdout.write(`• ${line}\n`);
      const raw = msg.tool_raw || { success: true };
      const resultLines = formatResultLines(name, args, raw);
      printResultLines(resultLines);
      continue;
    }
  }
}

module.exports = { handleCommand };
