const CONFIG = require('../config')
const Parse = getApp().Parse

let config = {
  qiniuRegion: '',
  qiniuImageURLPrefix: '',
  qiniuUploadToken: '',
  qiniuUploadTokenURL: '',
  qiniuUploadTokenFunction: null,
  qiniuShouldUseQiniuFileName: false
}
let spaceLimit = 1024 * 1024 * 1024; // 默认1GB

// 在整个程序生命周期中,只需要 init 一次即可
// 如果需要变更参数,再调用 init 即可
function init(options) {
  config = {
    qiniuRegion: '',
    qiniuImageURLPrefix: '',
    qiniuUploadToken: '',
    qiniuUploadTokenURL: '',
    qiniuUploadTokenFunction: null,
    qiniuShouldUseQiniuFileName: false
  };
  updateConfigWithOptions(options);
}

function updateConfigWithOptions(options) {
  if (options.region) {
    config.qiniuRegion = options.region;
  } else {
    console.error('qiniu uploader need your bucket region');
  }
  if (options.uptoken) {
    config.qiniuUploadToken = options.uptoken;
  } else if (options.uptokenURL) {
    config.qiniuUploadTokenURL = options.uptokenURL;
  } else if (options.uptokenFunc) {
    config.qiniuUploadTokenFunction = options.uptokenFunc;
  }
  if (options.domain) {
    config.qiniuImageURLPrefix = options.domain;
  }
  config.qiniuShouldUseQiniuFileName = options.shouldUseQiniuFileName
}

function upload(filePath, success, fail, options, progress, cancelTask, before, complete) {
  if (null == filePath) {
    console.error('qiniu uploader need filePath to upload');
    return;
  }
  options && updateConfigWithOptions(options);
  if (config.qiniuUploadToken) {
    doUpload(filePath, success, fail, options, progress, cancelTask, before, complete);
  } else if (config.qiniuUploadTokenURL) {
    getQiniuToken(function () {
      doUpload(filePath, success, fail, options, progress, cancelTask, before, complete);
    });
  } else if (config.qiniuUploadTokenFunction) {
    config.qiniuUploadToken = config.qiniuUploadTokenFunction();
    if (null == config.qiniuUploadToken && config.qiniuUploadToken.length > 0) {
      console.error('qiniu UploadTokenFunction result is null, please check the return value');
      return
    }
    doUpload(filePath, success, fail, options, progress, cancelTask, before, complete);
  } else {
    console.error('qiniu uploader need one of [uptoken, uptokenURL, uptokenFunc]');
    return;
  }
}
/* 文件上传函数 */
async function doUpload(filePath, success, fail, options, progress, cancelTask, before, complete) {
  if (null == config.qiniuUploadToken && config.qiniuUploadToken.length > 0) {
    console.error('qiniu UploadToken is null, please check the init config or networking');
    return
  }
  let authLoad = await authSpaceCount()
  if (!authLoad) {
    wx.showModal({
      title: '上传失败',
      content: '文件存储空间已满,请联系维护人员。',
      showCancel: false,
      cancelColor: '#000000',
      confirmText: '确定',
      confirmColor: '#3CC51F',
    });
    return
  }
  let url = uploadURLFromRegionCode(config.qiniuRegion);
  let fileName = filePath.split('//')[1];
  if (options && options.key) {
    fileName = options.key;
  }
  let formData = {
    'token': config.qiniuUploadToken
  };
  if (!config.qiniuShouldUseQiniuFileName) {
    formData['key'] = fileName
  }
  before && before();
  let uploadTask = wx.uploadFile({
    url: url,
    filePath: filePath,
    name: 'file',
    formData: formData,
    success: async function (res) {
      let dataString = res.data
      try {
        let dataObject = JSON.parse(dataString);
        //do something
        let fileUrl = config.qiniuImageURLPrefix + '/' + dataObject.key;
        dataObject.fileUrl = fileUrl
        dataObject.imageURL = fileUrl;
        let size = await getFileInfo(filePath)
        dataObject.size = size
        console.log(dataObject);
        if (success) {
          success(dataObject);
        }
        let type = dataObject.imageURL.split('.').slice(-1)
        let startIndex = dataObject.imageURL.lastIndexOf('/')
        let name = dataObject.imageURL.slice(startIndex + 1)
        let file = {
          name: name,
          type: formatFile(type),
          size: size,
          url: dataObject.fileUrl,
        }
        console.log(file);
        saveAttachment(file)
      } catch (e) {
        console.log('parse JSON failed, origin String is: ' + dataString)
        if (fail) {
          fail(e);
        }
      }
    },
    fail: function (error) {
      console.error(error);
      if (fail) {
        fail(error);
      }
    },
    complete: function (data) {
      complete && complete(data);
    }
  })

  uploadTask.onProgressUpdate((res) => {
    progress && progress(res)
  })

  cancelTask && cancelTask(() => {
    uploadTask.abort()
  })
}

function getQiniuToken(callback) {
  wx.request({
    url: config.qiniuUploadTokenURL,
    success: function (res) {
      let token = res.data.uptoken;
      if (token && token.length > 0) {
        config.qiniuUploadToken = token;
        if (callback) {
          callback();
        }
      } else {
        console.error('qiniuUploader cannot get your token, please check the uptokenURL or server')
      }
    },
    fail: function (error) {
      console.error('qiniu UploadToken is null, please check the init config or networking: ' + error);
    }
  })
}

function uploadURLFromRegionCode(code) {
  let uploadURL = null;
  switch (code) {
    case 'ECN': uploadURL = 'https://up.qiniup.com'; break;
    case 'NCN': uploadURL = 'https://up-z1.qiniup.com'; break;
    case 'SCN': uploadURL = 'https://up-z2.qiniup.com'; break;
    case 'NA': uploadURL = 'https://up-na0.qiniup.com'; break;
    case 'ASG': uploadURL = 'https://up-as0.qiniup.com'; break;
    default: console.error('please make the region is with one of [ECN, SCN, NCN, NA, ASG]');
  }
  return uploadURL;
}
/* 上传校验空间 */
async function authSpaceCount() {
  let company = CONFIG.default.company
  let query = new Parse.Query("Company");
  query.select("configSpace")
  let comObj = await query.get(company);
  let limit = comObj.get("configSpace") && comObj.get("configSpace").limit;
  return new Promise((res, rej) => {
    wx.request({
      url: `https://server.fmode.cn/api/storage/space?c=${company}`,
      data: {},
      header: { 'content-type': 'application/json' },
      method: 'GET',
      dataType: 'json',
      responseType: 'text',
      success: (result) => {
        let data = result?.data?.data
        let spaceMap = data;
        let _spaceLimit = getLimitBytes(limit) || spaceLimit;
        let spaceUsed = spaceMap.totalSize;
        console.log('总空间:', _spaceLimit);
        console.log('已用空间:', spaceUsed);
        if (!_spaceLimit || spaceUsed > _spaceLimit) {
          res(false)
          return
        }
        res(true)
      },
      fail: (err) => {
        console.warn(err);
        rej('request space API fail')
      },
      complete: () => { }
    });
  })
}
// 单位
function getLimitBytes(limit) {
  if (limit) {
    let num = Number(limit.slice(0, limit.length - 2))
    let unit = limit.slice(-2)
    switch (unit) {
      case "EB":
        unit = 1024 * 1024 * 1024 * 1024 * 1024 * 1024
        break;
      case "PB":
        unit = 1024 * 1024 * 1024 * 1024 * 1024
        break;
      case "TB":
        unit = 1024 * 1024 * 1024 * 1024
        break;
      case "GB":
        unit = 1024 * 1024 * 1024
        break;
      case "MB":
        unit = 1024 * 1024
        break;
      case "KB":
        unit = 1024
        break;
      default:
        break;
    }
    return num * unit
  }
  return 0
}
//上传保存Attachment
async function saveAttachment(file, cateId) {
  let query = new Parse.Query("Attachment");
  query.equalTo("url", file.url);
  let attachment = await query.first();
  if (attachment && attachment.id) {
    console.error("该文件已存在,无需重复上传");
    return
  } else {
    let Attachment = Parse.Object.extend("Attachment")
    attachment = new Attachment();
    attachment.set("size", file.size)
    attachment.set("url", file.url)
    attachment.set("name", file.name)
    attachment.set("mime", file.type)
    attachment.set("company", {
      __type: "Pointer",
      className: "Company",
      objectId: CONFIG.default.company
    })
    cateId && attachment.set("category", {
      __type: "Pointer",
      className: "Category",
      objectId: cateId
    })
    return await attachment.save()
  }
}

// 获取本地存储文件大小
function getFileInfo(filePath) {
  return new Promise((result) => {
    wx.getFileInfo({
      filePath: filePath,
      success(res) {
        result(res.size)
      },
      fail(err){
        result(0)
      }
    })
  })
}

function formatFile(type) {
  let fileJson = {
    "doc": "xapplication/vnd.openxmlformats-officedocument.wordprocessingml.document",
    "doc": "application/msword",
    "pdf": "application/pdf",
    "rtf": "application/rtf",
    "xls": "application/vnd.ms-excel",
    "ppt": "application/vnd.ms-powerpoint",
    "rar": "application/x-rar-compressed",
    "swf": "application/x-shockwave-flash",
    "zip": "application/zip",
    "mid": "audio/midi",
    "midi": "audio/midi",
    "kar": "audio/midi",
    "mp3": "audio/mpeg",
    "ogg": "audio/ogg",
    "m4a": "audio/x-m4a",
    "ra": "audio/x-realaudio",
    "gif": "image/gif",
    "jpeg": "image/jpeg",
    "jpg": "image/jpeg",
    "png": "image/png",
    "tif": "image/tiff",
    "tiff": " image/tiff",
    "wbmp": " image/vnd.wap.wbmp",
    "ico": "image/x-icon",
    "jng": "image/x-jng",
    "bmp": "image/x-ms-bmp",
    "svg": "image/svg+xml",
    "svgz": " image/svg+xml",
    "webp": " image/webp",
    "css": "text/css",
    "html": " text/html",
    "htm": "text/html",
    "shtm": "l text/html",
    "txt": "text/plain",
    "xml": "text/xml",
    "3gpp": " video/3gpp",
    "3gp": "video/3gpp",
    "mp4": "video/mp4",
    "mpeg": " video/mpeg",
    "mpg": "video/mpeg",
    "mov": "video/quicktime",
    "webm": "video/webm",
    "flv": "video/x-flv",
    "m4v": "video/x-m4v",
    "wmv": "video/x-ms-wmv",
    "avi": "video/x-msvideo",
  }
  return fileJson[type] || type
}

module.exports = {
  init: init,
  upload: upload,
}