/**
 * Token Counter Utility
 * Shared between frontend and backend for consistent validation
 *
 * Uses character-based estimation with safety margin
 * Future: Can be upgraded to tiktoken for exact counts
 */

export interface TokenCountResult {
  tokens: number
  characters: number
  withinLimit: boolean
}

export interface TokenLimits {
  maxTokens: number
  errorMessage?: string
}

/**
 * Estimate token count from text
 * Uses 1 token ≈ 3.5 characters (improved accuracy)
 *
 * Character-based approximation provides:
 * - Fast estimation (no external dependencies)
 * - ~10-15% error margin for English text
 * - Works for all text types (code, prose, JSON)
 *
 * Note: For exact token counts, use model-specific tokenizers (tiktoken for OpenAI, Anthropic SDK for Claude)
 *
 * @param text - Text to estimate tokens for (string or JSON-serializable object)
 * @returns Estimated token count
 *
 * @example
 * ```typescript
 * estimateTokens("Hello world") // ~3 tokens
 * estimateTokens({ message: "Hello" }) // ~5 tokens (includes JSON structure)
 * ```
 */
export function estimateTokens(text: string | unknown): number {
  const content = typeof text === 'string' ? text : JSON.stringify(text)
  const chars = content.length
  // 1 token ≈ 3.5 characters (better accuracy than 4 chars with safety margin)
  return Math.ceil(chars / 3.5)
}

/**
 * Validate text against token limit
 *
 * @param text - Text to validate (string or JSON-serializable object)
 * @param limits - Token limits configuration
 * @returns Validation result with token count and character count
 *
 * @example
 * ```typescript
 * const result = validateTokenLimit(userInput, { maxTokens: 25000 })
 * if (!result.withinLimit) {
 *   console.error(`Too large: ${result.tokens} tokens (max 25000)`)
 * }
 * ```
 */
export function validateTokenLimit(text: string | unknown, limits: TokenLimits): TokenCountResult {
  const content = typeof text === 'string' ? text : JSON.stringify(text)
  const characters = content.length
  const tokens = estimateTokens(content)

  return {
    tokens,
    characters,
    withinLimit: tokens <= limits.maxTokens
  }
}

/**
 * Common token limits for different use cases
 *
 * Limits are based on:
 * - User experience (reasonable input sizes)
 * - DoS prevention (resource exhaustion)
 * - Model context windows (AI capabilities)
 */
export const TOKEN_LIMITS = {
  // User input limits (prompts)
  USER_MESSAGE: 25000, // ~100KB text - allows large code pastes
  CHAT_MESSAGE: 10000, // ~40KB text - typical chat message

  // WebSocket message limits
  WEBSOCKET_MESSAGE: 25000, // Same as user message
  WEBSOCKET_TOTAL: 250000, // Hard limit for entire payload (1MB)

  // AI model context windows (for reference)
  GPT4_TURBO: 128000,
  CLAUDE_SONNET: 200000,
  GPT35_TURBO: 16385
} as const

