const BASE_URL = import.meta.env.VITE_API_BASE_URL || '/api/v1'

const api = {
  async request<T>(endpoint: string, options: RequestInit = {}): Promise<T> {
    const token = localStorage.getItem('token')

    const response = await fetch(`${BASE_URL}${endpoint}`, {
      ...options,
      headers: {
        'Content-Type': 'application/json',
        ...(token && { Authorization: `Bearer ${token}` }),
        ...options.headers,
      },
    })

    const data = await response.json()

    if (response.status === 401 || data.code === 401) {
      localStorage.removeItem('token')
      localStorage.removeItem('user')
      window.location.href = '/login'
      throw new Error('登录已过期，请重新登录')
    }

    if (!response.ok || data.code !== 200) {
      throw new Error(data.message || '请求失败')
    }

    return data.data
  },

  async get<T>(endpoint: string): Promise<T> {
    return this.request<T>(endpoint, { method: 'GET' })
  },

  async post<T>(endpoint: string, body?: any): Promise<T> {
    return this.request<T>(endpoint, {
      method: 'POST',
      body: body ? JSON.stringify(body) : undefined,
    })
  },

  async postFormData<T>(endpoint: string, formData: FormData): Promise<T> {
    const token = localStorage.getItem('token')

    const response = await fetch(`${BASE_URL}${endpoint}`, {
      method: 'POST',
      body: formData,
      headers: {
        ...(token && { Authorization: `Bearer ${token}` }),
      },
    })

    const data = await response.json()

    if (response.status === 401 || data.code === 401) {
      localStorage.removeItem('token')
      localStorage.removeItem('user')
      window.location.href = '/login'
      throw new Error('登录已过期，请重新登录')
    }

    if (!response.ok || data.code !== 200) {
      throw new Error(data.message || '请求失败')
    }

    return data.data
  },

  async postFormDataWithProgress<T>(
    endpoint: string,
    formData: FormData,
    onProgress?: (progress: number, speed: string) => void
  ): Promise<T> {
    const token = localStorage.getItem('token')

    return new Promise((resolve, reject) => {
      const xhr = new XMLHttpRequest()

      let startTime = Date.now()
      let lastLoaded = 0

      xhr.upload.addEventListener('progress', (event) => {
        if (event.lengthComputable) {
          const progress = Math.round((event.loaded / event.total) * 100)

          // 计算上传速度
          const currentTime = Date.now()
          const elapsedTime = (currentTime - startTime) / 1000 // 秒
          const loadedSinceLast = event.loaded - lastLoaded

          if (elapsedTime > 0) {
            const speed = loadedSinceLast / elapsedTime // bytes per second
            const speedStr = formatSpeed(speed)
            onProgress?.(progress, speedStr)
            lastLoaded = event.loaded
          }
        }
      })

      xhr.addEventListener('load', () => {
        if (xhr.status === 401) {
          localStorage.removeItem('token')
          localStorage.removeItem('user')
          window.location.href = '/login'
          reject(new Error('登录已过期，请重新登录'))
          return
        }

        try {
          const data = JSON.parse(xhr.responseText)
          if (xhr.status !== 200 || data.code !== 200) {
            reject(new Error(data.message || '请求失败'))
          } else {
            resolve(data.data)
          }
        } catch {
          reject(new Error('解析响应失败'))
        }
      })

      xhr.addEventListener('error', () => {
        reject(new Error('网络错误'))
      })

      xhr.addEventListener('abort', () => {
        reject(new Error('上传已取消'))
      })

      xhr.open('POST', `${BASE_URL}${endpoint}`)
      if (token) {
        xhr.setRequestHeader('Authorization', `Bearer ${token}`)
      }
      xhr.send(formData)
    })
  },

  async put<T>(endpoint: string, body?: any): Promise<T> {
    return this.request<T>(endpoint, {
      method: 'PUT',
      body: body ? JSON.stringify(body) : undefined,
    })
  },

  async delete<T>(endpoint: string, body?: any): Promise<T> {
    return this.request<T>(endpoint, {
      method: 'DELETE',
      body: body ? JSON.stringify(body) : undefined,
    })
  },
}

function formatSpeed(bytesPerSecond: number): string {
  if (bytesPerSecond < 1024) {
    return `${bytesPerSecond.toFixed(0)} B/s`
  } else if (bytesPerSecond < 1024 * 1024) {
    return `${(bytesPerSecond / 1024).toFixed(2)} KB/s`
  } else if (bytesPerSecond < 1024 * 1024 * 1024) {
    return `${(bytesPerSecond / (1024 * 1024)).toFixed(2)} MB/s`
  } else {
    return `${(bytesPerSecond / (1024 * 1024 * 1024)).toFixed(2)} GB/s`
  }
}

export { BASE_URL }
export default api
