import { host } from "../utils/constant";

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 {
  const uploadTask = wxUploadFile(
    `${host}/file/upload`,
    filePath,
    {},
    {
      success: (res: any) => {
        if (res.statusCode == 200 && res.data) {
          try {
            const data = JSON.parse(res.data);
            if (data.message === "ok") {
              callback.onSuccess &&
                callback.onSuccess({
                  url: data.data.url,
                });
            } else {
              callback.onFail &&
              callback.onFail({
                errMsg: data.message,
              });
            }
          } catch (error) {
            callback.onFail &&
              callback.onFail({
                errMsg: `update error JSON.parse`,
              });
          }
        } 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);
  }
}

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();
    },
  });
}
