import request from '@/utils/request'
import Vue from 'vue'

/**
 * 安全改造：前端不再使用OBS AK/SK直传
 * 改为通过后端获取presigned URL，然后用签名URL上传到OBS
 * AK/SK仅在后端保存，前端无需接触
 */

/**
 * 通过后端presigned URL上传文件到OBS
 * @param file 要上传的文件对象
 * @param progressCallback 进度回调函数 (progress: 0-100)
 * @param type 上传类型：1=课程视频, 2=用户视频
 * @param cancelCallback 取消回调对象 {cancel: fn}
 */
export const uploadToOBS = async (file, progressCallback, type, cancelCallback) => {
  try {
    // 1. 从后端获取presigned URL
    const suffix = (file.name || 'mp4').split('.').pop() || 'mp4'
    const presignRes = await request({
      url: '/common/obs/presignedUploadUrl',
      method: 'get',
      params: { type: type || 2, suffix }
    })

    // request拦截器已解包res.data，直接检查返回对象
    if (!presignRes.url) {
      throw new Error('获取签名URL失败')
    }

    const presignedUrl = presignRes.url
    const objKey = presignRes.objKey

    // 2. 使用presigned URL通过原生XMLHttpRequest上传（支持进度回调）
    return new Promise((resolve, reject) => {
      const xhr = new XMLHttpRequest()

      // 取消回调
      if (cancelCallback) {
        cancelCallback({
          cancel: () => {
            xhr.abort()
            reject(new Error('Upload cancelled by user'))
          }
        })
      }

      // 进度监听
      xhr.upload.onprogress = (event) => {
        if (event.lengthComputable && progressCallback) {
          const progress = Math.round((event.loaded / event.total) * 100)
          progressCallback(progress)
        }
      }

      xhr.onload = () => {
        if (xhr.status >= 200 && xhr.status < 300) {
          resolve({ urlPath: objKey })
        } else {
          reject(new Error('OBS上传失败: HTTP ' + xhr.status))
        }
      }

      xhr.onerror = () => {
        reject(new Error('OBS上传网络错误'))
      }

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

      // 使用PUT方式上传到presigned URL
      xhr.open('PUT', presignedUrl, true)
      xhr.setRequestHeader('Content-Type', file.type || 'application/octet-stream')
      xhr.send(file)
    })
  } catch (error) {
    throw error
  }
}