import axios from 'axios';
import { ILLMAdapter, Message, LLMOptions, LLMResponse, StreamChunk } from './types.js';
import { config } from '../../../config/env.js';

export class DeepSeekAdapter implements ILLMAdapter {
  modelName: string;
  private apiKey: string;
  private baseURL: string;

  constructor(modelName: string = 'deepseek-chat') {
    this.modelName = modelName;
    this.apiKey = config.deepseekApiKey || '';
    this.baseURL = 'https://api.deepseek.com/v1';

    if (!this.apiKey) {
      throw new Error('DeepSeek API key is not configured');
    }
  }

  // 非流式调用
  async chat(messages: Message[], options?: LLMOptions): Promise<LLMResponse> {
    try {
      const response = await axios.post(
        `${this.baseURL}/chat/completions`,
        {
          model: this.modelName,
          messages: messages,
          temperature: options?.temperature ?? 0.7,
          max_tokens: options?.maxTokens ?? 2000,
          top_p: options?.topP ?? 0.9,
          stream: false,
        },
        {
          headers: {
            'Content-Type': 'application/json',
            Authorization: `Bearer ${this.apiKey}`,
          },
          timeout: 180000, // 180秒超时（3分钟）- 稿件评估需要更长时间
        }
      );

      const choice = response.data.choices[0];
      
      return {
        content: choice.message.content,
        model: response.data.model,
        usage: {
          promptTokens: response.data.usage.prompt_tokens,
          completionTokens: response.data.usage.completion_tokens,
          totalTokens: response.data.usage.total_tokens,
        },
        finishReason: choice.finish_reason,
      };
    } catch (error: unknown) {
      console.error('DeepSeek API Error:', error);
      if (axios.isAxiosError(error)) {
        throw new Error(
          `DeepSeek API调用失败: ${error.response?.data?.error?.message || error.message}`
        );
      }
      throw error;
    }
  }

  // 流式调用
  async *chatStream(
    messages: Message[],
    options?: LLMOptions,
    onChunk?: (chunk: StreamChunk) => void
  ): AsyncGenerator<StreamChunk, void, unknown> {
    try {
      const response = await axios.post(
        `${this.baseURL}/chat/completions`,
        {
          model: this.modelName,
          messages: messages,
          temperature: options?.temperature ?? 0.7,
          max_tokens: options?.maxTokens ?? 2000,
          top_p: options?.topP ?? 0.9,
          stream: true,
        },
        {
          headers: {
            'Content-Type': 'application/json',
            Authorization: `Bearer ${this.apiKey}`,
          },
          responseType: 'stream',
          timeout: 60000,
        }
      );

      const stream = response.data;
      let buffer = '';

      for await (const chunk of stream) {
        buffer += chunk.toString();
        const lines = buffer.split('\n');
        buffer = lines.pop() || '';

        for (const line of lines) {
          const trimmedLine = line.trim();
          if (!trimmedLine || trimmedLine === 'data: [DONE]') {
            continue;
          }

          if (trimmedLine.startsWith('data: ')) {
            try {
              const jsonStr = trimmedLine.slice(6);
              const data = JSON.parse(jsonStr);
              
              const choice = data.choices[0];
              const content = choice.delta?.content || '';
              
              const streamChunk: StreamChunk = {
                content: content,
                done: choice.finish_reason === 'stop',
                model: data.model,
              };

              if (choice.finish_reason === 'stop' && data.usage) {
                streamChunk.usage = {
                  promptTokens: data.usage.prompt_tokens,
                  completionTokens: data.usage.completion_tokens,
                  totalTokens: data.usage.total_tokens,
                };
              }

              if (onChunk) {
                onChunk(streamChunk);
              }

              yield streamChunk;
            } catch (parseError) {
              console.error('Failed to parse SSE data:', parseError);
            }
          }
        }
      }
    } catch (error) {
      console.error('DeepSeek Stream Error:', error);
      if (axios.isAxiosError(error)) {
        throw new Error(
          `DeepSeek流式调用失败: ${error.response?.data?.error?.message || error.message}`
        );
      }
      throw error;
    }
  }
}

