import { reportServerError } from '~/lib/server-error-logging'
import { useChatAccountsStore } from '~/stores/chatAccounts'

const chatContactsListCache = new Map()
const CHAT_CONTACTS_LIST_CACHE_TTL_MS = 3000

// API请求组合式函数
export const useApi = () => {
  const baseURL = useApiBase()
  const chatAccounts = useChatAccountsStore()

  const responseDetailMessage = (response, fallback = '') => {
    const detail = response?._data?.detail
    if (typeof detail === 'string') return detail.trim() || fallback
    if (detail && typeof detail === 'object') {
      return String(detail.message || detail.detail || detail.code || '').trim() || fallback
    }
    return fallback
  }
  
  // 基础请求函数
  const request = async (url, options = {}) => {
    try {
      const response = await $fetch(url, {
        baseURL,
        ...options,
        async onResponseError({ response }) {
          if (response.status === 400) {
            throw new Error(responseDetailMessage(response, '请求参数错误'))
          } else if (response.status >= 500) {
            const backendDetail = responseDetailMessage(response)
            const message = backendDetail || '服务器错误，请稍后重试'
            await reportServerError({
              status: response.status,
              method: options?.method || 'GET',
              requestUrl: url,
              message,
              backendDetail,
              source: 'useApi',
              apiBase: baseURL,
            })
            throw new Error(message)
          }
        }
      })
      chatAccounts.applySourceResponse(response)
      return response
    } catch (error) {
      console.error('API请求错误:', error)
      throw error
    }
  }
  
  // 微信检测API
  const detectWechat = async (params = {}) => {
    const query = new URLSearchParams()
    if (params && params.data_root_path) {
      query.set('data_root_path', params.data_root_path)
    }
    const url = '/wechat-detection' + (query.toString() ? `?${query.toString()}` : '')
    return await request(url)
  }
  
  // 检测当前登录账号API
  const detectCurrentAccount = async (params = {}) => {
    const query = new URLSearchParams()
    if (params && params.data_root_path) {
      query.set('data_root_path', params.data_root_path)
    }
    const url = '/current-account' + (query.toString() ? `?${query.toString()}` : '')
    return await request(url)
  }
  
  // 数据库解密API
  const decryptDatabase = async (data) => {
    return await request('/decrypt', {
      method: 'POST',
      body: data
    })
  }

  // 导入预览API
  const importDecryptedPreview = async (data) => {
    return await request('/import_decrypted/preview', {
      method: 'POST',
      body: data
    })
  }

  // 导入已解密目录API
  const importDecrypted = async (data) => {
    return await request('/import_decrypted', {
      method: 'POST',
      body: data
    })
  }
  
  // 健康检查API
  const healthCheck = async () => {
    return await request('/health')
  }

  const getPlatformCapabilities = async () => {
    return await request('/system/platform')
  }

  const listChatAccounts = async () => {
    return await request('/chat/accounts')
  }

  const getChatAccountInfo = async (params = {}) => {
    const query = new URLSearchParams()
    if (params && params.account) query.set('account', params.account)
    const url = '/chat/account_info' + (query.toString() ? `?${query.toString()}` : '')
    return await request(url)
  }

  const deleteChatAccount = async (params = {}) => {
    const account = String(params?.account || '').trim()
    if (!account) throw new Error('Missing account')
    const query = new URLSearchParams()
    query.set('account', account)
    const url = '/chat/account' + (query.toString() ? `?${query.toString()}` : '')
    return await request(url, { method: 'DELETE' })
  }

  const listChatSessions = async (params = {}) => {
    const query = new URLSearchParams()
    if (params && params.account) query.set('account', params.account)
    if (params && params.limit != null) query.set('limit', String(params.limit))
    if (params && params.include_hidden != null) query.set('include_hidden', String(!!params.include_hidden))
    if (params && params.include_official != null) query.set('include_official', String(!!params.include_official))
    if (params && params.source) query.set('source', params.source)
    const url = '/chat/sessions' + (query.toString() ? `?${query.toString()}` : '')
    return await request(url)
  }

  const listChatMessages = async (params = {}) => {
    const query = new URLSearchParams()
    if (params && params.account) query.set('account', params.account)
    if (params && params.username) query.set('username', params.username)
    if (params && params.limit != null) query.set('limit', String(params.limit))
    if (params && params.offset != null) query.set('offset', String(params.offset))
    if (params && params.order) query.set('order', params.order)
    if (params && params.render_types) query.set('render_types', params.render_types)
    if (params && params.filter_mode) query.set('filter_mode', params.filter_mode)
    if (params && params.scan_offset != null) query.set('scan_offset', String(params.scan_offset))
    if (params && params.scan_limit != null) query.set('scan_limit', String(params.scan_limit))
    if (params && params.source) query.set('source', params.source)
    const url = '/chat/messages' + (query.toString() ? `?${query.toString()}` : '')
    return await request(url)
  }

  const getChatMessageRaw = async (params = {}) => {
    const query = new URLSearchParams()
    if (params && params.account) query.set('account', params.account)
    if (params && params.username) query.set('username', params.username)
    if (params && params.message_id) query.set('message_id', params.message_id)
    const url = '/chat/messages/raw' + (query.toString() ? `?${query.toString()}` : '')
    return await request(url)
  }

  const editChatMessage = async (payload = {}) => {
    return await request('/chat/messages/edit', {
      method: 'POST',
      body: payload
    })
  }

  const repairChatMessageSender = async (payload = {}) => {
    return await request('/chat/messages/repair_sender', {
      method: 'POST',
      body: payload
    })
  }

  // Flip message direction in the WeChat client by swapping packed_info_data (unsafe, but undoable via reset).
  const flipChatMessageDirection = async (payload = {}) => {
    return await request('/chat/messages/flip_direction', {
      method: 'POST',
      body: payload
    })
  }

  const listChatEditedSessions = async (params = {}) => {
    const query = new URLSearchParams()
    if (params && params.account) query.set('account', params.account)
    const url = '/chat/edits/sessions' + (query.toString() ? `?${query.toString()}` : '')
    return await request(url)
  }

  const listChatEditedMessages = async (params = {}) => {
    const query = new URLSearchParams()
    if (params && params.account) query.set('account', params.account)
    if (params && params.username) query.set('username', params.username)
    const url = '/chat/edits/messages' + (query.toString() ? `?${query.toString()}` : '')
    return await request(url)
  }

  const getChatEditStatus = async (params = {}) => {
    const query = new URLSearchParams()
    if (params && params.account) query.set('account', params.account)
    if (params && params.username) query.set('username', params.username)
    if (params && params.message_id) query.set('message_id', params.message_id)
    const url = '/chat/edits/message_status' + (query.toString() ? `?${query.toString()}` : '')
    return await request(url)
  }

  const resetChatEditedMessage = async (payload = {}) => {
    return await request('/chat/edits/reset_message', {
      method: 'POST',
      body: payload
    })
  }

  const resetChatEditedSession = async (payload = {}) => {
    return await request('/chat/edits/reset_session', {
      method: 'POST',
      body: payload
    })
  }

  const getChatRealtimeStatus = async (params = {}) => {
    const query = new URLSearchParams()
    if (params && params.account) query.set('account', params.account)
    const url = '/chat/realtime/status' + (query.toString() ? `?${query.toString()}` : '')
    return await request(url)
  }

  const syncChatRealtimeMessages = async (params = {}) => {
    const query = new URLSearchParams()
    if (params && params.account) query.set('account', params.account)
    if (params && params.username) query.set('username', params.username)
    if (params && params.max_scan != null) query.set('max_scan', String(params.max_scan))
    if (params && params.backfill_limit != null) query.set('backfill_limit', String(params.backfill_limit))
    const url = '/chat/realtime/sync' + (query.toString() ? `?${query.toString()}` : '')
    return await request(url, { method: 'POST' })
  }

  const syncChatRealtimeAll = async (params = {}) => {
    const query = new URLSearchParams()
    if (params && params.account) query.set('account', params.account)
    if (params && params.max_scan != null) query.set('max_scan', String(params.max_scan))
    if (params && params.priority_username) query.set('priority_username', params.priority_username)
    if (params && params.priority_max_scan != null) query.set('priority_max_scan', String(params.priority_max_scan))
    if (params && params.include_hidden != null) query.set('include_hidden', String(!!params.include_hidden))
    if (params && params.include_official != null) query.set('include_official', String(!!params.include_official))
    if (params && params.only_official != null) query.set('only_official', String(!!params.only_official))
    if (params && params.backfill_limit != null) query.set('backfill_limit', String(params.backfill_limit))
    const url = '/chat/realtime/sync_all' + (query.toString() ? `?${query.toString()}` : '')
    return await request(url, { method: 'POST' })
  }

  const searchChatMessages = async (params = {}) => {
    const query = new URLSearchParams()
    if (params && params.account) query.set('account', params.account)
    if (params && params.q) query.set('q', params.q)
    if (params && params.username) query.set('username', params.username)
    if (params && params.sender) query.set('sender', params.sender)
    if (params && params.session_type) query.set('session_type', params.session_type)
    if (params && params.limit != null) query.set('limit', String(params.limit))
    if (params && params.offset != null) query.set('offset', String(params.offset))
    if (params && params.start_time != null) query.set('start_time', String(params.start_time))
    if (params && params.end_time != null) query.set('end_time', String(params.end_time))
    if (params && params.render_types) query.set('render_types', params.render_types)
    if (params && params.include_hidden != null) query.set('include_hidden', String(!!params.include_hidden))
    if (params && params.include_official != null) query.set('include_official', String(!!params.include_official))
    if (params && params.session_limit != null) query.set('session_limit', String(params.session_limit))
    if (params && params.per_chat_scan != null) query.set('per_chat_scan', String(params.per_chat_scan))
    if (params && params.scan_limit != null) query.set('scan_limit', String(params.scan_limit))
    if (params && params.source) query.set('source', params.source)
    const url = '/chat/search' + (query.toString() ? `?${query.toString()}` : '')
    return await request(url)
  }

  const listChatSearchSenders = async (params = {}) => {
    const query = new URLSearchParams()
    if (params && params.account) query.set('account', params.account)
    if (params && params.username) query.set('username', params.username)
    if (params && params.session_type) query.set('session_type', params.session_type)
    if (params && params.limit != null) query.set('limit', String(params.limit))
    if (params && params.q) query.set('q', params.q)
    if (params && params.message_q) query.set('message_q', params.message_q)
    if (params && params.start_time != null) query.set('start_time', String(params.start_time))
    if (params && params.end_time != null) query.set('end_time', String(params.end_time))
    if (params && params.render_types) query.set('render_types', params.render_types)
    if (params && params.include_hidden != null) query.set('include_hidden', String(!!params.include_hidden))
    if (params && params.include_official != null) query.set('include_official', String(!!params.include_official))
    if (params && params.source) query.set('source', params.source)
    const url = '/chat/search-index/senders' + (query.toString() ? `?${query.toString()}` : '')
    return await request(url)
  }

  const getChatSearchIndexStatus = async (params = {}) => {
    const query = new URLSearchParams()
    if (params && params.account) query.set('account', params.account)
    if (params && params.source) query.set('source', params.source)
    const url = '/chat/search-index/status' + (query.toString() ? `?${query.toString()}` : '')
    return await request(url)
  }

  const buildChatSearchIndex = async (params = {}) => {
    const query = new URLSearchParams()
    if (params && params.account) query.set('account', params.account)
    if (params && params.rebuild != null) query.set('rebuild', String(!!params.rebuild))
    if (params && params.source) query.set('source', params.source)
    const url = '/chat/search-index/build' + (query.toString() ? `?${query.toString()}` : '')
    return await request(url, { method: 'POST' })
  }


  const getChatMessagesAround = async (params = {}) => {
    const query = new URLSearchParams()
    if (params && params.account) query.set('account', params.account)
    if (params && params.username) query.set('username', params.username)
    if (params && params.anchor_id) query.set('anchor_id', params.anchor_id)
    if (params && params.before != null) query.set('before', String(params.before))
    if (params && params.after != null) query.set('after', String(params.after))
    if (params && params.source) query.set('source', params.source)
    const url = '/chat/messages/around' + (query.toString() ? `?${query.toString()}` : '')
    return await request(url)
  }

  // 聊天记录日历热力图：某月每日消息数
  const getChatMessageDailyCounts = async (params = {}) => {
    const query = new URLSearchParams()
    if (params && params.account) query.set('account', params.account)
    if (params && params.username) query.set('username', params.username)
    if (params && params.year != null) query.set('year', String(params.year))
    if (params && params.month != null) query.set('month', String(params.month))
    if (params && params.source) query.set('source', params.source)
    const url = '/chat/messages/daily_counts' + (query.toString() ? `?${query.toString()}` : '')
    return await request(url)
  }

  // 聊天记录定位锚点：某日第一条 / 会话最早一条
  const getChatMessageAnchor = async (params = {}) => {
    const query = new URLSearchParams()
    if (params && params.account) query.set('account', params.account)
    if (params && params.username) query.set('username', params.username)
    if (params && params.kind) query.set('kind', String(params.kind))
    if (params && params.date) query.set('date', String(params.date))
    if (params && params.source) query.set('source', params.source)
    const url = '/chat/messages/anchor' + (query.toString() ? `?${query.toString()}` : '')
    return await request(url)
  }

  // 解析嵌套合并转发聊天记录（通过 server_id）
  const resolveNestedChatHistory = async (params = {}) => {
    const query = new URLSearchParams()
    if (params && params.account) query.set('account', params.account)
    if (params && params.server_id != null) query.set('server_id', String(params.server_id))
    const url = '/chat/chat_history/resolve' + (query.toString() ? `?${query.toString()}` : '')
    return await request(url)
  }

  // 解析卡片/小程序等 App 消息（通过 server_id）
  const resolveAppMsg = async (params = {}) => {
    const query = new URLSearchParams()
    if (params && params.account) query.set('account', params.account)
    if (params && params.server_id != null) query.set('server_id', String(params.server_id))
    const url = '/chat/appmsg/resolve' + (query.toString() ? `?${query.toString()}` : '')
    return await request(url)
  }

  // 朋友圈时间线
  const listSnsTimeline = async (params = {}) => {
    const query = new URLSearchParams()
    if (params && params.account) query.set('account', params.account)
    if (params && params.limit != null) query.set('limit', String(params.limit))
    if (params && params.offset != null) query.set('offset', String(params.offset))
    if (params && params.usernames && Array.isArray(params.usernames) && params.usernames.length > 0) {
      query.set('usernames', params.usernames.join(','))
    } else if (params && params.usernames && typeof params.usernames === 'string') {
      query.set('usernames', params.usernames)
    }
    if (params && params.keyword) query.set('keyword', params.keyword)
    if (params && params.source) query.set('source', params.source)
    const url = '/sns/timeline' + (query.toString() ? `?${query.toString()}` : '')
    return await request(url)
  }

  // 朋友圈联系人列表（按发圈数统计）
  const listSnsUsers = async (params = {}) => {
    const query = new URLSearchParams()
    if (params && params.account) query.set('account', params.account)
    if (params && params.keyword) query.set('keyword', String(params.keyword))
    if (params && params.limit != null) query.set('limit', String(params.limit))
    const url = '/sns/users' + (query.toString() ? `?${query.toString()}` : '')
    return await request(url)
  }

  const openChatMediaFolder = async (params = {}) => {
    const query = new URLSearchParams()
    if (params && params.account) query.set('account', params.account)
    if (params && params.username) query.set('username', params.username)
    if (params && params.kind) query.set('kind', params.kind)
    if (params && params.md5) query.set('md5', params.md5)
    if (params && params.file_id) query.set('file_id', params.file_id)
    if (params && params.server_id != null) query.set('server_id', String(params.server_id))
    const url = '/chat/media/open_folder' + (query.toString() ? `?${query.toString()}` : '')
    return await request(url, { method: 'POST' })
  }

  const downloadChatEmoji = async (data = {}) => {
    return await request('/chat/media/emoji/download', {
      method: 'POST',
      body: {
        account: data.account || null,
        md5: data.md5 || '',
        emoji_url: data.emoji_url || '',
        force: !!data.force
      }
    })
  }

  // 保存图片解密密钥
  const saveMediaKeys = async (params = {}) => {
    return await request('/media/keys', {
      method: 'POST',
      body: {
        account: params.account || null,
        xor_key: params.xor_key || '',
        aes_key: params.aes_key || null
      }
    })
  }

  // 获取已保存的密钥（数据库密钥 + 图片密钥）
  const getSavedKeys = async (params = {}) => {
    const query = new URLSearchParams()
    if (params && params.account) query.set('account', params.account)
    if (params && params.db_storage_path) query.set('db_storage_path', params.db_storage_path)
    const url = '/keys' + (query.toString() ? `?${query.toString()}` : '')
    return await request(url)
  }

  // 批量解密所有图片
  const decryptAllMedia = async (params = {}) => {
    return await request('/media/decrypt_all', {
      method: 'POST',
      body: {
        account: params.account || null,
        xor_key: params.xor_key || null,
        aes_key: params.aes_key || null
      }
    })
  }

  // 聊天记录导出（离线zip）
  const createChatExport = async (data = {}) => {
    return await request('/chat/exports', {
      method: 'POST',
      body: {
        account: data.account || null,
        source: data.source || 'auto',
        scope: data.scope || 'selected',
        usernames: Array.isArray(data.usernames) ? data.usernames : [],
        format: data.format || 'json',
        start_time: data.start_time != null ? Number(data.start_time) : null,
        end_time: data.end_time != null ? Number(data.end_time) : null,
        include_hidden: !!data.include_hidden,
        include_official: !!data.include_official,
        message_types: Array.isArray(data.message_types) ? data.message_types : [],
        include_media: data.include_media == null ? true : !!data.include_media,
        media_kinds: Array.isArray(data.media_kinds) ? data.media_kinds : ['image', 'emoji', 'video', 'video_thumb', 'voice', 'file'],
        output_dir: data.output_dir == null ? null : String(data.output_dir || '').trim(),
        allow_process_key_extract: !!data.allow_process_key_extract,
        download_remote_media: !!data.download_remote_media,
        html_page_size: data.html_page_size != null ? Number(data.html_page_size) : 1000,
        privacy_mode: !!data.privacy_mode,
        file_name: data.file_name || null
      }
    })
  }

  const getChatExport = async (exportId) => {
    if (!exportId) throw new Error('Missing exportId')
    return await request(`/chat/exports/${encodeURIComponent(String(exportId))}`)
  }

  const listChatExports = async () => {
    return await request('/chat/exports')
  }

  const getChatExportTargets = async (params = {}) => {
    const query = new URLSearchParams()
    if (params && params.account) query.set('account', params.account)
    if (params && params.include_hidden != null) query.set('include_hidden', String(!!params.include_hidden))
    if (params && params.include_official != null) query.set('include_official', String(!!params.include_official))
    if (params && params.source) query.set('source', params.source)
    const url = '/chat/exports/targets' + (query.toString() ? `?${query.toString()}` : '')
    return await request(url)
  }

  const cancelChatExport = async (exportId) => {
    if (!exportId) throw new Error('Missing exportId')
    return await request(`/chat/exports/${encodeURIComponent(String(exportId))}`, { method: 'DELETE' })
  }

  // 朋友圈导出（离线 ZIP，支持 HTML / JSON / TXT）
  const createSnsExport = async (data = {}) => {
    return await request('/sns/exports', {
      method: 'POST',
      body: {
        account: data.account || null,
        scope: data.scope || 'selected',
        usernames: Array.isArray(data.usernames) ? data.usernames : [],
        format: data.format || 'html',
        use_cache: data.use_cache == null ? true : !!data.use_cache,
        output_dir: data.output_dir == null ? null : String(data.output_dir || '').trim(),
        file_name: data.file_name || null
      }
    })
  }

  const getSnsExport = async (exportId) => {
    if (!exportId) throw new Error('Missing exportId')
    return await request(`/sns/exports/${encodeURIComponent(String(exportId))}`)
  }

  const cancelSnsExport = async (exportId) => {
    if (!exportId) throw new Error('Missing exportId')
    return await request(`/sns/exports/${encodeURIComponent(String(exportId))}`, { method: 'DELETE' })
  }

  // 联系人
  const listChatContacts = async (params = {}) => {
    const query = new URLSearchParams()
    if (params && params.account) query.set('account', params.account)
    if (params && params.source) query.set('source', params.source)
    if (params && params.keyword) query.set('keyword', params.keyword)
    if (params && params.include_friends != null) query.set('include_friends', String(!!params.include_friends))
    if (params && params.include_groups != null) query.set('include_groups', String(!!params.include_groups))
    if (params && params.include_officials != null) query.set('include_officials', String(!!params.include_officials))
    if (params && params.include_official_subscriptions != null) query.set('include_official_subscriptions', String(!!params.include_official_subscriptions))
    if (params && params.include_official_services != null) query.set('include_official_services', String(!!params.include_official_services))
    if (params && params.include_former_friends != null) query.set('include_former_friends', String(!!params.include_former_friends))
    if (params && params.include_blocked != null) query.set('include_blocked', String(!!params.include_blocked))
    const url = '/chat/contacts' + (query.toString() ? `?${query.toString()}` : '')
    const cacheKey = `${baseURL}::${url}`
    const now = Date.now()
    const cached = chatContactsListCache.get(cacheKey)
    if (!params?.refresh && cached && now - cached.updatedAt < CHAT_CONTACTS_LIST_CACHE_TTL_MS) {
      if (cached.promise) return await cached.promise
      return cached.data
    }
    const promise = request(url)
    chatContactsListCache.set(cacheKey, { updatedAt: now, promise })
    let data
    try {
      data = await promise
    } catch (error) {
      chatContactsListCache.delete(cacheKey)
      throw error
    }
    chatContactsListCache.set(cacheKey, { updatedAt: Date.now(), data })
    if (chatContactsListCache.size > 24) {
      const firstKey = chatContactsListCache.keys().next().value
      if (firstKey) chatContactsListCache.delete(firstKey)
    }
    return data
  }

  const getChatContactProfile = async (params = {}) => {
    const query = new URLSearchParams()
    if (params && params.account) query.set('account', params.account)
    if (params && params.source) query.set('source', params.source)
    if (params && params.username) query.set('username', params.username)
    const url = '/chat/contacts/profile' + (query.toString() ? `?${query.toString()}` : '')
    return await request(url)
  }

  const exportChatContacts = async (payload = {}) => {
    return await request('/chat/contacts/export', {
      method: 'POST',
      body: {
        account: payload.account || null,
        source: payload.source || 'auto',
        output_dir: payload.output_dir || '',
        format: payload.format || 'json',
        include_avatar_link: payload.include_avatar_link == null ? true : !!payload.include_avatar_link,
        keyword: payload.keyword || null,
        contact_types: {
          friends: payload?.contact_types?.friends == null ? true : !!payload.contact_types.friends,
          groups: payload?.contact_types?.groups == null ? true : !!payload.contact_types.groups,
          officials: payload?.contact_types?.officials == null ? true : !!payload.contact_types.officials,
          official_subscriptions: payload?.contact_types?.official_subscriptions == null ? null : !!payload.contact_types.official_subscriptions,
          official_services: payload?.contact_types?.official_services == null ? null : !!payload.contact_types.official_services,
          former_friends: payload?.contact_types?.former_friends == null ? false : !!payload.contact_types.former_friends,
          blocked: payload?.contact_types?.blocked == null ? false : !!payload.contact_types.blocked,
        }
      }
    })
  }

  // Account archive export (databases + resource files)
  const createAccountArchiveExport = async (payload = {}) => {
    return await request('/account/archive_export', {
      method: 'POST',
      body: {
        account: payload.account || null,
        output_dir: payload.output_dir == null ? null : String(payload.output_dir || '').trim(),
        include_databases: payload.include_databases == null ? true : !!payload.include_databases,
        include_resources: payload.include_resources == null ? true : !!payload.include_resources,
        file_name: payload.file_name || null
      }
    })
  }

  const getAccountArchiveExport = async (exportId) => {
    if (!exportId) throw new Error('Missing exportId')
    return await request(`/account/archive_export/${encodeURIComponent(String(exportId))}`)
  }

  const cancelAccountArchiveExport = async (exportId) => {
    if (!exportId) throw new Error('Missing exportId')
    return await request(`/account/archive_export/${encodeURIComponent(String(exportId))}`, { method: 'DELETE' })
  }

  // WeChat Wrapped（年度总结）
  const getWrappedAnnual = async (params = {}) => {
    const query = new URLSearchParams()
    if (params && params.year != null) query.set('year', String(params.year))
    if (params && params.account) query.set('account', String(params.account))
    if (params && params.refresh != null) query.set('refresh', String(!!params.refresh))
    const url = '/wrapped/annual' + (query.toString() ? `?${query.toString()}` : '')
    return await request(url)
  }

  // WeChat Wrapped（年度总结）- 目录/元信息（轻量，用于按页懒加载）
  const getWrappedAnnualMeta = async (params = {}) => {
    const query = new URLSearchParams()
    if (params && params.year != null) query.set('year', String(params.year))
    if (params && params.account) query.set('account', String(params.account))
    if (params && params.refresh != null) query.set('refresh', String(!!params.refresh))
    const url = '/wrapped/annual/meta' + (query.toString() ? `?${query.toString()}` : '')
    return await request(url)
  }

  // WeChat Wrapped（年度总结）- 单张卡片（按页加载）
  const getWrappedAnnualCard = async (cardId, params = {}) => {
    if (cardId == null) throw new Error('Missing cardId')
    const query = new URLSearchParams()
    if (params && params.year != null) query.set('year', String(params.year))
    if (params && params.account) query.set('account', String(params.account))
    if (params && params.refresh != null) query.set('refresh', String(!!params.refresh))
    const safeId = encodeURIComponent(String(cardId))
    const url = `/wrapped/annual/cards/${safeId}` + (query.toString() ? `?${query.toString()}` : '')
    return await request(url)
  }

  // 获取微信进程状态
  const getWxStatus = async (params = {}) => {
    return await request('/wechat/status', params?.signal ? { signal: params.signal } : {})
  }

  // 获取数据库密钥
  const getKeys = async (params = {}) => {
    const query = new URLSearchParams()
    if (params && params.wechat_install_path) query.set('wechat_install_path', params.wechat_install_path)
    if (params && params.db_storage_path) query.set('db_storage_path', params.db_storage_path)
    if (params && params.key_mode) query.set('key_mode', params.key_mode)
    const url = '/get_keys' + (query.toString() ? `?${query.toString()}` : '')
    return await request(url, params?.signal ? { signal: params.signal } : {})
  }

  // 获取图片密钥
  const getImageKey = async (params = {}) => {
    const query = new URLSearchParams()
    if (params && params.account) query.set('account', params.account)
    if (params && params.db_storage_path) query.set('db_storage_path', params.db_storage_path)
    if (params && params.wxid_dir) query.set('wxid_dir', params.wxid_dir)
    const url = '/get_image_key' + (query.toString() ? `?${query.toString()}` : '')

    return await request(url)
  }

  // 扫描微信进程内存并通过本地 V2 图片校验密钥
  const getImageKeyMemory = async (params = {}) => {
    return await request('/get_image_key_memory', {
      method: 'POST',
      body: {
        account: params.account || null,
        db_storage_path: params.db_storage_path || null,
        wxid_dir: params.wxid_dir || null
      }
    })
  }

  // 枚举服务号信息
  const listBizAccounts = async (params = {}) => {
    const query = new URLSearchParams()
    if (params && params.account) query.set('account', params.account)
    if (params && params.source) query.set('source', params.source)
    const url = '/biz/list' + (query.toString() ? `?${query.toString()}` : '')
    return await request(url)
  }

  // 获取普通服务号消息
  const listBizMessages = async (params = {}) => {
    const query = new URLSearchParams()
    if (params && params.account) query.set('account', params.account)
    if (params && params.username) query.set('username', params.username)
    if (params && params.limit != null) query.set('limit', String(params.limit))
    if (params && params.offset != null) query.set('offset', String(params.offset))
    if (params && params.source) query.set('source', params.source)
    const url = '/biz/messages' + (query.toString() ? `?${query.toString()}` : '')
    return await request(url)
  }

  // 获取微信支付记录
  const listBizPayRecords = async (params = {}) => {
    const query = new URLSearchParams()
    if (params && params.account) query.set('account', params.account)
    if (params && params.limit != null) query.set('limit', String(params.limit))
    if (params && params.offset != null) query.set('offset', String(params.offset))
    if (params && params.source) query.set('source', params.source)
    const url = '/biz/pay_records' + (query.toString() ? `?${query.toString()}` : '')
    return await request(url)
  }

  const buildGeneralUrl = (path, params = {}) => {
    const query = new URLSearchParams()
    if (params && params.account) query.set('account', params.account)
    if (params && params.q) query.set('q', params.q)
    if (params && params.kind) query.set('kind', params.kind)
    if (params && params.status) query.set('status', params.status)
    query.set('source', params?.source || 'realtime')
    if (params && params.limit != null) query.set('limit', String(params.limit))
    if (params && params.offset != null) query.set('offset', String(params.offset))
    return `/general/${path}` + (query.toString() ? `?${query.toString()}` : '')
  }

  const listGeneralOverview = async (params = {}) => {
    return await request(buildGeneralUrl('overview', params))
  }

  const listFriendVerifications = async (params = {}) => {
    return await request(buildGeneralUrl('friend-verifications', params))
  }

  const listMiniPrograms = async (params = {}) => {
    return await request(buildGeneralUrl('mini-programs', params))
  }

  const listFinderRecords = async (params = {}) => {
    return await request(buildGeneralUrl('finder', params))
  }

  const listPaymentRecords = async (params = {}) => {
    return await request(buildGeneralUrl('payments', params))
  }

  const listRevokeRecords = async (params = {}) => {
    return await request(buildGeneralUrl('revokes', params))
  }

  const listGeneralSearchRecords = async (params = {}) => {
    return await request(buildGeneralUrl('search-records', params))
  }

  const listFavorites = async (params = {}) => {
    const query = new URLSearchParams()
    if (params && params.account) query.set('account', params.account)
    if (params && params.q) query.set('q', params.q)
    if (params && params.kind) query.set('kind', params.kind)
    if (params && params.tagId) query.set('tag_id', String(params.tagId))
    query.set('source', 'realtime')
    if (params && params.limit != null) query.set('limit', String(params.limit))
    if (params && params.offset != null) query.set('offset', String(params.offset))
    return await request('/favorites' + (query.toString() ? `?${query.toString()}` : ''))
  }

  const exportRecords = async (payload = {}) => {
    return await request('/records/export', {
      method: 'POST',
      body: {
        account: payload.account || null,
        dataset: payload.dataset || '',
        username: payload.username || '',
        subject_name: payload.subject_name || '',
        format: payload.format || 'html',
        types: Array.isArray(payload.types) ? payload.types : [],
        query: payload.query || '',
        output_dir: payload.output_dir || '',
        file_name: payload.file_name || '',
      },
    })
  }

  const getBizProxyImageUrl = (url) => {
    if (!url) return ''
    if (url.startsWith('data:')) return url // 如果已经是 base64，不处理
    const query = new URLSearchParams()
    query.set('url', url)
    const base = baseURL ? baseURL.replace(/\/$/, '') : ''
    return `${base}/biz/proxy_image?${query.toString()}`
  }

  const pickSystemDirectory = async (params = {}) => {
    const query = new URLSearchParams()
    if (params && params.title) query.set('title', params.title)
    if (params && params.initial_dir) query.set('initial_dir', params.initial_dir)
    const url = '/system/pick_directory' + (query.toString() ? `?${query.toString()}` : '')
    return await request(url)
  }

  const getImgHelperStatus = async () => {
    return await request('/system/img_helper/status')
  }

  const toggleImgHelper = async (enabled) => {
    return await request('/system/img_helper/toggle', {
      method: 'POST',
      body: { enabled: !!enabled }
    })
  }


  return {
    pickSystemDirectory,
    getImgHelperStatus,
    toggleImgHelper,
    detectWechat,
    detectCurrentAccount,
    decryptDatabase,
    importDecryptedPreview,
    importDecrypted,
    healthCheck,
    getPlatformCapabilities,
    listChatAccounts,
    getChatAccountInfo,
    deleteChatAccount,
    listChatSessions,
    listChatMessages,
    getChatMessageRaw,
    editChatMessage,
    repairChatMessageSender,
    flipChatMessageDirection,
    listChatEditedSessions,
    listChatEditedMessages,
    getChatEditStatus,
    resetChatEditedMessage,
    resetChatEditedSession,
    getChatRealtimeStatus,
    syncChatRealtimeMessages,
    syncChatRealtimeAll,
    searchChatMessages,
    getChatSearchIndexStatus,
    buildChatSearchIndex,
    listChatSearchSenders,
    getChatMessagesAround,
    getChatMessageDailyCounts,
    getChatMessageAnchor,
    resolveNestedChatHistory,
    resolveAppMsg,
    listSnsTimeline,
    listSnsUsers,
    openChatMediaFolder,
    downloadChatEmoji,
    saveMediaKeys,
    getSavedKeys,
    decryptAllMedia,
    createChatExport,
    getChatExport,
    listChatExports,
    getChatExportTargets,
    cancelChatExport,
    createSnsExport,
    getSnsExport,
    cancelSnsExport,
    listChatContacts,
    getChatContactProfile,
    exportChatContacts,
    createAccountArchiveExport,
    getAccountArchiveExport,
    cancelAccountArchiveExport,
    getWrappedAnnual,
    getWrappedAnnualMeta,
    getWrappedAnnualCard,
    getKeys,
    getImageKey,
    getImageKeyMemory,
    getWxStatus,
    listBizAccounts,
    listBizMessages,
    listBizPayRecords,
    listGeneralOverview,
    listFriendVerifications,
    listMiniPrograms,
    listFinderRecords,
    listPaymentRecords,
    listRevokeRecords,
    listGeneralSearchRecords,
    listFavorites,
    exportRecords,
    getBizProxyImageUrl,
  }
}
