import Anthropic from '@anthropic-ai/sdk';
import type { AiProvider, PingRequest, PingResponse, ToolCallRequest, ToolCallResponse } from './provider.interface';

/**
 * Anthropic 格式提供商（官方 API + 兼容 Anthropic 格式的中转站）
 */
export class AnthropicProvider implements AiProvider {
  readonly format = 'anthropic' as const;
  private client: Anthropic;

  constructor(apiKey: string, baseURL?: string) {
    this.client = new Anthropic({
      apiKey,
      ...(baseURL && baseURL !== 'https://api.anthropic.com' ? { baseURL } : {}),
    });
  }

  async callTool(req: ToolCallRequest): Promise<ToolCallResponse> {
    const toolChoice = req.forceTool
      ? ({
          type: 'tool',
          name: req.tool.name,
          disable_parallel_tool_use: true,
        } as any)
      : { type: 'auto' as const };

    const response = await this.client.messages.create({
      model: req.model,
      max_tokens: req.maxTokens,
      system: req.systemPrompt,
      tools: [
        {
          name: req.tool.name,
          description: req.tool.description,
          input_schema: req.tool.inputSchema,
        },
      ],
      tool_choice: toolChoice,
      messages: [{ role: 'user', content: req.userPrompt }],
    });

    const toolUse = response.content.find(
      (c): c is Anthropic.ToolUseBlock => c.type === 'tool_use',
    );
    if (!toolUse) {
      throw new Error(this.describeMissingToolUse(response));
    }

    return {
      toolName: toolUse.name,
      toolInput: toolUse.input as Record<string, any>,
      inputTokens: response.usage.input_tokens,
      outputTokens: response.usage.output_tokens,
      rawModel: response.model,
    };
  }

  async ping(req: PingRequest): Promise<PingResponse> {
    const resp = await this.client.messages.create({
      model: req.model,
      max_tokens: 16,
      messages: [{ role: 'user', content: 'ping' }],
    });
    return {
      ok: true,
      inputTokens: resp.usage.input_tokens,
      outputTokens: resp.usage.output_tokens,
    };
  }

  private describeMissingToolUse(response: Anthropic.Message): string {
    const contentSummary = response.content
      .map((block) => {
        if (block.type === 'text') {
          const text = block.text.replace(/\s+/g, ' ').slice(0, 160);
          return `text("${text}")`;
        }
        return block.type;
      })
      .join(', ');

    return [
      'Anthropic 未通过 tool_use 返回结果',
      `stop_reason=${response.stop_reason || 'unknown'}`,
      `content=${contentSummary || 'empty'}`,
    ].join('；');
  }
}
