import { Injectable } from '@nestjs/common';
import { randomUUID } from 'crypto';
import type {
  ModelProvider,
  ProviderRequest,
  ProviderResponse,
} from './provider.types';
import { estimateTokens } from '../utils/token-estimation.util';

/**
 * Mock provider —— PR3 day-1 不依赖任何真实 LLM key / 网络出境合规。
 *
 * 行为：
 *  - 接受任意 model alias（'mock-echo' / 'mock-fast' / 'mock-strong'）
 *  - 取最后一条 user message 内容拼一段"模拟回复"
 *  - 不限速、永远可用、token 用量按字符长度估算
 *
 * PR3.5 ModelRouter 进来后会按规则把"低难度/无 PII"任务路由到 mock，
 * 真任务路由到 AnthropicProvider / OpenAIProvider。
 */
@Injectable()
export class MockProvider implements ModelProvider {
  readonly name = 'mock';
  readonly supportedModels = ['mock-echo', 'mock-fast', 'mock-strong'] as const;

  isAvailable(): boolean {
    return true;
  }

  async invoke(request: ProviderRequest): Promise<ProviderResponse> {
    const userMsg = [...request.messages].reverse().find((m) => m.role === 'user');
    const prompt = userMsg?.content ?? '';
    const text = composeMockReply(prompt, request.model);

    const inputTokens = estimateTokens(request.messages.map((m) => m.content).join('\n'));
    const outputTokens = estimateTokens(text);

    return {
      id: randomUUID(),
      model: request.model,
      resolvedModel: request.model,
      text,
      stopReason: 'end_turn',
      usage: { inputTokens, outputTokens },
    };
  }
}

function composeMockReply(prompt: string, model: string): string {
  const tag = `[mock provider · ${model}]`;
  if (!prompt) {
    return `${tag} 我收到了一个空 prompt。PR3 阶段没有真实 LLM 接入，PR3.5 之后会按 ModelRouter 路由到 Anthropic / OpenAI。`;
  }
  const preview = prompt.length > 120 ? `${prompt.slice(0, 120)}…` : prompt;
  return `${tag} 我收到了你的问题：「${preview}」。\n\n这是 PR3 的 mock provider 占位回复——结构和 token 用量都已对齐 ProviderResponse 契约，PR3.5 ModelRouter 路由到真实 provider 后就会换成真答案。`;
}

