import { host } from "../../utils/constant";
import Http from "../../utils/http";
const uploaderHttp = new Http(host);

type UploadCallback = {
  onSuccess?(result: { url: string }): void;
  onFail?(error: any): void;
  /** [onStart]
   *
   * 开始上传回调函数，返回微信UploadTask
   *
   */
  onStart?(task: any): void;
  onProgressUpdate?(progress: any): void;
};

type UploadItem = {
  filePath: string;
  callback: UploadCallback;
};

// 上传并行控制
const UPLOAD_PARALLEL_COUNT = 2;
const UPLOAD_QUEUE: Array<UploadItem> = [];

// 单独上传一个并限制在上传并行数量中
export function uploadByQueue(filePath: string, callback: UploadCallback) {
  if (UPLOAD_QUEUE.length >= UPLOAD_PARALLEL_COUNT) {
    UPLOAD_QUEUE.push({
      filePath,
      callback,
    });
    return;
  }
  upload(filePath, {
    onFail: callback.onFail,
    onStart: callback.onStart,
    onProgressUpdate: callback.onProgressUpdate,
    onSuccess: (res) => {
      // 还有待上传的
      if (UPLOAD_QUEUE.length) {
        const item = UPLOAD_QUEUE.shift();
        if (item) {
          uploadByQueue(item.filePath, item.callback);
        }
      }
      callback.onSuccess && callback.onSuccess(res);
    },
  });
}

// 单独上传一个
export function upload(filePath: string, callback: UploadCallback): void {
  uploaderHttp
    .get("/file/getSts")
    .then((oss) => {
      const key =
        "uniapp-scan-code-" +
        guid() +
        filePath.slice(filePath.lastIndexOf("."));
      const uploadTask = wxUploadFile(
        oss.host,
        filePath,
        {
          key,
          policy: oss.policy,
          OSSAccessKeyId: oss.accesskeyId,
          expire: oss.expire,
          signature: oss.signature,
          success_action_status: "200",
        },
        {
          success: (res: any) => {
            if (res.statusCode == 200 && /ok/.test(res.errMsg)) {
              // https://kym-static.oss-cn-shenzhen.aliyuncs.com/uniapp-scan-code-41d308c3-2252-1b46-744a-104808f1c0c3.png
              callback.onSuccess &&
                callback.onSuccess({
                  url: `${oss.host}/${key}`,
                });
            } else {
              callback.onFail &&
                callback.onFail({
                  errMsg: `update error(${JSON.stringify(res)})`,
                });
            }
          },
          fail: callback.onFail,
          complete: () => {
            // 取消监听
            callback.onProgressUpdate &&
              uploadTask.offProgressUpdate(callback.onProgressUpdate);
          },
        }
      );
      callback.onStart && callback.onStart(uploadTask);
      if (callback.onProgressUpdate) {
        uploadTask.onProgressUpdate(callback.onProgressUpdate);
      }
    })
    .catch(callback.onFail);
}

function wxUploadFile(
  url: string,
  filePath: string,
  formData: any,
  callback: any
) {
  return uni.uploadFile({
    url,
    filePath,
    header: {
      // satoken: getApp<any>().globalData.token || "",
    },
    name: "file",
    formData,
    success: (res) => {
      callback.success && callback.success(res);
    },
    fail: (err) => {
      if (err && err.errMsg.indexOf("abort") >= 0) {
        // 主动中止s
        return;
      }
      callback.fail && callback.fail(err);
    },
    complete: () => {
      callback.complete && callback.complete();
    },
  });
}

function guid() {
  function S4() {
    return (((1 + Math.random()) * 0x10000) | 0).toString(16).substring(1);
  }
  return (
    S4() +
    S4() +
    "-" +
    S4() +
    "-" +
    S4() +
    "-" +
    S4() +
    "-" +
    S4() +
    S4() +
    S4()
  );
}
