import { getDashboard } from '../dashboard'

const baseUrl = import.meta.env.VITE_MOSQUITO_API_BASE_URL ?? ''
const apiKey = import.meta.env.VITE_MOSQUITO_API_KEY ?? ''

// 审批状态映射
const mapApprovalStatus = (status: string): '待审批' | '已通过' | '已拒绝' => {
  switch (status) {
    case 'PENDING':
    case 'PROCESSING':
      return '待审批'
    case 'APPROVED':
    case 'COMPLETED':
      return '已通过'
    case 'REJECTED':
    case 'CANCELLED':
      return '已拒绝'
    default:
      return '待审批'
  }
}

// 获取存储的 token（从 localStorage）
const getStoredToken = (): string => {
  if (typeof localStorage !== 'undefined') {
    return localStorage.getItem('mosquito_token') ?? ''
  }
  return ''
}

// 统一的请求头获取（从 localStorage 或环境变量）
const getAuthHeaders = (): Record<string, string> => {
  const token = getStoredToken() || (import.meta.env.VITE_MOSQUITO_USER_TOKEN ?? '')
  return {
    'Content-Type': 'application/json',
    'X-API-Key': apiKey,
    ...(token ? { Authorization: `Bearer ${token}` } : {})
  }
}

// 处理后端响应，兼容多种分页格式
// 支持: {items}, {data}, {content} 三种分页载荷与数组载荷
const processResponse = (data: any): any => {
  if (!data || typeof data !== 'object') {
    return data
  }

  // 如果data是分页对象（有items属性），返回items数组
  if ('items' in data && Array.isArray(data.items)) {
    return data.items
  }
  // 如果data是分页对象（有data属性），返回data数组
  if ('data' in data && Array.isArray(data.data)) {
    return data.data
  }
  // 如果data是分页对象（有content属性），返回content数组
  if ('content' in data && Array.isArray(data.content)) {
    return data.content
  }
  // 如果data是数组，直接返回
  if (Array.isArray(data)) {
    return data
  }
  // 其他情况返回data本身
  return data
}

// 处理分页响应，返回完整分页数据对象
const processPageResponse = (data: any): { items: any[]; total: number; page: number; size: number } | null => {
  if (!data || typeof data !== 'object') {
    return null
  }

  // 提取数组项
  let items: any[] = []
  if ('items' in data && Array.isArray(data.items)) {
    items = data.items
  } else if ('data' in data && Array.isArray(data.data)) {
    items = data.data
  } else if ('content' in data && Array.isArray(data.content)) {
    items = data.content
  } else if (Array.isArray(data)) {
    items = data
  }

  // 兼容后端返回的字段名：totalElements -> total, currentPage -> page
  const total = typeof data.total === 'number' ? data.total
    : typeof data.totalElements === 'number' ? data.totalElements
    : items.length
  const page = typeof data.page === 'number' ? data.page
    : typeof data.currentPage === 'number' ? data.currentPage + 1  // 后端currentPage从0开始
    : 1
  const size = typeof data.size === 'number' ? data.size
    : typeof data.pageSize === 'number' ? data.pageSize
    : items.length

  return {
    items,
    total,
    page,
    size
  }
}

const requestJson = async (url: string) => {
  const response = await fetch(url, {
    headers: getAuthHeaders()
  })
  const payload = await response.json().catch(() => ({}))
  if (!response.ok) {
    throw new Error(payload?.message || '请求失败')
  }
  return processResponse(payload?.data)
}

const requestJsonWithPage = async (url: string) => {
  const response = await fetch(url, {
    headers: getAuthHeaders()
  })
  const payload = await response.json().catch(() => ({}))
  if (!response.ok) {
    throw new Error(payload?.message || '请求失败')
  }
  // 使用processPageResponse处理多种分页格式
  const pageData = processPageResponse(payload?.data)
  if (pageData) {
    return pageData
  }
  // 兼容非分页响应
  return { items: processResponse(payload?.data), total: 0, page: 1, size: 10 }
}

export const apiDataService = {
  async getDashboard() {
    try {
      const data = await getDashboard()
      return {
        updatedAt: data.updatedAt,
        kpis: data.kpis,
        activities: data.activities,
        alerts: data.alerts
      }
    } catch (error) {
      console.error('Failed to fetch dashboard:', error)
      return {
        updatedAt: '刚刚',
        kpis: [],
        activities: [],
        alerts: []
      }
    }
  },
  // 获取活动列表（支持分页和筛选）- 返回完整分页对象
  async getActivities(params?: {
    page?: number
    size?: number
    status?: string
    keyword?: string
    startDate?: string
    endDate?: string
  }) {
    try {
      const queryParams = new URLSearchParams()
      if (params?.page !== undefined) queryParams.append('page', String(params.page))
      if (params?.size !== undefined) queryParams.append('size', String(params.size))
      if (params?.status) queryParams.append('status', params.status)
      if (params?.keyword) queryParams.append('keyword', params.keyword)
      if (params?.startDate) queryParams.append('startDate', params.startDate)
      if (params?.endDate) queryParams.append('endDate', params.endDate)

      const queryString = queryParams.toString()
      const url = queryString
        ? `${baseUrl}/api/v1/activities/admin?${queryString}`
        : `${baseUrl}/api/v1/activities/admin`

      // 使用 requestJsonWithPage 返回完整分页对象 {items,total,page,size}
      return await requestJsonWithPage(url)
    } catch (error) {
      console.error('Failed to fetch activities:', error)
      return { items: [], total: 0, page: 1, size: 10 }
    }
  },
  async getActivityById(id: number) {
    try {
      return await requestJson(`${baseUrl}/api/v1/activities/admin/${id}`)
    } catch (error) {
      console.error('Failed to fetch activity:', error)
      return null
    }
  },

  // 获取活动参与者列表（用于转化明细导出）
  async getActivityParticipants(activityId: number, page = 0, size = 1000) {
    try {
      // 注意：requestJson 内部使用 processResponse 会将分页对象转为数组
      // 所以这里直接使用返回的数组即可
      const result = await requestJson(`${baseUrl}/api/v1/activities/admin/${activityId}/participants?page=${page}&size=${size}`)
      // processResponse 会返回 data.content 数组
      return Array.isArray(result) ? result : []
    } catch (error) {
      console.error('Failed to fetch activity participants:', error)
      return []
    }
  },

  // 获取活动奖励明细（用于奖励导出）
  async getActivityRewards(activityId: number, page = 0, size = 10000) {
    try {
      const result = await requestJson(`${baseUrl}/api/v1/activities/admin/${activityId}/rewards?page=${page}&size=${size}`)
      // processResponse 会返回 data.content 数组
      return Array.isArray(result) ? result : []
    } catch (error) {
      console.error('Failed to fetch activity rewards:', error)
      return []
    }
  },

  // 导出活动参与者 CSV
  async exportActivityParticipants(activityId: number) {
    try {
      const participants = await this.getActivityParticipants(activityId, 0, 10000)
      if (!participants || participants.length === 0) {
        return null
      }
      // 转换为 CSV 格式
      const headers = ['用户ID', '邮箱', '状态', '邀请时间']
      const rows = participants.map((p: any) => [
        p.inviterUserId || '',
        p.email || '',
        p.status || '',
        p.invitedAt ? new Date(p.invitedAt).toLocaleString('zh-CN') : ''
      ])
      return { headers, rows }
    } catch (error) {
      console.error('Failed to export participants:', error)
      throw error
    }
  },

  // 导出活动奖励 CSV
  async exportActivityRewards(activityId: number) {
    try {
      const rewards = await this.getActivityRewards(activityId)
      if (!rewards || rewards.length === 0) {
        return null
      }
      const headers = ['用户ID', '积分', '优惠券码', '优惠券批次', '类型', '状态', '发放时间']
      const rows = rewards.map((r: any) => [
        r.userId || '',
        r.points || '',
        r.couponCode || '',
        r.couponBatchId || '',
        r.type || '',
        r.status || '',
        r.createdAt ? new Date(r.createdAt).toLocaleString('zh-CN') : ''
      ])
      return { headers, rows }
    } catch (error) {
      console.error('Failed to export rewards:', error)
      throw error
    }
  },

  // 获取用户列表（默认返回全部，用于兼容性）
  async getUsers() {
    try {
      return await requestJson(`${baseUrl}/api/v1/users`)
    } catch (error) {
      console.error('Failed to fetch users:', error)
      return []
    }
  },

  // 获取用户分页列表（返回完整分页对象）
  async getUsersPage(params?: {
    page?: number
    size?: number
    keyword?: string
    status?: string
    role?: string
  }) {
    try {
      const queryParams = new URLSearchParams()
      if (params?.page !== undefined) queryParams.append('page', String(params.page))
      if (params?.size !== undefined) queryParams.append('size', String(params.size))
      if (params?.keyword) queryParams.append('keyword', params.keyword)
      if (params?.status) queryParams.append('status', params.status)
      if (params?.role) queryParams.append('role', params.role)

      const queryString = queryParams.toString()
      const url = queryString
        ? `${baseUrl}/api/v1/users?${queryString}`
        : `${baseUrl}/api/v1/users`

      return await requestJsonWithPage(url)
    } catch (error) {
      console.error('Failed to fetch users page:', error)
      return { items: [], total: 0, page: 1, size: 10 }
    }
  },
  async getInvites() {
    try {
      return await requestJson(`${baseUrl}/api/v1/invites`)
    } catch (error) {
      console.error('Failed to fetch invites:', error)
      return []
    }
  },
  async getRoleRequests() {
    try {
      const response = await requestJson(`${baseUrl}/api/v1/approval/pending?userId=0`) as any[]
      // 将后端SysApprovalRecord映射为前端的统一审批模型
      return response.map((record: any) => {
        const bizData = record.bizData ? JSON.parse(record.bizData) : {}
        const bizType = record.bizType || 'ROLE_CHANGE'

        // 根据业务类型生成不同的显示信息
        let title = ''
        let description = ''
        let userId = ''
        let currentValue = ''
        let targetValue = ''
        let reason = bizData.reason || record.comment || ''

        switch (bizType) {
          case 'SENSITIVE_EXPORT':
            title = '敏感数据导出'
            description = `申请导出敏感数据`
            userId = String(record.applicantId || '')
            break
          case 'ROLE_CHANGE':
            userId = String(record.applicantId || bizData.userId || '')
            currentValue = bizData.currentRole || 'viewer'
            targetValue = bizData.targetRole || bizData.role || 'viewer'
            title = '角色变更'
            description = `从 ${currentValue} 变更为 ${targetValue}`
            break
          case 'USER_FREEZE':
            userId = bizData.userId ? String(bizData.userId) : String(record.applicantId || '')
            title = '用户冻结'
            description = `冻结用户: ${bizData.userName || userId}`
            break
          case 'USER_UNFREEZE':
            userId = bizData.userId ? String(bizData.userId) : String(record.applicantId || '')
            title = '用户解冻'
            description = `解冻用户: ${bizData.userName || userId}`
            break
          case 'SYSTEM_CONFIG':
            title = '系统配置变更'
            description = bizData.configKey || '系统配置'
            break
          default:
            title = bizType
            description = JSON.stringify(bizData)
        }

        return {
          id: String(record.id),
          bizType,
          userId,
          title,
          description,
          currentValue,
          targetValue,
          reason,
          status: mapApprovalStatus(record.status),
          requestedAt: record.createdAt || new Date().toISOString(),
          approvedBy: record.currentApproverId ? String(record.currentApproverId) : undefined,
          decisionAt: record.updatedAt,
          rejectReason: bizData.rejectReason
        }
      })
    } catch (error) {
      console.error('Failed to fetch role requests:', error)
      return []
    }
  },
  /**
   * 处理审批（通过/拒绝/转交）
   * @param recordId 审批记录ID
   * @param action 操作类型: APPROVE(通过), REJECT(拒绝), TRANSFER(转交)
   * @param comment 审批意见
   * @deprecated 请使用 approveRecord, rejectRecord, transferRecord 三个独立方法
   */
  async handleApproval(recordId: string, action: string, comment?: string) {
    // 根据action调用对应的独立接口
    switch (action) {
      case 'APPROVE':
        return this.approveRecord(recordId, comment)
      case 'REJECT':
        return this.rejectRecord(recordId, comment)
      case 'TRANSFER':
        return this.transferRecord(recordId, comment)
      default:
        throw new Error(`Unknown action: ${action}`)
    }
  },

  /**
   * 审批通过
   * @param recordId 审批记录ID
   * @param comment 审批意见
   */
  async approveRecord(recordId: string, comment?: string) {
    try {
      const response = await fetch(`${baseUrl}/api/v1/approval/approve`, {
        method: 'POST',
        headers: getAuthHeaders(),
        body: JSON.stringify({
          recordId: recordId,
          comment: comment || ''
        })
      })
      const result = await response.json()
      if (!response.ok) {
        throw new Error(result?.message || '审批通过失败')
      }
      return result?.data ?? true
    } catch (error) {
      console.error('Failed to approve record:', error)
      throw error
    }
  },

  /**
   * 审批拒绝
   * @param recordId 审批记录ID
   * @param comment 拒绝原因
   */
  async rejectRecord(recordId: string, comment?: string) {
    try {
      const response = await fetch(`${baseUrl}/api/v1/approval/reject`, {
        method: 'POST',
        headers: getAuthHeaders(),
        body: JSON.stringify({
          recordId: recordId,
          comment: comment || ''
        })
      })
      const result = await response.json()
      if (!response.ok) {
        throw new Error(result?.message || '审批拒绝失败')
      }
      return result?.data ?? true
    } catch (error) {
      console.error('Failed to reject record:', error)
      throw error
    }
  },

  /**
   * 审批转交
   * @param recordId 审批记录ID
   * @param comment 转交意见
   */
  async transferRecord(recordId: string, comment?: string) {
    try {
      const response = await fetch(`${baseUrl}/api/v1/approval/transfer`, {
        method: 'POST',
        headers: getAuthHeaders(),
        body: JSON.stringify({
          recordId: recordId,
          comment: comment || ''
        })
      })
      const result = await response.json()
      if (!response.ok) {
        throw new Error(result?.message || '审批转交失败')
      }
      return result?.data ?? true
    } catch (error) {
      console.error('Failed to transfer record:', error)
      throw error
    }
  },

  /**
   * 批量处理审批（通过/拒绝/转交）
   * @param recordIds 审批记录ID数组
   * @param action 操作类型: APPROVE(通过), REJECT(拒绝), TRANSFER(转交)
   * @param comment 审批意见
   * @returns 包含 successCount, failCount, results 的对象
   */
  async batchHandleApproval(recordIds: string[], action: string, comment?: string) {
    try {
      const response = await fetch(`${baseUrl}/api/v1/approval/batch-handle`, {
        method: 'POST',
        headers: getAuthHeaders(),
        body: JSON.stringify({
          recordIds: recordIds,
          action: action,
          comment: comment || ''
        })
      })
      const result = await response.json()
      if (!response.ok) {
        throw new Error(result?.message || '批量审批处理失败')
      }
      return result?.data ?? { successCount: 0, failCount: 0, results: [] }
    } catch (error) {
      console.error('Failed to batch handle approval:', error)
      throw error
    }
  },

  /**
   * 转交审批
   * @param recordId 审批记录ID
   * @param transferTo 转交给目标用户ID
   * @param comment 转交意见
   */
  async transferApproval(recordId: string, transferTo: string, comment?: string) {
    try {
      const response = await fetch(`${baseUrl}/api/v1/approval/transfer`, {
        method: 'POST',
        headers: getAuthHeaders(),
        body: JSON.stringify({
          recordId: recordId,
          transferTo: transferTo,
          comment: comment || ''
        })
      })
      const result = await response.json()
      if (!response.ok) {
        throw new Error(result?.message || '转交审批失败')
      }
      return result?.data ?? true
    } catch (error) {
      console.error('Failed to transfer approval:', error)
      throw error
    }
  },
  /**
   * 委托审批
   * @param recordId 审批记录ID
   * @param delegateTo 委托给目标用户ID
   * @param reason 委托原因
   */
  async delegateApproval(recordId: string, delegateTo: string, reason?: string) {
    try {
      const response = await fetch(`${baseUrl}/api/v1/approval/delegate`, {
        method: 'POST',
        headers: getAuthHeaders(),
        body: JSON.stringify({
          recordId: recordId,
          delegateTo: delegateTo,
          reason: reason || ''
        })
      })
      const result = await response.json()
      if (!response.ok) {
        throw new Error(result?.message || '委托审批失败')
      }
      return result?.data ?? true
    } catch (error) {
      console.error('Failed to delegate approval:', error)
      throw error
    }
  },
  async getRewards() {
    try {
      return await requestJson(`${baseUrl}/api/v1/rewards/admin`)
    } catch (error) {
      console.error('Failed to fetch rewards:', error)
      return []
    }
  },
  /**
   * 发放奖励
   */
  async grantReward(id: number) {
    try {
      const response = await fetch(`${baseUrl}/api/v1/rewards/admin/${id}/grant`, {
        method: 'POST',
        headers: getAuthHeaders()
      })
      const result = await response.json()
      if (!response.ok) {
        throw new Error(result?.message || '发放奖励失败')
      }
      return result?.data ?? true
    } catch (error) {
      console.error('Failed to grant reward:', error)
      throw error
    }
  },
  /**
   * 取消/回滚奖励
   */
  async cancelReward(id: number, reason: string) {
    try {
      const response = await fetch(`${baseUrl}/api/v1/rewards/admin/${id}/cancel`, {
        method: 'POST',
        headers: getAuthHeaders(),
        body: JSON.stringify({ reason })
      })
      const result = await response.json()
      if (!response.ok) {
        throw new Error(result?.message || '取消奖励失败')
      }
      return result?.data ?? true
    } catch (error) {
      console.error('Failed to cancel reward:', error)
      throw error
    }
  },
  /**
   * 导出奖励列表（后端流式导出）
   */
  async exportRewards(params?: { status?: string; rewardType?: string; startDate?: string; endDate?: string }) {
    try {
      const searchParams = new URLSearchParams()
      if (params?.status) searchParams.set('status', params.status)
      if (params?.rewardType) searchParams.set('rewardType', params.rewardType)
      if (params?.startDate) searchParams.set('startDate', params.startDate)
      if (params?.endDate) searchParams.set('endDate', params.endDate)

      const response = await fetch(`${baseUrl}/api/v1/rewards/admin/export?${searchParams}`, {
        headers: getAuthHeaders()
      })
      if (!response.ok) {
        throw new Error('导出奖励记录失败')
      }
      return response.blob()
    } catch (error) {
      console.error('Failed to export rewards:', error)
      throw error
    }
  },
  /**
   * 批量发放奖励
   */
  async batchGrantRewards(ids: number[]) {
    try {
      const response = await fetch(`${baseUrl}/api/v1/rewards/admin/batch-grant`, {
        method: 'POST',
        headers: getAuthHeaders(),
        body: JSON.stringify({ ids })
      })
      const result = await response.json()
      if (!response.ok) {
        throw new Error(result?.message || '批量发放失败')
      }
      return result?.data ?? true
    } catch (error) {
      console.error('Failed to batch grant rewards:', error)
      throw error
    }
  },
  async getRiskItems(params?: { page?: number; size?: number }) {
    try {
      const queryParams = new URLSearchParams()
      if (params?.page !== undefined) queryParams.append('page', String(params.page))
      if (params?.size !== undefined) queryParams.append('size', String(params.size))
      const queryString = queryParams.toString()
      const url = queryString ? `${baseUrl}/api/v1/risks/items?${queryString}` : `${baseUrl}/api/v1/risks/items`
      return await requestJsonWithPage(url)
    } catch (error) {
      console.error('Failed to fetch risk items:', error)
      return { items: [], total: 0, page: 1, size: 10 }
    }
  },
  async getRiskAlerts() {
    try {
      return await requestJson(`${baseUrl}/api/v1/risks/alerts`)
    } catch (error) {
      console.error('Failed to fetch risk alerts:', error)
      return []
    }
  },
  async getAuditLogs() {
    try {
      return await requestJson(`${baseUrl}/api/v1/audit/logs`)
    } catch (error) {
      console.error('Failed to fetch audit logs:', error)
      return []
    }
  },
  async getNotifications() {
    try {
      return await requestJson(`${baseUrl}/api/v1/notifications`)
    } catch (error) {
      console.error('Failed to fetch notifications:', error)
      return []
    }
  },
  async addNotification(payload: { title: string; content: string }) {
    try {
      const response = await fetch(`${baseUrl}/api/v1/notifications`, {
        method: 'POST',
        headers: getAuthHeaders(),
        body: JSON.stringify({ title: payload.title, content: payload.content })
      })
      const result = await response.json()
      return result?.data ?? null
    } catch (error) {
      console.error('Failed to add notification:', error)
      return null
    }
  },
  async getConfig() {
    try {
      return await requestJson(`${baseUrl}/api/v1/system/configs`)
    } catch (error) {
      console.error('Failed to fetch config:', error)
      return []
    }
  },
  async getInvitedFriends(activityId: number, userId: number, page: number, size: number) {
    const params = new URLSearchParams({
      activityId: String(activityId),
      userId: String(userId),
      page: String(page),
      size: String(size)
    })
    return requestJson(`${baseUrl}/api/v1/me/invited-friends?${params}`)
  },

  // ========== 邀请管理 ==========

  async createInvite(email: string, role: string) {
    try {
      const response = await fetch(`${baseUrl}/api/v1/invites`, {
        method: 'POST',
        headers: getAuthHeaders(),
        body: JSON.stringify({ email, role })
      })
      const payload = await response.json()
      if (!response.ok) {
        throw new Error(payload?.message || '创建邀请失败')
      }
      return payload?.data
    } catch (error) {
      console.error('Failed to create invite:', error)
      throw error
    }
  },

  async deleteInvite(id: number) {
    try {
      const response = await fetch(`${baseUrl}/api/v1/invites/${id}`, {
        method: 'DELETE',
        headers: getAuthHeaders()
      })
      const payload = await response.json()
      if (!response.ok) {
        throw new Error(payload?.message || '删除邀请失败')
      }
      return true
    } catch (error) {
      console.error('Failed to delete invite:', error)
      throw error
    }
  },

  async resendInvite(id: number) {
    try {
      const response = await fetch(`${baseUrl}/api/v1/invites/${id}/resend`, {
        method: 'POST',
        headers: getAuthHeaders()
      })
      const payload = await response.json()
      if (!response.ok) {
        throw new Error(payload?.message || '重发邀请失败')
      }
      return true
    } catch (error) {
      console.error('Failed to resend invite:', error)
      throw error
    }
  },

  async expireInvite(id: number) {
    try {
      const response = await fetch(`${baseUrl}/api/v1/invites/${id}/expire`, {
        method: 'POST',
        headers: getAuthHeaders()
      })
      const payload = await response.json()
      if (!response.ok) {
        throw new Error(payload?.message || '设置邀请过期失败')
      }
      return true
    } catch (error) {
      console.error('Failed to expire invite:', error)
      throw error
    }
  },

  // ========== 带分页的方法 ==========

  async getRewardsPage(page: number, size: number) {
    try {
      const params = new URLSearchParams({
        page: String(page),
        size: String(size)
      })
      return await requestJsonWithPage(`${baseUrl}/api/v1/rewards/admin?${params}`)
    } catch (error) {
      console.error('Failed to fetch rewards:', error)
      return { items: [], total: 0, page: 1, size: 10 }
    }
  },

  async getRiskAlertsPage(page: number, size: number) {
    try {
      const params = new URLSearchParams({
        page: String(page),
        size: String(size)
      })
      return await requestJsonWithPage(`${baseUrl}/api/v1/risks/alerts?${params}`)
    } catch (error) {
      console.error('Failed to fetch risk alerts:', error)
      return { items: [], total: 0, page: 1, size: 10 }
    }
  },

  async getAuditLogsPage(
    page: number,
    size: number,
    filters?: { keyword?: string; action?: string; module?: string; user?: string; startDate?: string; endDate?: string }
  ) {
    try {
      const params = new URLSearchParams({
        page: String(page),
        size: String(size)
      })
      // 透传筛选参数到后端
      if (filters) {
        if (filters.keyword) {
          params.append('keyword', filters.keyword)
        }
        if (filters.action) {
          params.append('action', filters.action)
        }
        if (filters.module) {
          params.append('module', filters.module)
        }
        if (filters.user) {
          params.append('user', filters.user)
        }
        if (filters.startDate) {
          params.append('startDate', filters.startDate)
        }
        if (filters.endDate) {
          params.append('endDate', filters.endDate)
        }
      }
      return await requestJsonWithPage(`${baseUrl}/api/v1/audit/logs?${params}`)
    } catch (error) {
      console.error('Failed to fetch audit logs:', error)
      return { items: [], total: 0, page: 1, size: 10 }
    }
  },

  async getNotificationsPage(page: number, size: number, filters?: { type?: string; isRead?: boolean; keyword?: string }) {
    try {
      const params = new URLSearchParams({
        page: String(page),
        size: String(size)
      })
      // 透传筛选参数到后端
      if (filters) {
        if (filters.type) {
          params.append('type', filters.type)
        }
        if (filters.isRead !== undefined && filters.isRead !== null) {
          params.append('isRead', String(filters.isRead))
        }
        if (filters.keyword) {
          params.append('keyword', filters.keyword)
        }
      }
      return await requestJsonWithPage(`${baseUrl}/api/v1/notifications?${params}`)
    } catch (error) {
      console.error('Failed to fetch notifications:', error)
      return { items: [], total: 0, page: 1, size: 10 }
    }
  },

  async markNotificationRead(id: number) {
    try {
      const response = await fetch(`${baseUrl}/api/v1/notifications/${id}/read`, {
        method: 'POST',
        headers: getAuthHeaders()
      })
      const payload = await response.json()
      if (!response.ok) {
        throw new Error(payload?.message || '标记已读失败')
      }
      return true
    } catch (error) {
      console.error('Failed to mark notification read:', error)
      throw error
    }
  },

  async markAllNotificationsRead() {
    try {
      const response = await fetch(`${baseUrl}/api/v1/notifications/read-all`, {
        method: 'POST',
        headers: getAuthHeaders()
      })
      const payload = await response.json()
      if (!response.ok) {
        throw new Error(payload?.message || '标记全部已读失败')
      }
      return true
    } catch (error) {
      console.error('Failed to mark all notifications read:', error)
      throw error
    }
  },

  async batchMarkNotificationsRead(ids: number[]) {
    try {
      const response = await fetch(`${baseUrl}/api/v1/notifications/batch-read`, {
        method: 'POST',
        headers: getAuthHeaders(),
        body: JSON.stringify(ids)
      })
      const payload = await response.json()
      if (!response.ok) {
        throw new Error(payload?.message || '批量标记已读失败')
      }
      return payload?.data ?? true
    } catch (error) {
      console.error('Failed to batch mark notifications read:', error)
      throw error
    }
  },

  async exportAuditLogs(keyword?: string, operation?: string, user?: string) {
    try {
      const params = new URLSearchParams()
      if (keyword) params.append('keyword', keyword)
      if (operation) params.append('operation', operation)
      if (user) params.append('user', user)

      const response = await fetch(`${baseUrl}/api/v1/audit/logs/export?${params}`, {
        method: 'GET',
        headers: getAuthHeaders()
      })
      if (!response.ok) {
        throw new Error('导出审计日志失败')
      }
      // 返回blob用于下载
      return await response.blob()
    } catch (error) {
      console.error('Failed to export audit logs:', error)
      throw error
    }
  },

  // ========== 风控规则 CRUD ==========
  async createRiskRule(rule: { type: string; target: string; status: string }) {
    try {
      const response = await fetch(`${baseUrl}/api/v1/risks/rules`, {
        method: 'POST',
        headers: getAuthHeaders(),
        body: JSON.stringify(rule)
      })
      const payload = await response.json()
      if (!response.ok) {
        throw new Error(payload?.message || '创建风控规则失败')
      }
      return payload?.data ?? true
    } catch (error) {
      console.error('Failed to create risk rule:', error)
      throw error
    }
  },

  async updateRiskRule(id: string, rule: { type: string; target: string; status: string }) {
    try {
      const response = await fetch(`${baseUrl}/api/v1/risks/rules/${id}`, {
        method: 'PUT',
        headers: getAuthHeaders(),
        body: JSON.stringify(rule)
      })
      const payload = await response.json()
      if (!response.ok) {
        throw new Error(payload?.message || '更新风控规则失败')
      }
      return payload?.data ?? true
    } catch (error) {
      console.error('Failed to update risk rule:', error)
      throw error
    }
  },

  async toggleRiskRule(id: string, enabled: boolean = true) {
    try {
      const response = await fetch(`${baseUrl}/api/v1/risks/rules/${id}/toggle`, {
        method: 'POST',
        headers: {
          ...getAuthHeaders(),
          'Content-Type': 'application/json'
        },
        body: JSON.stringify({ enabled })
      })
      const payload = await response.json()
      if (!response.ok) {
        throw new Error(payload?.message || '切换风控规则状态失败')
      }
      return payload?.data ?? true
    } catch (error) {
      console.error('Failed to toggle risk rule:', error)
      throw error
    }
  },

  async handleRiskAlert(id: string, action: 'handle' | 'close', remark?: string) {
    try {
      // 后端只支持 /alerts/{id}/handle，close也使用handle接口
      const endpoint = action === 'close' ? 'handle' : action
      const response = await fetch(`${baseUrl}/api/v1/risks/alerts/${id}/${endpoint}`, {
        method: 'POST',
        headers: {
          ...getAuthHeaders(),
          'Content-Type': 'application/json'
        },
        body: JSON.stringify({
          action: action,
          remark: remark || ''
        })
      })
      const payload = await response.json()
      if (!response.ok) {
        throw new Error(payload?.message || '处理风险告警失败')
      }
      return payload?.data ?? true
    } catch (error) {
      console.error('Failed to handle risk alert:', error)
      throw error
    }
  },

  // ========== 审批中心 ==========
  /**
   * 获取已审批记录
   */
  async getProcessedApprovals(params?: {
    page?: number
    size?: number
    keyword?: string
  }) {
    try {
      const queryParams = new URLSearchParams()
      if (params?.page !== undefined) queryParams.append('page', String(params.page))
      if (params?.size !== undefined) queryParams.append('size', String(params.size))
      if (params?.keyword) queryParams.append('keyword', params.keyword)
      // userId=0 表示当前用户
      queryParams.append('userId', '0')

      const queryString = queryParams.toString()
      const url = `${baseUrl}/api/v1/approval/processed?${queryString}`

      return await requestJsonWithPage(url)
    } catch (error) {
      console.error('Failed to fetch processed approvals:', error)
      return { items: [], total: 0, page: 1, size: 10 }
    }
  },

  /**
   * 获取我提交的审批
   */
  async getMyApprovals(params?: {
    page?: number
    size?: number
    keyword?: string
  }) {
    try {
      const queryParams = new URLSearchParams()
      if (params?.page !== undefined) queryParams.append('page', String(params.page))
      if (params?.size !== undefined) queryParams.append('size', String(params.size))
      if (params?.keyword) queryParams.append('keyword', params.keyword)
      // userId=0 表示当前用户
      queryParams.append('userId', '0')

      const queryString = queryParams.toString()
      const url = `${baseUrl}/api/v1/approval/my?${queryString}`

      return await requestJsonWithPage(url)
    } catch (error) {
      console.error('Failed to fetch my approvals:', error)
      return { items: [], total: 0, page: 1, size: 10 }
    }
  },

  async batchHandleRiskAlerts(ids: string[]) {
    try {
      // 后端期望 { ids: [...] } 格式
      const response = await fetch(`${baseUrl}/api/v1/risks/alerts/batch-handle`, {
        method: 'POST',
        headers: getAuthHeaders(),
        body: JSON.stringify({ ids: ids })
      })
      const payload = await response.json()
      if (!response.ok) {
        throw new Error(payload?.message || '批量处理风险告警失败')
      }
      return payload?.data ?? true
    } catch (error) {
      console.error('Failed to batch handle risk alerts:', error)
      throw error
    }
  },

  // ========== 敏感导出审批 ==========
  /**
   * 提交敏感导出审批申请
   */
  async submitSensitiveExportApproval(reason: string) {
    try {
      const response = await fetch(`${baseUrl}/api/v1/approval/submit-by-event`, {
        method: 'POST',
        headers: getAuthHeaders(),
        body: JSON.stringify({
          triggerEvent: 'SENSITIVE_EXPORT',
          bizType: 'SENSITIVE_EXPORT',
          title: '敏感数据导出申请',
          applyReason: reason
        })
      })
      const payload = await response.json()
      if (!response.ok) {
        throw new Error(payload?.message || '提交审批失败')
      }
      return payload?.data ?? true
    } catch (error) {
      console.error('Failed to submit sensitive export approval:', error)
      throw error
    }
  },

  /**
   * 检查当前用户是否有已批准的敏感导出审批
   */
  async hasApprovedSensitiveExport() {
    try {
      const response = await fetch(`${baseUrl}/api/v1/approval/has-export-approval`, {
        method: 'GET',
        headers: getAuthHeaders()
      })
      const payload = await response.json()
      if (!response.ok) {
        return false
      }
      return payload?.data === true
    } catch (error) {
      console.error('Failed to check export approval:', error)
      return false
    }
  },

  /**
   * 导出用户（带敏感数据）
   */
  async exportUsersWithSensitive() {
    try {
      const response = await fetch(`${baseUrl}/api/v1/users/export`, {
        method: 'GET',
        headers: getAuthHeaders()
      })
      if (response.status === 409) {
        // 需要审批
        throw new Error('NEED_APPROVAL')
      }
      if (!response.ok) {
        const payload = await response.json().catch(() => ({}))
        throw new Error(payload?.message || '导出失败')
      }
      return response.blob()
    } catch (error) {
      console.error('Failed to export users:', error)
      throw error
    }
  }
}
