/* eslint-disable style/operator-linebreak */
/**
 * 桌面端 HTTP 客户端
 * 基于现有的 uni.request 架构，自动注入 baseURL: api.xianglexue.com
 * 适配现有中文名 API 文件的调用方式
 */

import type { CustomRequestOptions } from '@/http/types'
import { http, httpDelete, httpGet, httpPost, httpPut } from '@/http/http'

// 桌面端 baseURL
const DESKTOP_BASE_URL = 'http://api.xianglexue.com/api/v1'

interface ControllerResponse<T> {
  code?: number
  data?: T
}

// 重写 ModelPageResponse 以支持泛型，避免 any[] 覆盖问题
interface TypedModelPageResponse<T = any> {
  /** 是否有更多数据 */
  has_more?: boolean
  /** 当前页数据列表 */
  list?: T[]
  /** 当前页 */
  page?: number
  /** 每页数量 */
  page_size?: number
  /** 总记录数 */
  total?: number
}

// 检测是否为分页响应类型
type IsPageResponse<T> = T extends { list?: any[], page?: number, total?: number } ? true : false

// 优化的类型解压，智能处理分页响应
type ExtractData<T> = T extends ControllerResponse<infer U>
  ? IsPageResponse<U> extends true
    ? // 如果是分页响应，保持原始结构但替换 ModelPageResponse 为 TypedModelPageResponse
    U extends { list?: infer L }
      ? Omit<U, 'list'> & { list?: L }
      : U
    : U
  : T

/**
 * 桌面端 GET 请求
 */
function desktopHttpGet<T>(url: string, query?: Record<string, any>, header?: Record<string, any>, options?: Partial<CustomRequestOptions>) {
  const desktopUrl = url.startsWith('http') ? url : `${DESKTOP_BASE_URL}${url}`
  return httpGet<ExtractData<T>>(desktopUrl, query, header, options)
}

/**
 * 桌面端 POST 请求
 */
function desktopHttpPost<T>(url: string, data?: Record<string, any>, query?: Record<string, any>, header?: Record<string, any>, options?: Partial<CustomRequestOptions>) {
  const desktopUrl = url.startsWith('http') ? url : `${DESKTOP_BASE_URL}${url}`
  return httpPost<ExtractData<T>>(desktopUrl, data, query, header, options)
}

/**
 * 桌面端 PUT 请求
 */
function desktopHttpPut<T>(url: string, data?: Record<string, any>, query?: Record<string, any>, header?: Record<string, any>, options?: Partial<CustomRequestOptions>) {
  const desktopUrl = url.startsWith('http') ? url : `${DESKTOP_BASE_URL}${url}`
  return httpPut<ExtractData<T>>(desktopUrl, data, query, header, options)
}

/**
 * 桌面端 DELETE 请求
 */
function desktopHttpDelete<T>(url: string, query?: Record<string, any>, header?: Record<string, any>, options?: Partial<CustomRequestOptions>) {
  const desktopUrl = url.startsWith('http') ? url : `${DESKTOP_BASE_URL}${url}`
  return httpDelete<ExtractData<T>>(desktopUrl, query, header, options)
}

/**
 * 桌面端 HTTP 客户端
 * 完全适配现有 API 文件的调用方式
 */
class DesktopHttpClient {
  /**
   * GET 请求 - 适配现有调用方式
   */
  get<T>(url: string, options: { query?: Record<string, any>, headers?: Record<string, any> } = {}) {
    return desktopHttpGet<T>(url, options.query, options.headers)
  }

  /**
   * POST 请求 - 适配现有调用方式
   * 支持 params 参数（对应现有代码的 { params: xxx } 传参方式）
   */
  post<T>(url: string, options: {
    params?: Record<string, any>
    query?: Record<string, any>
    data?: Record<string, any>
    headers?: Record<string, any>
  } = {}) {
    // 适配现有代码：{ params: xxx } 传参方式
    const requestData = options.params || options.data
    return desktopHttpPost<T>(url, requestData, options.query, options.headers)
  }

  /**
   * PUT 请求 - 适配现有调用方式
   */
  put<T>(url: string, options: {
    params?: Record<string, any>
    query?: Record<string, any>
    data?: Record<string, any>
    headers?: Record<string, any>
  } = {}) {
    const requestData = options.params || options.data
    return desktopHttpPut<T>(url, requestData, options.query, options.headers)
  }

  /**
   * DELETE 请求 - 适配现有调用方式
   */
  delete<T>(url: string, options: { query?: Record<string, any>, headers?: Record<string, any> } = {}) {
    return desktopHttpDelete<T>(url, options.query, options.headers)
  }

  /**
   * 表单数据请求 - 适配现有 formData 方法
   * 使用 uni.uploadFile 来处理文件上传
   */
  formData<T>(url: string, options: {
    params?: Record<string, any>
    headers?: Record<string, any>
  } = {}) {
    return new Promise<T>((resolve, reject) => {
      const desktopUrl = url.startsWith('http') ? url : `${DESKTOP_BASE_URL}${url}`

      // 处理文件和其他参数
      let filePath = ''
      let name = 'file'
      const formData: Record<string, any> = {}

      if (options.params) {
        Object.entries(options.params).forEach(([key, value]) => {
          if (value && typeof value === 'object' && 'path' in value) {
            // 文件对象
            filePath = value.path
            name = key
          }
          else if (value !== undefined && value !== null) {
            formData[key] = String(value)
          }
        })
      }

      uni.uploadFile({
        url: desktopUrl,
        filePath,
        name,
        formData,
        header: options.headers,
        success(res) {
          try {
            const responseData = JSON.parse(res.data)
            if (responseData && typeof responseData === 'object' && 'code' in responseData) {
              if (responseData.code === 200) {
                resolve(responseData.data)
              }
              else {
                reject(responseData)
              }
            }
            else {
              resolve(responseData)
            }
          }
          catch (error) {
            reject(error)
          }
        },
        fail(err) {
          reject(err)
        },
      })
    })
  }

  /**
   * 下载文件请求 - 适配现有 download 方法
   * 使用 uni.downloadFile 来处理文件下载
   */
  download<T = any>(url: string, options: { query?: Record<string, any> } = {}) {
    return new Promise<T>((resolve, reject) => {
      let desktopUrl = url.startsWith('http') ? url : `${DESKTOP_BASE_URL}${url}`

      // 处理 query 参数
      if (options.query && Object.keys(options.query).length > 0) {
        const queryString = Object.entries(options.query)
          .filter(([_, value]) => value !== undefined && value !== null)
          .map(([key, value]) => `${encodeURIComponent(key)}=${encodeURIComponent(String(value))}`)
          .join('&')

        desktopUrl += desktopUrl.includes('?') ? `&${queryString}` : `?${queryString}`
      }

      uni.downloadFile({
        url: desktopUrl,
        success(res) {
          if (res.statusCode === 200) {
            resolve(res.tempFilePath as T)
          }
          else {
            reject(new Error(`Download failed with status: ${res.statusCode}`))
          }
        },
        fail(err) {
          reject(err)
        },
      })
    })
  }
}

// 创建桌面端 HTTP 客户端实例
const httpClient = new DesktopHttpClient()

// 导出类型和客户端
export { TypedModelPageResponse }
export type { ExtractData }
export default httpClient
