'use strict';

const fs = require('fs');
const path = require('path');
const crypto = require('crypto');
const { toISO } = require('../utils/time');
const { normalizeTokenUsage } = require('../utils/token_usage');

function getWorkspaceStore(workspace) {
  const base = path.join(workspace, '.easyagent');
  const convDir = path.join(base, 'conversations');
  const indexFile = path.join(base, 'index.json');
  if (!fs.existsSync(convDir)) fs.mkdirSync(convDir, { recursive: true });
  if (!fs.existsSync(indexFile)) fs.writeFileSync(indexFile, JSON.stringify({}, null, 2), 'utf8');
  return { base, convDir, indexFile };
}

function newConversationId() {
  return crypto.randomUUID();
}

function loadIndex(indexFile) {
  try {
    const raw = fs.readFileSync(indexFile, 'utf8');
    return raw ? JSON.parse(raw) : {};
  } catch (_) {
    return {};
  }
}

function saveIndex(indexFile, index) {
  fs.writeFileSync(indexFile, JSON.stringify(index, null, 2), 'utf8');
}

function extractTitle(messages) {
  for (const msg of messages) {
    if (msg.role === 'user') {
      let content = '';
      if (typeof msg.content === 'string') {
        content = msg.content.trim();
      } else if (Array.isArray(msg.content)) {
        content = msg.content
          .filter((part) => part && part.type === 'text' && typeof part.text === 'string')
          .map((part) => part.text)
          .join(' ')
          .trim();
      }
      if (content) return content.length > 50 ? `${content.slice(0, 50)}...` : content;
    }
  }
  return '新对话';
}

function countTools(messages) {
  let count = 0;
  for (const msg of messages) {
    if (msg.role === 'assistant' && Array.isArray(msg.tool_calls)) count += msg.tool_calls.length;
    if (msg.role === 'tool') count += 1;
  }
  return count;
}

function saveConversation(workspace, conversation) {
  const { convDir, indexFile } = getWorkspaceStore(workspace);
  const filePath = path.join(convDir, `${conversation.id}.json`);
  fs.writeFileSync(filePath, JSON.stringify(conversation, null, 2), 'utf8');

  const index = loadIndex(indexFile);
  index[conversation.id] = {
    title: conversation.title || '新对话',
    created_at: conversation.created_at,
    updated_at: conversation.updated_at,
    total_messages: (conversation.messages || []).length,
    total_tools: countTools(conversation.messages || []),
    thinking_mode: conversation.metadata?.thinking_mode || false,
    run_mode: conversation.metadata?.thinking_mode ? 'thinking' : 'fast',
    model_key: conversation.metadata?.model_key || '',
  };
  saveIndex(indexFile, index);
}

function createConversation(workspace, metadata = {}) {
  const id = newConversationId();
  const now = toISO();
  const conversation = {
    id,
    title: '新对话',
    created_at: now,
    updated_at: now,
    metadata: {
      model_key: metadata.model_key || '',
      model_id: metadata.model_id || '',
      thinking_mode: !!metadata.thinking_mode,
      allow_mode: metadata.allow_mode || 'full_access',
      token_usage: normalizeTokenUsage(metadata.token_usage),
      cwd: metadata.cwd || '',
    },
    messages: [],
  };
  saveConversation(workspace, conversation);
  return conversation;
}

function loadConversation(workspace, id) {
  const { convDir } = getWorkspaceStore(workspace);
  const filePath = path.join(convDir, `${id}.json`);
  if (!fs.existsSync(filePath)) return null;
  const raw = fs.readFileSync(filePath, 'utf8');
  if (!raw) return null;
  return JSON.parse(raw);
}

function listConversations(workspace) {
  const { indexFile } = getWorkspaceStore(workspace);
  const index = loadIndex(indexFile);
  const entries = Object.entries(index).map(([id, meta]) => ({ id, ...meta }));
  entries.sort((a, b) => {
    const ta = new Date(a.updated_at || a.created_at || 0).getTime();
    const tb = new Date(b.updated_at || b.created_at || 0).getTime();
    return tb - ta;
  });
  return entries;
}

function updateConversation(workspace, conversation, messages, metadataUpdates = {}) {
  const now = toISO();
  const updated = {
    ...conversation,
    messages,
    updated_at: now,
  };
  updated.title = extractTitle(messages);
  updated.metadata = {
    ...conversation.metadata,
    ...metadataUpdates,
    token_usage: metadataUpdates && Object.prototype.hasOwnProperty.call(metadataUpdates, 'token_usage')
      ? normalizeTokenUsage(metadataUpdates.token_usage)
      : normalizeTokenUsage(conversation.metadata?.token_usage),
  };
  saveConversation(workspace, updated);
  return updated;
}

module.exports = {
  getWorkspaceStore,
  createConversation,
  loadConversation,
  listConversations,
  updateConversation,
  saveConversation,
};
