import { getSystemVersion, METHOD, request } from '@vue2-client/utils/request'
import { ACCESS_TOKEN, V4_ACCESS_TOKEN } from '@vue2-client/store/mutation-types'
import { showGlobalLoading, hideGlobalLoading } from '@vue2-client/composables/useGlobalLoading'

/**
 * GET请求
 * @param url 请求地址
 * @param parameter 路径参数
 * @returns {Promise<AxiosResponse<T>>}
 */
function get (url, parameter) {
  return request(url, METHOD.GET, parameter)
}

/**
 * POST请求
 * @param url 请求地址
 * @param parameter 请求参数
 * @param config 配置项
 * @param {boolean|string} config.globalLoading - 是否显示全局 Loading，可传入字符串作为提示文字
 * @param {boolean} config.showErrorMessage - 业务 code 500 及其他非 200（不含 601）时是否显示默认错误提示（默认 true），设为 false 时由业务自行处理
 * @param {boolean} config.dedupe - 是否启用请求去重（POST 默认开启，设为 false 可关闭）
 * @param {string} config.dedupeStrategy - 去重策略：'reject'（拒绝，默认）或 'reuse'（复用结果）
 * @returns {Promise<AxiosResponse<T>>}
 *
 * @example
 * // 表单提交 - 默认拒绝重复（防止重复提交）
 * post('/api/save', formData)
 *
 * // 下拉框数据 - 复用结果（多处同时请求共享结果）
 * post('/api/options', params, { dedupe: true, dedupeStrategy: 'reuse' })
 *
 * // 列表查询 - 关闭去重（允许重复查询）
 * post('/api/list', params, { dedupe: false })
 */
function post (url, parameter, config = {}) {
  // 兼容 config 为 null 的情况
  const safeConfig = config || {}
  const { globalLoading, ...axiosConfig } = safeConfig

  // 全局 Loading - 请求开始时显示
  if (globalLoading) {
    showGlobalLoading(globalLoading)
  }

  // 发起请求
  return request(url, METHOD.POST, parameter, axiosConfig)
    .finally(() => {
      // 请求结束时隐藏全局 Loading
      if (globalLoading) {
        hideGlobalLoading()
      }
    })
}

/**
 * POST请求（按服务名）
 */
function postByServiceName (url, parameter, serviceName = process.env.VUE_APP_SYSTEM_NAME, isDev, config = {}) {
  if (url.startsWith('api/') || url.startsWith('/api/')) {
    return request(url, METHOD.POST, parameter, config)
  }
  let apiPre = '/api/'
  if (isDev) {
    apiPre = '/devApi/'
  }
  if (!url.startsWith('/')) {
    url = '/' + url
  }
  url = apiPre + serviceName + url
  return request(url, METHOD.POST, parameter, config)
}

/**
 * DELETE请求
 * @param url 请求地址
 * @param parameter 请求参数
 * @param config
 * @returns {Promise<AxiosResponse<T>>}
 */
function del (url, parameter, config = {}) {
  return request(url, METHOD.DELETE, parameter, config)
}

/**
 * PUT请求
 * @param url 请求地址
 * @param parameter 请求参数
 * @param config
 * @returns {Promise<AxiosResponse<T>>}
 */
function put (url, parameter, config = {}) {
  return request(url, METHOD.PUT, parameter, config)
}

/**
 * 封装 EventSource 请求函数
 * @param {string} url - 请求地址
 * @param {Object} options - 请求选项（包括 method, headers, body 等）
 * @param {Function} onDataUpdate - 数据更新回调，每次接收到新的数据都会调用
 * @param {Function} onError - 错误处理回调
 * @param {Function} onComplete - 请求完成回调（流正常结束）
 * @returns {Function} - 用于取消请求的函数
 */
function startEventStreamPOST (url, params, headers = {}, onDataUpdate, onError, onComplete, serviceName = process.env.VUE_APP_SYSTEM_NAME) {
  return startEventStream(url, params, headers, onDataUpdate, onError, onComplete, serviceName, 'POST')
}

/**
 * EventSource 请求
 */
function startEventStream (url, params, headers = {}, onDataUpdate, onError, onComplete, serviceName = process.env.VUE_APP_SYSTEM_NAME, method = 'GET') {
  let isStopped = false
  let requestCount = 0

  if (!(url.startsWith('api/') || url.startsWith('/api/') || url.startsWith('http'))) {
    if (!url.startsWith('/')) {
      url = '/' + url
    }
    url = '/api/' + serviceName + url
  }

  console.log(`[EventStream] 开始新的请求: ${url}`, { params, headers, method })

  const controller = new AbortController()
  const { signal } = controller
  const token = localStorage.getItem(ACCESS_TOKEN)

  if (token) {
    const compatible = getSystemVersion()
    if (compatible === 'V4') {
      headers[V4_ACCESS_TOKEN] = token
    } else {
      headers[ACCESS_TOKEN] = token
    }
  }

  fetch(url, {
    method: method,
    headers: {
      ...headers,
      Accept: 'text/event-stream',
      'Cache-Control': 'no-cache',
      Connection: 'keep-alive'
    },
    body: JSON.stringify(params),
    signal
  }).then(response => {
    if (!response.ok) {
      throw new Error(`HTTP error! status: ${response.status}`)
    }

    requestCount++
    console.log(`[EventStream] 请求已打开 (第${requestCount}次): ${url}`)

    const reader = response.body.getReader()
    const decoder = new TextDecoder()
    let buffer = ''

    function processStream () {
      if (isStopped) return

      reader.read().then(({ done, value }) => {
        if (done) {
          console.log(`[EventStream] 流读取完成: ${url}`)
          if (!isStopped) {
            isStopped = true
            onComplete?.()
          }
          return
        }

        // console.log('[EventStream] 收到原始数据, length:', value ? value.length : 0)
        const chunk = decoder.decode(value, { stream: true })
        // console.log('[EventStream] 收到原始数据:', chunk)
        buffer += chunk

        const lines = buffer.split('\n')
        buffer = lines.pop()

        let currentEvent = null

        for (const line of lines) {
          if (line.startsWith('event: ')) {
            currentEvent = line.slice(7)
          } else if (line.startsWith('data: ')) {
            const currentData = line.slice(6)
            if (currentData === '[DONE]') continue
            try {
              const parsedData = JSON.parse(currentData)
              const dataType = currentEvent === 'additionalInfo' ? 'additionalInfo' : (currentEvent === 'sourceInfo' ? 'sourceInfo' : 'data')
              onDataUpdate?.(parsedData, dataType)
            } catch (e) {
              onDataUpdate?.(currentData, currentEvent === 'sourceInfo' ? 'sourceInfo' : 'data')
            }
            currentEvent = null
          }
        }

        processStream()
      }).catch(error => {
        console.error(`[EventStream] 流读取错误: ${url}`, error)
        if (!isStopped) {
          isStopped = true
          onError?.(error)
        }
      })
    }

    processStream()
  }).catch(error => {
    console.error(`[EventStream] 请求错误: ${url}`, error)
    if (!isStopped) {
      isStopped = true
      onError?.(error)
    }
  })

  return () => {
    isStopped = true
    controller.abort()
    console.log('连接已关闭')
  }
}

export { get, post, del, put, postByServiceName, startEventStream, startEventStreamPOST }
