import { joinLlmUrl, LLM_API_KEY } from '@/config/llm'
import { mediaUrl, SENDER_ROLE_USER, SENDER_ROLE_AI } from '@/utils/aiConsult'

export { SENDER_ROLE_USER, SENDER_ROLE_AI }

export const MODEL_OPTION_DEFS = [
  { value: 'auto', labelKey: 'modelAuto', shortKey: 'modelAutoShort', descKey: 'modelAutoDesc', icon: 'grid-fill' },
  { value: 'yak-disease', labelKey: 'modelDisease', shortKey: 'modelDiseaseShort', descKey: 'modelDiseaseDesc', icon: 'order' },
  { value: 'yak-general', labelKey: 'modelGeneral', shortKey: 'modelGeneralShort', descKey: 'modelGeneralDesc', icon: 'chat' },
  { value: 'yak-feeding', labelKey: 'modelFeeding', shortKey: 'modelFeedingShort', descKey: 'modelFeedingDesc', icon: 'shopping-cart' },
  { value: 'yak-growth', labelKey: 'modelGrowth', shortKey: 'modelGrowthShort', descKey: 'modelGrowthDesc', icon: 'chat' }
]

export const MEDIA_RULES = {
  image: { exts: ['jpg', 'jpeg', 'png', 'gif'], maxMb: 10, errFmt: 'errImageFmt', errMb: 'errImageMb' },
  video: { exts: ['mp4', 'mov'], maxMb: 50, errFmt: 'errVideoFmt', errMb: 'errVideoMb' },
  voice: { exts: ['mp3', 'm4a', 'wav'], maxMb: 10, errFmt: 'errVoiceFmt', errMb: 'errVoiceMb' }
}

export function genLocalId() {
  return 'm_' + Date.now().toString(36) + '_' + Math.random().toString(36).slice(2, 9)
}

export function extOf(fileName) {
  if (!fileName || fileName.lastIndexOf('.') < 0) {
    return ''
  }
  return fileName.slice(fileName.lastIndexOf('.') + 1).toLowerCase()
}

/** 与大模型 SSE/JSON 一致：id 即为网关 sessionId */
export function extractLlmSessionId(data) {
  if (!data || typeof data !== 'object') {
    return null
  }
  if (data.id != null && data.id !== '') {
    return String(data.id)
  }
  if (data.session_id != null && data.session_id !== '') {
    return String(data.session_id)
  }
  if (data.sessionId != null && data.sessionId !== '') {
    return String(data.sessionId)
  }
  return null
}

export function extractAssistantText(data) {
  try {
    const choice = data.choices && data.choices[0]
    const msg = choice && choice.message
    return (msg && msg.content) || ''
  } catch (e) {
    return ''
  }
}

export function contentForLlm(content) {
  if (typeof content === 'string') {
    return content
  }
  if (!Array.isArray(content)) {
    return ''
  }
  return content
}

export function buildUserContentForLlm(text, pendingAttachments) {
  const parts = []
  const imgs = (pendingAttachments || []).filter((a) => a.kind === 'image')
  for (const im of imgs) {
    parts.push({ type: 'image_url', image_url: { url: im.url } })
  }
  const body = (text || '').trim()
  if (body) {
    parts.push({ type: 'text', text: body })
  }
  if (!parts.length) {
    return ''
  }
  if (parts.length === 1 && parts[0].type === 'text') {
    return parts[0].text
  }
  return parts
}

export function buildMessagesForLlm(messages, llmSessionId) {
  if (llmSessionId) {
    for (let i = (messages || []).length - 1; i >= 0; i--) {
      const m = messages[i]
      if (m.senderRole === SENDER_ROLE_USER) {
        let content = m.content
        if (m.msgType === 2 && content) {
          content = [{ type: 'image_url', image_url: { url: mediaUrl(content) } }]
        }
        return [{ role: 'user', content: contentForLlm(content) }]
      }
    }
    return []
  }
  const out = []
  for (const m of messages || []) {
    const role = m.senderRole === SENDER_ROLE_AI ? 'assistant' : 'user'
    let content = m.content
    if (m.msgType === 2 && content) {
      content = [{ type: 'image_url', image_url: { url: mediaUrl(content) } }]
    }
    out.push({ role, content: contentForLlm(content) })
  }
  return out
}

export function resolvePayloadUserContent(payload, draft) {
  if (payload.msgType === 1) {
    return payload.content
  }
  if (payload.msgType === 2) {
    const parts = [{ type: 'image_url', image_url: { url: mediaUrl(payload.content) } }]
    const text = (draft || '').trim()
    if (text) {
      parts.push({ type: 'text', text })
    }
    return parts.length === 1 && parts[0].type === 'text' ? parts[0].text : parts
  }
  return String(payload.content || '')
}

export function buildPersistSendBody(msgType, payload, draftText, pendingAttachments) {
  const body = { msgType: msgType || 1 }
  if (body.msgType === 1) {
    let text =
      (draftText || '').trim() || (payload && payload.content ? String(payload.content).trim() : '')
    if (!text && pendingAttachments && pendingAttachments.length) {
      const img = pendingAttachments.find((a) => a.kind === 'image')
      if (img && img.url) {
        body.msgType = 2
        body.content = img.url
        return body
      }
    }
    body.content = text
  } else {
    body.content = (payload && payload.content) || ''
    if (payload && payload.mediaDuration != null) {
      body.mediaDuration = payload.mediaDuration
    }
  }
  return body
}

export function findLastLocalExchangeIndexes(messages) {
  let userIdx = -1
  let aiIdx = -1
  for (let i = (messages || []).length - 1; i >= 0; i--) {
    const m = messages[i]
    if (!m || !String(m.id).startsWith('m_')) {
      continue
    }
    if (aiIdx < 0 && m.senderRole === SENDER_ROLE_AI) {
      aiIdx = i
    } else if (userIdx < 0 && m.senderRole === SENDER_ROLE_USER) {
      userIdx = i
    }
    if (userIdx >= 0 && aiIdx >= 0) {
      break
    }
  }
  return { userIdx, aiIdx }
}

/**
 * 调用大模型 /v1/chat/completions
 */
export function requestLlmChat(body) {
  const baseUrl = joinLlmUrl('')
  if (!baseUrl) {
    return Promise.reject(new Error('configLlmBase'))
  }
  if (!LLM_API_KEY) {
    return Promise.reject(new Error('configLlmKey'))
  }
  const header = {
    'Content-Type': 'application/json',
    Authorization: 'Bearer ' + LLM_API_KEY
  }
  return new Promise((resolve, reject) => {
    uni.request({
      url: joinLlmUrl('/v1/chat/completions'),
      method: 'POST',
      header,
      data: body,
      timeout: 120000,
      success: (res) => {
        const httpStatus = res.statusCode || 200
        if (httpStatus >= 200 && httpStatus < 300) {
          const data = typeof res.data === 'string' ? JSON.parse(res.data) : res.data
          resolve(data)
          return
        }
        let msg = 'requestFailed'
        try {
          const errBody = typeof res.data === 'string' ? JSON.parse(res.data) : res.data
          msg = (errBody && (errBody.message || errBody.msg)) || msg
        } catch (e) {
          /* ignore */
        }
        reject(new Error(msg))
      },
      fail: (err) => reject(err || new Error('requestFailed'))
    })
  })
}
