// Common API 相关接口
import { BASE_URL } from './constants'

export interface ApiResponse<T = any> {
  code: number
  successful: boolean
  message: string
  data: T
}

export interface TokenResponse {
  code: number
  message: string
  data: {
    token: string
  }
  successful: boolean
}

export interface TokenWithDomainResponse {
  code: number
  message: string
  data: {
    token: string
    domain: string
  }
  successful: boolean
}

export interface QiniuUploadResponse {
  hash: string
  key: string
  url?: string
}


// 获取七牛云上传token（包含domain）
export const getUploadToken = async (timeoutMs: number = 10000): Promise<{ token: string, domain: string }> => {
  // 添加超时控制
  const controller = new AbortController()
  const timeoutId = setTimeout(() => {
    console.log(`Request timeout（${timeoutMs / 1000}s），aborting...`)
    controller.abort()
  }, timeoutMs)

  try {
    const response = await fetch(`${BASE_URL}/common/get-upload-token`, {
      method: "GET",
      headers: {
        Accept: "application/json",
        "Content-Type": "application/json",
        "Authorization": `Bearer ${localStorage.getItem("token")}`
      },
      signal: controller.signal,
      mode: "cors",
    })

    // 请求完成后清除超时
    clearTimeout(timeoutId)

    if (!response.ok) {
      const errorText = await response.text()
      console.error("Get token response error:", response.status, errorText)
      throw new Error(`Get token failed: ${response.status} ${response.statusText}`)
    }

    const result: TokenWithDomainResponse | TokenResponse = await response.json()
    console.log("Get token response:", result)

    if (result.code === 0 && result.successful && result.data.token) {
      console.log("Successfully get token")
      // Support both old and new API response formats
      const domain = 'domain' in result.data ? result.data.domain : 'cdn.qikongjian.com'
      return {
        token: result.data.token,
        domain: domain
      }
    } else {
      throw new Error(result.message || "Get token failed, server did not return a valid token")
    }
  } catch (error) {
    clearTimeout(timeoutId)
    console.error("Get upload token failed:", error)

    if (error instanceof Error) {
      if (error.name === "AbortError") {
        throw new Error("Request timeout, please check your network connection")
      } else if (error.message.includes("Failed to fetch")) {
        throw new Error("Network connection failed, possibly due to CORS policy or server unreachable")
      }
    }

    throw error
  }
}

// 生成唯一文件名
export const generateUniqueFileName = (originalName: string): string => {
  const timestamp = Date.now()
  const randomStr = Math.random().toString(36).substring(2, 8)
  const extension = originalName.split(".").pop()
  return `videos/${timestamp}_${randomStr}.${extension}`
}

// 七牛云上传
export const uploadToQiniu = async (
  file: File,
  token: string,
  onProgress?: (progress: number) => void
): Promise<string> => {
  const uniqueFileName = generateUniqueFileName(file.name)

  const formData = new FormData()
  formData.append("token", token)
  formData.append("key", uniqueFileName)
  formData.append("file", file)

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

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

    xhr.addEventListener("load", () => {
      if (xhr.status >= 200 && xhr.status < 300) {
        try {
          const response: QiniuUploadResponse = JSON.parse(xhr.responseText)
          const qiniuUrl = `https://cdn.qikongjian.com/${response.key || uniqueFileName}`
          console.log("Qiniu cloud upload success:", response)
          resolve(qiniuUrl)
        } catch (error) {
          console.error("Parse response failed:", error, "Original response:", xhr.responseText)
          reject(new Error(`Parse upload response failed: ${xhr.responseText}`))
        }
      } else {
        console.error("Qiniu cloud upload failed:", xhr.status, xhr.statusText, xhr.responseText)
        reject(new Error(`Upload failed: ${xhr.status} ${xhr.statusText}`))
      }
    })

    xhr.addEventListener("error", (e) => {
      console.error("Upload network error:", e)
      reject(new Error("Network error, upload failed"))
    })

    xhr.addEventListener("abort", () => {
      reject(new Error("Upload aborted"))
    })

    xhr.open("POST", "https://up-z2.qiniup.com")
    xhr.send(formData)
  })
}
