/**
 * Auto-Compact Context Summarization
 * Ported from opencode-ai/opencode internal/llm/agent/agent.go (summarize logic)
 *
 * When a conversation approaches the context window limit, this module
 * summarizes the conversation and returns a condensed version.
 *
 * Used for BYOK cloud mode (OpenRouter, direct API calls) where the server
 * manages the message history. For relay mode, the CLI handles context internally.
 */

// Model context windows (opencode pattern: models.go ContextWindow)
const CONTEXT_WINDOWS = {
  'claude-sonnet-4-20250514': 200000,
  'claude-opus-4-20250514': 200000,
  'claude-haiku-4-5-20251001': 200000,
  'gpt-4o': 128000,
  'gpt-4o-mini': 128000,
  'o1': 200000,
  'o3-mini': 200000,
  'deepseek-chat': 64000,
  'deepseek-reasoner': 64000,
};

// Rough token estimation (~4 chars per token)
function estimateTokens(text) {
  return Math.ceil((text || '').length / 4);
}

/**
 * Check if a message history needs compaction.
 * @param {Array} messages - Array of { role, content } messages
 * @param {string} model - Model name
 * @param {number} threshold - Fraction of context window to trigger (default 0.85)
 * @returns {{ needsCompact: boolean, estimatedTokens: number, contextWindow: number }}
 */
export function checkNeedsCompact(messages, model, threshold = 0.85) {
  const contextWindow = CONTEXT_WINDOWS[model] || 128000;
  const totalTokens = messages.reduce((sum, m) => sum + estimateTokens(m.content), 0);
  return {
    needsCompact: totalTokens > contextWindow * threshold,
    estimatedTokens: totalTokens,
    contextWindow,
  };
}

/**
 * Build a summarization prompt for compacting conversation history.
 * Returns messages array suitable for sending to an LLM.
 *
 * @param {Array} messages - Full message history
 * @param {string} systemPrompt - Original system prompt
 * @returns {Array} Messages for the summarization call
 */
export function buildSummarizationPrompt(messages, systemPrompt = '') {
  // Take the conversation content and ask for a summary
  // (opencode pattern: AgentSummarizer with dedicated prompt)
  const conversationText = messages
    .map(m => `[${m.role}]: ${(m.content || '').slice(0, 2000)}`)
    .join('\n\n');

  return [
    {
      role: 'system',
      content: `You are a conversation summarizer. Summarize the following conversation between a user and an AI coding assistant. Focus on:
1. Key decisions made
2. Files modified and why
3. Current state of the task
4. Any unresolved issues or next steps

Keep the summary concise but preserve all critical technical details. The summary will be used as context for continuing the conversation.`,
    },
    {
      role: 'user',
      content: `Summarize this conversation:\n\n${conversationText}`,
    },
  ];
}

/**
 * Compact a message history by replacing old messages with a summary.
 * The summary becomes the first message, preserving the most recent messages.
 *
 * @param {Array} messages - Full message history
 * @param {string} summary - Generated summary text
 * @param {number} keepRecent - Number of recent messages to keep verbatim (default 4)
 * @returns {Array} Compacted messages
 */
export function compactMessages(messages, summary, keepRecent = 4) {
  const recentMessages = messages.slice(-keepRecent);

  return [
    {
      role: 'system',
      content: `[Conversation Summary]\n${summary}\n\n[The conversation continues below with the most recent messages]`,
    },
    ...recentMessages,
  ];
}
