/**
 * OpenAI 到 Claude 格式转换服务
 * 处理 OpenAI API 格式与 Claude API 格式之间的转换
 */

const logger = require('../utils/logger')

class OpenAIToClaudeConverter {
  constructor() {
    // 停止原因映射
    this.stopReasonMapping = {
      end_turn: 'stop',
      max_tokens: 'length',
      stop_sequence: 'stop',
      tool_use: 'tool_calls'
    }
  }

  /**
   * 将 OpenAI 请求格式转换为 Claude 格式
   * @param {Object} openaiRequest - OpenAI 格式的请求
   * @returns {Object} Claude 格式的请求
   */
  convertRequest(openaiRequest) {
    const claudeRequest = {
      model: openaiRequest.model, // 直接使用提供的模型名，不进行映射
      messages: this._convertMessages(openaiRequest.messages),
      max_tokens: openaiRequest.max_tokens || 4096,
      temperature: openaiRequest.temperature,
      top_p: openaiRequest.top_p,
      stream: openaiRequest.stream || false
    }

    // 定义 Claude Code 的默认系统提示词
    const claudeCodeSystemMessage = "You are Claude Code, Anthropic's official CLI for Claude."

    // 如果 OpenAI 请求中包含系统消息,提取并检查
    const systemMessage = this._extractSystemMessage(openaiRequest.messages)
    if (systemMessage && systemMessage.includes('You are currently in Xcode')) {
      // Xcode 系统提示词
      claudeRequest.system = systemMessage
      logger.info(
        `🔍 Xcode request detected, using Xcode system prompt (${systemMessage.length} chars)`
      )
      logger.debug(`📋 System prompt preview: ${systemMessage.substring(0, 150)}...`)
    } else {
      // 使用 Claude Code 默认系统提示词
      claudeRequest.system = claudeCodeSystemMessage
      logger.debug(
        `📋 Using Claude Code default system prompt${systemMessage ? ' (ignored custom prompt)' : ''}`
      )
    }

    // 处理停止序列
    if (openaiRequest.stop) {
      claudeRequest.stop_sequences = Array.isArray(openaiRequest.stop)
        ? openaiRequest.stop
        : [openaiRequest.stop]
    }

    // 处理工具调用
    if (openaiRequest.tools) {
      claudeRequest.tools = this._convertTools(openaiRequest.tools)
      if (openaiRequest.tool_choice) {
        claudeRequest.tool_choice = this._convertToolChoice(openaiRequest.tool_choice)
      }
    }

    // OpenAI 特有的参数已在转换过程中被忽略
    // 包括: n, presence_penalty, frequency_penalty, logit_bias, user

    logger.debug('📝 Converted OpenAI request to Claude format:', {
      model: claudeRequest.model,
      messageCount: claudeRequest.messages.length,
      hasSystem: !!claudeRequest.system,
      stream: claudeRequest.stream
    })

    return claudeRequest
  }

  /**
   * 将 Claude 响应格式转换为 OpenAI 格式
   * @param {Object} claudeResponse - Claude 格式的响应
   * @param {String} requestModel - 原始请求的模型名
   * @returns {Object} OpenAI 格式的响应
   */
  convertResponse(claudeResponse, requestModel) {
    const timestamp = Math.floor(Date.now() / 1000)

    const openaiResponse = {
      id: `chatcmpl-${this._generateId()}`,
      object: 'chat.completion',
      created: timestamp,
      model: requestModel || 'gpt-4',
      choices: [
        {
          index: 0,
          message: this._convertClaudeMessage(claudeResponse),
          finish_reason: this._mapStopReason(claudeResponse.stop_reason)
        }
      ],
      usage: this._convertUsage(claudeResponse.usage)
    }

    logger.debug('📝 Converted Claude response to OpenAI format:', {
      responseId: openaiResponse.id,
      finishReason: openaiResponse.choices[0].finish_reason,
      usage: openaiResponse.usage
    })

    return openaiResponse
  }

  /**
   * 转换流式响应的单个数据块
   * @param {String} chunk - Claude SSE 数据块
   * @param {String} requestModel - 原始请求的模型名
   * @param {String} sessionId - 会话ID
   * @returns {String} OpenAI 格式的 SSE 数据块
   */
  convertStreamChunk(chunk, requestModel, sessionId) {
    if (!chunk || chunk.trim() === '') {
      return ''
    }

    // 解析 SSE 数据
    const lines = chunk.split('\n')
    const convertedChunks = []
    let hasMessageStop = false

    for (const line of lines) {
      if (line.startsWith('data: ')) {
        const data = line.substring(6)
        if (data === '[DONE]') {
          convertedChunks.push('data: [DONE]\n\n')
          continue
        }

        try {
          const claudeEvent = JSON.parse(data)

          // 检查是否是 message_stop 事件
          if (claudeEvent.type === 'message_stop') {
            hasMessageStop = true
          }

          const openaiChunk = this._convertStreamEvent(claudeEvent, requestModel, sessionId)
          if (openaiChunk) {
            convertedChunks.push(`data: ${JSON.stringify(openaiChunk)}\n\n`)
          }
        } catch (e) {
          // 跳过无法解析的数据，不传递非JSON格式的行
          continue
        }
      }
      // 忽略 event: 行和空行，OpenAI 格式不包含这些
    }

    // 如果收到 message_stop 事件，添加 [DONE] 标记
    if (hasMessageStop) {
      convertedChunks.push('data: [DONE]\n\n')
    }

    return convertedChunks.join('')
  }

  /**
   * 提取系统消息
   */
  _extractSystemMessage(messages) {
    const systemMessages = messages.filter((msg) => msg.role === 'system')
    if (systemMessages.length === 0) {
      return null
    }

    // 合并所有系统消息
    return systemMessages.map((msg) => msg.content).join('\n\n')
  }

  /**
   * 转换消息格式
   */
  _convertMessages(messages) {
    const claudeMessages = []

    for (const msg of messages) {
      // 跳过系统消息（已经在 system 字段处理）
      if (msg.role === 'system') {
        continue
      }

      // 转换角色名称
      const role = msg.role === 'user' ? 'user' : 'assistant'

      // 转换消息内容
      const { content: rawContent } = msg
      let content

      if (typeof rawContent === 'string') {
        content = rawContent
      } else if (Array.isArray(rawContent)) {
        // 处理多模态内容
        content = this._convertMultimodalContent(rawContent)
      } else {
        content = JSON.stringify(rawContent)
      }

      const claudeMsg = {
        role,
        content
      }

      // 处理工具调用
      if (msg.tool_calls) {
        claudeMsg.content = this._convertToolCalls(msg.tool_calls)
      }

      // 处理工具响应
      if (msg.role === 'tool') {
        claudeMsg.role = 'user'
        claudeMsg.content = [
          {
            type: 'tool_result',
            tool_use_id: msg.tool_call_id,
            content: msg.content
          }
        ]
      }

      claudeMessages.push(claudeMsg)
    }

    return claudeMessages
  }

  /**
   * 转换多模态内容
   */
  _convertMultimodalContent(content) {
    return content.map((item) => {
      if (item.type === 'text') {
        return {
          type: 'text',
          text: item.text
        }
      } else if (item.type === 'image_url') {
        const imageUrl = item.image_url.url

        // 检查是否是 base64 格式的图片
        if (imageUrl.startsWith('data:')) {
          // 解析 data URL: data:image/jpeg;base64,/9j/4AAQ...
          const matches = imageUrl.match(/^data:([^;]+);base64,(.+)$/)
          if (matches) {
            const mediaType = matches[1] // e.g., 'image/jpeg', 'image/png'
            const base64Data = matches[2]

            return {
              type: 'image',
              source: {
                type: 'base64',
                media_type: mediaType,
                data: base64Data
              }
            }
          } else {
            // 如果格式不正确，尝试使用默认处理
            logger.warn('⚠️ Invalid base64 image format, using default parsing')
            return {
              type: 'image',
              source: {
                type: 'base64',
                media_type: 'image/jpeg',
                data: imageUrl.split(',')[1] || ''
              }
            }
          }
        } else {
          // 如果是 URL 格式的图片，Claude 不支持直接 URL，需要报错
          logger.error(
            '❌ URL images are not supported by Claude API, only base64 format is accepted'
          )
          throw new Error(
            'Claude API only supports base64 encoded images, not URLs. Please convert the image to base64 format.'
          )
        }
      }
      return item
    })
  }

  /**
   * 转换工具定义
   */
  _convertTools(tools) {
    return tools.map((tool) => {
      if (tool.type === 'function') {
        return {
          name: tool.function.name,
          description: tool.function.description,
          input_schema: tool.function.parameters
        }
      }
      return tool
    })
  }

  /**
   * 转换工具选择
   */
  _convertToolChoice(toolChoice) {
    if (toolChoice === 'none') {
      return { type: 'none' }
    }
    if (toolChoice === 'auto') {
      return { type: 'auto' }
    }
    if (toolChoice === 'required') {
      return { type: 'any' }
    }
    if (toolChoice.type === 'function') {
      return {
        type: 'tool',
        name: toolChoice.function.name
      }
    }
    return { type: 'auto' }
  }

  /**
   * 转换工具调用
   */
  _convertToolCalls(toolCalls) {
    return toolCalls.map((tc) => ({
      type: 'tool_use',
      id: tc.id,
      name: tc.function.name,
      input: JSON.parse(tc.function.arguments)
    }))
  }

  /**
   * 转换 Claude 消息为 OpenAI 格式
   */
  _convertClaudeMessage(claudeResponse) {
    const message = {
      role: 'assistant',
      content: null
    }

    // 处理内容
    if (claudeResponse.content) {
      if (typeof claudeResponse.content === 'string') {
        message.content = claudeResponse.content
      } else if (Array.isArray(claudeResponse.content)) {
        // 提取文本内容和工具调用
        const textParts = []
        const toolCalls = []

        for (const item of claudeResponse.content) {
          if (item.type === 'text') {
            textParts.push(item.text)
          } else if (item.type === 'tool_use') {
            toolCalls.push({
              id: item.id,
              type: 'function',
              function: {
                name: item.name,
                arguments: JSON.stringify(item.input)
              }
            })
          }
        }

        message.content = textParts.join('') || null
        if (toolCalls.length > 0) {
          message.tool_calls = toolCalls
        }
      }
    }

    return message
  }

  /**
   * 转换停止原因
   */
  _mapStopReason(claudeReason) {
    return this.stopReasonMapping[claudeReason] || 'stop'
  }

  /**
   * 转换使用统计
   */
  _convertUsage(claudeUsage) {
    if (!claudeUsage) {
      return undefined
    }

    return {
      prompt_tokens: claudeUsage.input_tokens || 0,
      completion_tokens: claudeUsage.output_tokens || 0,
      total_tokens: (claudeUsage.input_tokens || 0) + (claudeUsage.output_tokens || 0)
    }
  }

  /**
   * 转换流式事件
   */
  _convertStreamEvent(event, requestModel, sessionId) {
    const timestamp = Math.floor(Date.now() / 1000)
    const baseChunk = {
      id: sessionId,
      object: 'chat.completion.chunk',
      created: timestamp,
      model: requestModel || 'gpt-4',
      choices: [
        {
          index: 0,
          delta: {},
          finish_reason: null
        }
      ]
    }

    // 根据事件类型处理
    if (event.type === 'message_start') {
      // 处理消息开始事件，发送角色信息
      baseChunk.choices[0].delta.role = 'assistant'
      return baseChunk
    } else if (event.type === 'content_block_start' && event.content_block) {
      if (event.content_block.type === 'text') {
        baseChunk.choices[0].delta.content = event.content_block.text || ''
      } else if (event.content_block.type === 'tool_use') {
        // 开始工具调用
        baseChunk.choices[0].delta.tool_calls = [
          {
            index: event.index || 0,
            id: event.content_block.id,
            type: 'function',
            function: {
              name: event.content_block.name,
              arguments: ''
            }
          }
        ]
      }
    } else if (event.type === 'content_block_delta' && event.delta) {
      if (event.delta.type === 'text_delta') {
        baseChunk.choices[0].delta.content = event.delta.text || ''
      } else if (event.delta.type === 'input_json_delta') {
        // 工具调用参数的增量更新
        baseChunk.choices[0].delta.tool_calls = [
          {
            index: event.index || 0,
            function: {
              arguments: event.delta.partial_json || ''
            }
          }
        ]
      }
    } else if (event.type === 'message_delta' && event.delta) {
      if (event.delta.stop_reason) {
        baseChunk.choices[0].finish_reason = this._mapStopReason(event.delta.stop_reason)
      }
      if (event.usage) {
        baseChunk.usage = this._convertUsage(event.usage)
      }
    } else if (event.type === 'message_stop') {
      // message_stop 事件不需要返回 chunk，[DONE] 标记会在 convertStreamChunk 中添加
      return null
    } else {
      // 忽略其他类型的事件
      return null
    }

    return baseChunk
  }

  /**
   * 生成随机 ID
   */
  _generateId() {
    return Math.random().toString(36).substring(2, 15) + Math.random().toString(36).substring(2, 15)
  }
}

module.exports = new OpenAIToClaudeConverter()
