import type { LanguageModel } from 'ai';

/**
 * Token 使用统计
 */
export interface TokenUsage {
  /** 输入 tokens（估算） */
  input: number;
  /** 上下文限制 */
  contextLimit: number;
  /** 可用空间（contextLimit - outputReserve） */
  available: number;
  /** 使用百分比 (0-100) */
  usagePercent: number;
}

/**
 * 压缩配置
 */
export interface CompressionConfig {
  /** 模型上下文限制 (默认 200k) */
  contextLimit: number;
  /** 预留输出 tokens (默认 32k) */
  outputReserve: number;
  /** 保护最近 tokens 不被 prune (默认 40k) */
  pruneProtect: number;
  /** 最小清理量才执行 prune (默认 20k) */
  pruneMinimum: number;
  /** 溢出阈值，超过此比例触发自动压缩 (默认 0.85) */
  overflowThreshold: number;
}

/**
 * 默认压缩配置
 */
export const DEFAULT_COMPRESSION_CONFIG: CompressionConfig = {
  contextLimit: 200_000,
  outputReserve: 32_000,
  pruneProtect: 40_000,
  pruneMinimum: 20_000,
  overflowThreshold: 0.85,
};

/**
 * 压缩占位符
 */
export const COMPACTED_PLACEHOLDER = '[此工具输出已压缩]';

/**
 * 摘要消息标记 key
 */
export const SUMMARY_MARKER = '__summary__';

/**
 * 工具结果压缩标记 key
 */
export const COMPACTED_MARKER = '__compacted__';

/**
 * 压缩上下文（传递给压缩器的参数）
 */
export interface CompressionContext {
  config: CompressionConfig;
  model?: LanguageModel;
}

/**
 * 压缩结果（基础）
 */
export interface CompressionResult {
  /** 压缩后的消息 */
  messages: import('ai').ModelMessage[];
  /** 释放的 tokens */
  freedTokens: number;
  /** 压缩类型 */
  type: 'prune' | 'compaction' | 'both';
}

/**
 * 压缩状态枚举
 */
export enum CompressionStatus {
  /** 成功压缩 */
  SUCCESS = 'success',
  /** 未达阈值，无需压缩 */
  NOOP = 'noop',
  /** 失败：空摘要 */
  FAILED_EMPTY_SUMMARY = 'failed_empty_summary',
  /** 失败：token 膨胀（摘要反而增加 token） */
  FAILED_TOKEN_INFLATED = 'failed_token_inflated',
  /** 失败：其他错误 */
  FAILED_ERROR = 'failed_error',
}

/**
 * 详细压缩结果
 */
export interface DetailedCompressionResult {
  /** 压缩后的消息 */
  messages: import('ai').ModelMessage[];
  /** 释放的 tokens（正数=成功，0或负数=失败） */
  freedTokens: number;
  /** 压缩类型 */
  type: 'prune' | 'compaction' | 'both' | 'none';
  /** 详细状态 */
  status: CompressionStatus;
  /** 错误信息（失败时） */
  error?: string;
  /** 原始 token 数（压缩前） */
  originalTokens?: number;
  /** 摘要 token 数（压缩后） */
  summaryTokens?: number;
}
