// =============================================================================
// 企微IT智能服务台 — H5用户端 API 调用层
// =============================================================================
// 说明：封装会话、消息、审批、下载等与后端 /api/h5/ 交互的 API 方法
// 注意：OAuth2 相关 API 已迁移至 @/api/employee.ts
//   1. 会话相关（当前会话、发送消息、轮询消息、敲桌子招手）
//   2. 审批流程链接
//   3. 软件下载列表
// =============================================================================

import apiClient from '@/api'

// -------------------------------------------------------------------------
// 类型定义
// -------------------------------------------------------------------------

/** 用户信息（兼容旧接口 /h5/user） */
export interface UserInfo {
  /** 员工 ID */
  employee_id: string
  /** 员工姓名 */
  employee_name: string
  /** 部门名称 */
  department: string
  /** 岗位 */
  position: string
  /** 职级 */
  level: string
  /** 是否 VIP 员工 */
  is_vip: boolean
  /** 头像 URL */
  avatar_url: string
}

/** 会话信息 */
export interface ConversationInfo {
  /** 会话 ID */
  conversation_id: string
  /** 员工 ID */
  employee_id: string
  /** 员工姓名（会话发起人） */
  employee_name: string
  /** 会话状态：waiting(排队中) / serving(服务中) / closed(已结单) */
  status: 'waiting' | 'serving' | 'closed'
  /** 坐席 ID（未接入时为空） */
  agent_id: string
  /** 坐席名称（未接入时为空） */
  agent_name: string
  /** 创建时间 */
  created_at: string
  /** 更新时间 */
  updated_at: string
  /** AI 实质性回复计数（满3次可呼叫坐席） */
  ai_substantive_reply_count?: number
  /** 是否可以呼叫人工坐席（AI 回复 >= 3 次） */
  can_call_agent?: boolean
  /** 被邀请参与会话的人员列表（邀请功能 P0-09~P0-11） */
  participants?: ParticipantItem[]
}

/** 消息类型 */
export type MessageType = 'employee' | 'agent' | 'ai' | 'system'

/** 消息内容类型（text/image/file/voice/video/location 等） */
export type MsgContentType = 'text' | 'image' | 'file' | 'voice' | 'video' | 'location'

/** 单条消息 */
export interface Message {
  /** 消息 ID */
  message_id: string
  /** 会话 ID */
  conversation_id: string
  /** 消息类型：employee(员工) / agent(坐席) / ai(AI) / system(系统) */
  message_type: MessageType
  /** 消息内容类型：text/image/file 等 */
  msg_type?: MsgContentType
  /** 消息内容 */
  content: string
  /** 发送者名称 */
  sender_name: string
  /** 创建时间 */
  created_at: string
  /** 图片/文件 URL */
  media_url?: string
  /** 文件名 */
  file_name?: string
  /** 文件大小（字节） */
  file_size?: number
  /** 扩展数据（额外字段，如 pic_url 等） */
  extra_data?: Record<string, any>
  /** 引用回复：被回复的消息 ID */
  reply_to_id?: string
  /** 发送状态：sending(发送中) / sent(已发送) / failed(发送失败) - 用于乐观更新UI */
  status?: 'sending' | 'sent' | 'failed'
}

/** 发送消息请求参数 */
export interface SendMessageRequest {
  /** 消息内容 */
  content: string
  /** 消息内容类型：text/image/file（默认 text） */
  msg_type?: MsgContentType
  /** 图片/文件 URL（非文本消息必填） */
  media_url?: string
  /** 文件名 */
  file_name?: string
  /** 文件大小（字节） */
  file_size?: number
}

/** 轮询消息请求参数 */
export interface PollMessagesParams {
  /** 获取此 ID 之后的消息（增量轮询） */
  after_message_id?: string
}

/** 招手请求参数 */
export interface ShakeRequest {
  /** 员工 ID */
  employee_id: string
  /** 员工姓名 */
  employee_name: string
}

/** 招手响应数据（与后端 h5.py shake 端点一致） */
export interface ShakeResponse {
  /** 趣味话术内容 */
  funny_phrase: string
  /** 会话信息（用于判断是否已接入坐席） */
  conversation: {
    /** 会话状态：queued(排队中) / serving(服务中) / closed(已结单) */
    status: string
  }
}

/** 审批流程链接 */
export interface ApprovalLink {
  /** 链接 ID */
  id: string
  /** 链接标题 */
  title: string
  /** 链接地址 */
  url: string
  /** 分类名称 */
  category: string
  /** 图标（可选） */
  icon?: string
}

/** 软件下载项 */
export interface SoftwareDownload {
  /** 软件 ID */
  id: string
  /** 软件名称 */
  name: string
  /** 版本号 */
  version: string
  /** 下载地址 */
  download_url: string
  /** 分类名称 */
  category: string
  /** 支持平台标签（如 "Windows", "macOS"） */
  platforms: string[]
  /** 图标（可选） */
  icon?: string
}

/** 发送消息响应（含 AI 自动回复） */
export interface SendMessageResponse {
  /** 用户发送的消息 */
  user_message: Message
  /** AI 自动回复消息 */
  ai_reply: Message
  /** 是否为引导类回复（打招呼/呼叫人工），不计入实质回复 */
  is_guidance: boolean
  /** 当前 AI 实质性回复计数 */
  ai_reply_count: number
  /** 是否可以呼叫人工坐席 */
  can_call_agent: boolean
}

// -------------------------------------------------------------------------
// 邀请功能类型（P0-09~P0-11）
// -------------------------------------------------------------------------

/** 参与者信息（与后端 ParticipantInfo 对应） */
export interface ParticipantItem {
  /** 企微员工UserID 或部门ID */
  id: string
  /** 姓名 或 部门名称 */
  name: string
  /** 部门（仅员工类型） */
  department?: string
  /** 类型 — employee（个人）或 department（部门） */
  type?: 'employee' | 'department'
  /** 头像URL（从企微通讯录获取，无头像时为空字符串） */
  avatar?: string
  /** 是否已加入（邀请后、点击加入前为 false） */
  joined?: boolean
  /** 加入时间（ISO 格式） */
  joined_at?: string
}

// -------------------------------------------------------------------------
// 后端字段 → H5前端字段映射
// -------------------------------------------------------------------------
// 根因：后端 MessageResponse 使用 id / sender_type，
//       但 H5 前端 Message 接口使用 message_id / message_type。
//       字段名不一致导致 MessageBubble 无法识别消息类型（全 undefined），
//       Vue :key 也失效（key 全为 undefined），消息无法正常渲染。
// 修复：在 API 层统一映射，保持 H5 组件代码不变。

/**
 * 将后端 MessageResponse 映射为 H5 前端 Message 格式
 * - id → message_id
 * - sender_type → message_type
 * - 其余字段直接透传
 */
function mapMessage(raw: any): Message {
  return {
    message_id: raw.id || raw.message_id || '',
    conversation_id: raw.conversation_id || '',
    message_type: (raw.sender_type || raw.message_type || 'text') as MessageType,
    msg_type: raw.msg_type,
    content: raw.content || '',
    sender_name: raw.sender_name || '',
    created_at: raw.created_at || '',
    media_url: raw.media_url,
    file_name: raw.file_name,
    file_size: raw.file_size,
    extra_data: raw.extra_data,
    reply_to_id: raw.reply_to_id,
  }
}

/**
 * 批量映射后端消息列表为 H5 前端 Message 格式
 */
function mapMessages(rawList: any[]): Message[] {
  return (rawList || []).map(mapMessage)
}

// -------------------------------------------------------------------------
// API 方法
// -------------------------------------------------------------------------
// 注意：响应拦截器返回 response.data（即 {code, data, message} 包装对象）
// API 函数通过 await + response.data 取出业务数据（与原始工作代码一致）
// -------------------------------------------------------------------------

/**
 * 获取当前用户信息（兼容旧接口）
 * 返回当前登录员工的详细信息（姓名、部门、岗位、VIP 状态等）
 * 注意：推荐使用 @/api/employee.ts 中的 getEmployeeInfo() 替代
 * @returns 用户信息对象
 */
export async function getUser(): Promise<UserInfo> {
  const response: any = await apiClient.get('/h5/user')
  return response.data
}

/**
 * 获取当前会话
 * 返回当前员工正在进行的会话，如果无活跃会话则返回 null
 * @returns 会话信息或 null
 */
export async function getCurrentConversation(): Promise<ConversationInfo | null> {
  const response: any = await apiClient.get('/h5/conversations/current')
  return response.data
}

/**
 * 发送消息（含 AI 自动回复）
 * 在当前会话中发送一条消息，后端自动生成 AI 回复
 * @param data 消息内容
 * @returns 包含用户消息和 AI 回复的响应
 */
export async function sendMessage(data: SendMessageRequest): Promise<SendMessageResponse> {
  // 图片/文件消息后端处理可能较慢（AI + Dify），增加超时到30秒
  // 修复截图发送超时Bug：apiClient默认10s不够
  const response: any = await apiClient.post('/h5/conversations/current/messages', data, {
    timeout: 30000,
  })
  // response = {code:0, data: {user_message:..., ai_reply:...}, message:"success"}
  // response.data = 业务数据 {user_message:..., ai_reply:..., ...}
  const raw = response.data
  // 修复字段映射：后端返回 id/sender_type，H5前端期望 message_id/message_type
  return {
    user_message: mapMessage(raw.user_message),
    ai_reply: raw.ai_reply ? mapMessage(raw.ai_reply) : raw.ai_reply,
    is_guidance: raw.is_guidance,
    ai_reply_count: raw.ai_reply_count,
    can_call_agent: raw.can_call_agent,
  }
}

/**
 * 轮询消息
 * 获取当前会话中指定消息 ID 之后的新消息（增量轮询）
 * @param params 轮询参数（after_message_id 用于增量获取）
 * @returns 新消息列表
 */
export async function pollMessages(params?: PollMessagesParams): Promise<Message[]> {
  const response: any = await apiClient.get('/h5/conversations/current/messages/poll', { params })
  // response.data = { items: [...], has_more: bool }
  const data = response.data
  const rawItems = data?.items || data || []
  // 修复字段映射：后端返回 id/sender_type，H5前端期望 message_id/message_type
  return mapMessages(rawItems)
}

/**
 * 摇人 — 一键呼叫 IT 坐席
 * 触发转人工流程，返回趣味话术和会话状态
 * @param data 摇人请求参数（employee_id 必填，employee_name 可选）
 * @returns 摇人响应（包含趣味话术和会话信息）
 */
export async function shake(data: ShakeRequest): Promise<ShakeResponse> {
  const response: any = await apiClient.post('/h5/conversations/current/shake', data)
  return response.data
}

/**
 * 获取审批流程链接列表
 * 返回所有可用的审批流程链接，按分类分组
 * @returns 审批流程链接数组
 */
export async function getApprovalLinks(): Promise<ApprovalLink[]> {
  const response: any = await apiClient.get('/h5/approval-links')
  // response.data = { items: [...] } 或 [...]
  const data = response.data
  return (data?.items || data || []) as ApprovalLink[]
}

// =============================================================================
// 审批流程关键词 API（新增 - 用于关键词触发卡片弹窗）
// =============================================================================

/** 审批关键词响应 */
export interface ApprovalKeyword {
  keyword: string
  template_id: string
  template_name: string
  type: 'jump' | 'api'
}

/**
 * 获取审批关键词列表
 * 用于前端关键词检测，触发卡片弹窗
 * @returns 审批关键词数组
 */
export async function getApprovalKeywords(): Promise<ApprovalKeyword[]> {
  const response: any = await apiClient.get('/approval/keywords')
  return response.data || []
}

/**
 * 生成跳转审批链接
 * @param templateId 模板ID
 * @returns 跳转链接
 */
export async function createApprovalJump(templateId: string): Promise<{ url: string; template_name: string }> {
  const response: any = await apiClient.post('/approval/jump', { template_id: templateId })
  return response.data
}

/**
 * 获取软件下载列表
 * 返回所有可下载的软件列表，按分类分组
 * @returns 软件下载数组
 */
export async function getSoftwareDownloads(): Promise<SoftwareDownload[]> {
  const response: any = await apiClient.get('/h5/software-downloads')
  // response.data = { items: [...] } 或 [...]
  const data = response.data
  return (data?.items || data || []) as SoftwareDownload[]
}

// -------------------------------------------------------------------------
// 邀请功能 API（P0-09~P0-11）
// -------------------------------------------------------------------------
// 注意：H5 专用端点使用 /h5/ 前缀，认证通过 Bearer Token 自动获取 employee_id
// 后端 _get_current_employee 依赖会从 Token 中提取 employee_id，无需前端传递
// --------------------------------------------------------------------------

/**
 * 被邀请人加入会话
 * 通过企微卡片链接点击后调用，后端从 Token 认证获取 employee_id
 *
 * @param conversationId - 会话ID
 * @returns 更新后的会话信息
 */
export async function joinConversation(
  conversationId: string
): Promise<any> {
  const response: any = await apiClient.post(
    `/h5/conversations/${conversationId}/join`
  )
  return response.data
}

/**
 * 参与者主动退出会话
 * 后端从 Token 认证获取 employee_id，无需前端传递
 *
 * @param conversationId - 会话ID
 * @returns 更新后的会话信息
 */
export async function leaveAsParticipant(
  conversationId: string
): Promise<any> {
  const response: any = await apiClient.post(
    `/h5/conversations/${conversationId}/leave-participant`
  )
  return response.data
}

/**
 * 获取会话参与者列表
 * 返回指定会话的所有被邀请参与者信息
 *
 * @param conversationId - 会话ID
 * @returns 参与者列表
 */
export async function getParticipants(
  conversationId: string
): Promise<ParticipantItem[]> {
  const response: any = await apiClient.get(
    `/h5/conversations/${conversationId}/participants`
  )
  const data = response.data
  return data?.participants || []
}
