import { Injectable, Logger } from '@nestjs/common';

/**
 * PromptCache — in-memory LRU(起步版)。
 *
 * key = inputHash(已含 callKey + promptVersion + input 指纹)
 * value = LLM output(任意 JSON)
 *
 * 用途:
 *   - 同 input + 同 prompt 短期重复调用(如 demo 页反复刷新)直接复用,省 token
 *   - 调试 / 单测时关掉(AI 调用支持 bustCache 参数)
 *
 * 阶段性升级路径:
 *   1. 当前:进程内 LRU,size=500
 *   2. 多副本部署:升级到 Redis(已有 RedisModule,只需替换实现)
 *   3. 长 TTL 缓存(治疗事实抽取这种几乎不变的)可单独走 DB 表
 */
@Injectable()
export class PromptCacheService {
  private readonly logger = new Logger(PromptCacheService.name);
  private readonly maxSize = 500;
  private readonly cache = new Map<string, unknown>();

  get<T>(inputHash: string): T | undefined {
    if (!this.cache.has(inputHash)) return undefined;
    // touch → 移到末尾(简易 LRU)
    const value = this.cache.get(inputHash) as T;
    this.cache.delete(inputHash);
    this.cache.set(inputHash, value);
    return value;
  }

  set<T>(inputHash: string, value: T): void {
    if (this.cache.has(inputHash)) this.cache.delete(inputHash);
    this.cache.set(inputHash, value);
    if (this.cache.size > this.maxSize) {
      // 淘汰最旧
      const oldest = this.cache.keys().next().value;
      if (oldest !== undefined) this.cache.delete(oldest);
    }
  }

  invalidate(inputHash: string): void {
    this.cache.delete(inputHash);
  }

  clear(): void {
    this.cache.clear();
  }

  size(): number {
    return this.cache.size;
  }
}
