import useStore from '@/stores'

/**
 * @ 封装流请求支持终止
 *
 */

interface ChunkData {
  type: string
  content: string
  error: string
}

let controller = new AbortController()

/**
 * 发起一个支持中止的 POST 请求
 * @param url - 请求的 URL 地址
 * @param data - 请求体数据，可选参数
 * @returns 返回一个 Promise，该 Promise 解析为 fetch 请求的响应结果
 */
async function fetchWithAbort(url: string, data?: any) {
  const { dada } = useStore()
  const fetchHeaders: any = {
    'Content-Type': 'application/json',
    // Token 	用户信息
    Token: dada.getDadaToken(),
    // 租户idTenantId
    TenantId: dada.getTenantId(),
    // AuthId客户端id 默认值
    AuthId: 'bGFtcF93ZWJfcHJvX3NveWJlYW46bGFtcF93ZWJfcHJvX3NveWJlYW5fc2VjcmV0',
    // ApplicationId 应用id默认3
    Authorization: 3
  }

  // const controller = new AbortController();
  // // @ts-ignore
  // window._controller = controller

  // try {
  //   const response = await fetch(url, {
  //     method: 'POST',
  //     body: data ? JSON.stringify(data) : undefined,
  //     headers: fetchHeaders,
  //     signal: controller.signal
  //   });
  //   console.log('Response:', response);
  //   if (!response.ok) {
  //     throw new Error(`HTTP error! status: ${response.status}`);
  //   }
  //   return response;
  // } catch (error: any) {
  //   if (error.name === 'AbortError') {
  //     console.log('请求被主动取消');
  //   } else {
  //     console.error('请求异常:', error);
  //     throw error; // 重新抛出供上层处理
  //   }
  // } finally {
  //   controller.abort(); // 确保资源释放
  // }

  try {
    controller = new AbortController() // 重置为新的实例
    // @ts-ignore
    window._controller = controller
    return await fetch(url, {
      method: 'POST',
      body: data ? JSON.stringify(data) : undefined,
      headers: fetchHeaders,
      signal: controller.signal
    }).catch((error) => {
      if (error.name === 'AbortError') {
        console.log('请求被取消')
      } else {
        console.error('请求失败:', error)
      }
    })
  } catch (err: any) {
    console.error('[Fetch error]', err)
    try {
      controller.abort()
    } catch (e) {
      console.log(e)
    }
  }
}

/**
 * 将响应流转换为文本，并逐块处理数据
 * @param response - 包含响应流的 Response 对象
 * @param cb - 回调函数，用于处理每块数据，接收三个参数：
 *             success 表示处理是否成功，
 *             data 表示解析后的块数据，
 *             fullResult 表示截至当前的完整结果（可选）
 */
async function responseToText(
  response: Response,
  cb: (success: boolean, data: ChunkData, fullResult?: string) => void
) {
  const reader = response?.body?.getReader()
  const decoder = new TextDecoder('utf-8')
  let result = ''

  if (!reader) {
    cb(false, { type: 'error', content: '', error: '' }, '')
    return
  }

  try {
    // eslint-disable-next-line no-constant-condition
    while (true) {
      const { done, value } = await reader.read()
      if (done) break

      const str = decoder.decode(value, { stream: true })
      console.log('str:', str)
      const messages = str.split('\n\n').filter((line) => line.trim().startsWith('data: '))
      console.log('messages:', messages)

      for (const msg of messages) {
        try {
          const jsonStr = msg.replace(/^data:\s*/, '').replace(/\n/g, '\\n')
          const parsed: ChunkData = JSON.parse(jsonStr)
          if (parsed.type === 'content') {
            result += parsed.content
            cb(true, parsed, result)
          } else {
            cb(true, parsed)
          }
        } catch (e) {
          console.error('JSON parse error:', e)
          cb(false, { type: 'error', content: '', error: '' })
        }
      }
    }
  } catch (e) {
    console.error('Stream reading error:', e)
    cb(false, { type: 'error', content: '', error: '' })
  }
}

/**
 * 将响应流转换为文本，并逐块处理数据
 * @param response - 包含响应流的 Response 对象
 * @param cb - 回调函数，用于处理每块数据，接收三个参数：
 *             success 表示处理是否成功，
 *             data 表示解析后的块数据，
 *             fullResult 表示截至当前的完整结果（可选）
 */
async function chatResponseToText(
  response: Response,
  cb: (success: boolean, data: ChunkData | any, fullResult?: string) => void
) {
  const reader = response?.body?.getReader()
  const decoder = new TextDecoder('utf-8')
  let result = ''

  if (!reader) {
    cb(false, { type: 'error', content: '', error: '' }, '')
    return
  }

  try {
    // eslint-disable-next-line no-constant-condition
    while (true) {
      const { done, value } = await reader.read()
      if (done) break

      const str = decoder.decode(value, { stream: true })
      // console.log('str:', str)

      const messages = str
        .split('\n\n') // 按空行分割事件
        .filter((block) => block.trim() !== '') // 过滤空块
      // console.log('messages:', messages)
      for (const block of messages) {
        const lines = block.split('\n')
        let dataJson: any = ''

        for (const line of lines) {
          if (line.startsWith('data:') && line.endsWith('}')) {
            dataJson += line.replace('data:', '').trim()
          }
        }

        if (dataJson) {
          try {
            const parsedData = JSON.parse(dataJson)
            // 处理内容类型事件
            if (parsedData.type === 'content') {
              // console.log('parsedData:', parsedData.content)
              result = parsedData.accumulated_content || result + parsedData.content
              cb(true, { ...parsedData, accumulated_content: result }, result)
            }
            // 处理完成类型事件
            else if (parsedData.type === 'done') {
              cb(true, { ...parsedData, accumulated_content: result }, result)
            }
            // 处理完成类型事件
            else if (parsedData.type === 'error') {
              throw new Error(parsedData.content)
            }
          } catch (e: any) {
            console.error('JSON parse error:', e)
            cb(false, { type: 'error', content: e }, e)
          }
        }
      }
    }
  } catch (e) {
    console.error('Stream reading error:', e)
    cb(false, { type: 'error', content: '', error: '' })
  }
}

// @ts-ignore
// window._controller = controller

/* 调用window上私有的中止方法 */

// @ts-ignore
// window.?_controller?.abort()

export { fetchWithAbort, responseToText, chatResponseToText, controller }
