import type { RawToast, IToast, ToastLoadingFunc, Options } from './types';

const DEFAULT_Z_INDEX = 10000;
const DEFAULT_DURATION = 2000;


let toastComp: RawToast;
function getToast(): Promise<RawToast>  {
  return new Promise((resolve) => {
    if (toastComp) {
      resolve(toastComp);
      return;
    }

    Promise.all(Toast.toastComponent())
      .then((comp: Array<{ default?: RawToast }>) => {
        const res = comp?.[0]?.default;
        if (res) {
          toastComp = res;
        }
        resolve(toastComp);
      });
  });
}
let toastCount = 0;


function show(text: Options = '', duration = DEFAULT_DURATION) {
  const zIndex = DEFAULT_Z_INDEX;
  let extra = {};
  let innerText = '';
  let innerDuration = duration;

  if (typeof text === 'string') {
    innerText = text;
  } else {
    extra = text;
    innerText = text.text || text.message || '';
    innerDuration = text.duration || DEFAULT_DURATION;
  }

  if (Toast.customUI) {
    getToast().then(() => {
      toastComp({
        ...extra,
        message: innerText,
        zIndex,
        duration: innerDuration,
      });
    });

    return;
  }


  // title 文本在小程序最多可显示两行
  toastCount = toastCount + 1;
  uni.showToast({
    title: innerText,
    icon: 'none',
    duration: innerDuration,
    success() {
      toastCount = toastCount - 1;
    },
    fail() {
      toastCount = toastCount - 1;
    },
  });
}


const Toast: IToast = function (options: Options, duration?: number) {
  return show(options, duration);
};

Toast.customUI = false;
Toast.toastComponent = () => [import('press-ui/press-toast/index')];

/**
 *
 * 设置自定义的 toast 组件
 * 小程序下默认使用平台提供的
 *
 * @param {function} comp 自定义组件引入方法
 *
 * @example
 *
 * ```ts
 * // 当设置 customUI 为 true，时，默认使用 Press UI
 * Toast.useCustomUI(true);
 *
 * // 也可以使用其他组件库
 * Toast.setComponent( () => [import('xxx')]);
 * ```
 */
Toast.setComponent = function (comp: ToastLoadingFunc) {
  Toast.toastComponent = comp;
};

/**
 *
 * 设置是否使用自定义的 toast 组件，可以在 main.js 中调用，全局生效
 *
 *
 * 如果使用 Press UI，需要注意提前预埋，
 * 参考：https://novlan1.github.io/docs/press-ui/components/press/press-toast.html#%E5%BC%95%E5%85%A5

* @param {boolean} [value=true] 是否使用自定义组件
 *
 * @example
 *
 * ```ts
 * // 当设置 customUI 为 true，时，默认使用 Press UI
 * Toast.useCustomUI(true);
 *
 * // 也可以使用其他组件库
 * Toast.setComponent( () => [import('xxx')]);
 * ```
 */
Toast.useCustomUI = function (value = true) {
  Toast.customUI = value;
};


function showSuccess(text: Options = '', duration = DEFAULT_DURATION) {
  let zIndex = DEFAULT_Z_INDEX;
  let extra = {};
  let innerText = '';
  let innerDuration = duration;
  if (typeof text === 'string') {
    innerText = text;
  } else {
    extra = text;
    innerText = text.text || text.message || '';
    innerDuration = text.duration || DEFAULT_DURATION;
    zIndex = text.zIndex || zIndex;
  }

  if (Toast.customUI) {
    getToast().then(() => {
      toastComp.success({
        ...extra,
        message: innerText,
        zIndex,
        duration: innerDuration,
      });
    });

    return;
  }

  if (innerText?.length <= 7) {
    // 在小程序平台最多显示 7 个汉字长度
    toastCount = toastCount + 1;
    uni.showToast({
      title: innerText,
      icon: 'success',
      duration,
      success() {
        toastCount = toastCount - 1;
      },
      fail() {
        toastCount = toastCount - 1;
      },
    });
  } else {
    Toast.show(innerText, innerDuration);
  }
}

function showFail(text: Options = '', duration = DEFAULT_DURATION) {
  let zIndex = DEFAULT_Z_INDEX;
  let extra = {};
  let innerText = '';
  let innerDuration = duration;
  if (typeof text === 'string') {
    innerText = text;
  } else {
    extra = text;
    innerText = text.text || text.message || '';
    innerDuration = text.duration || DEFAULT_DURATION;
    zIndex = text.zIndex || zIndex;
  }

  if (Toast.customUI) {
    getToast().then(() => {
      toastComp.fail({
        ...extra,
        message: innerText,
        zIndex,
        duration: innerDuration,
      });
    });

    return;
  }


  if (innerText?.length <= 7) {
    // 在小程序平台最多显示 7 个汉字长度
    toastCount = toastCount + 1;
    uni.showToast({
      title: innerText,
      icon: 'error',
      duration: innerDuration,
      success() {
        toastCount = toastCount - 1;
      },
      fail() {
        toastCount = toastCount - 1;
      },
    });
  } else {
    Toast.show(innerText, innerDuration);
  }
}

/**
    * 显示 loading
    * @name showLoading-mp
    * @param {string | object} options 配置，传递字符串时候为message
    * @param {string} options.message 内容
    * @param {number} options.duration 展示时长(ms)，值为 0 时，toast 不会消失
    * @param {boolean} options.forbidClick 是否禁止背景点击
    * @param {string} options.selector 自定义选择器
    */
function showLoading(options: Options = '') {
  if (typeof options === 'string') {
    if (Toast.customUI) {
      getToast().then(() => {
        toastComp.loading({ message: options, duration: 0, zIndex: DEFAULT_Z_INDEX });
      });
      return;
    }

    uni.showLoading({
      title: options,
      mask: false,
    });
  } else if (options.duration && options.duration > 0) {
    if (Toast.customUI) {
      getToast().then(() => {
        toastComp.loading(options);
      });
      return;
    }

    uni.showToast({
      title: options.message || '',
      icon: 'loading',
      duration: options.duration,
    });
  } else {
    if (Toast.customUI) {
      getToast().then(() => {
        toastComp.loading(options);
      });
      return;
    }

    uni.showLoading({
      title: options.message || '',
      mask: options.forbidClick,
    });
  }
}

/**
    * 清除loading
    */
function dismissLoading() {
  if (Toast.customUI) {
    getToast().then(() => {
      toastComp.clear();
    });
    return;
  }

  // 有toast不调用
  if (toastCount <= 0) {
    uni.hideLoading();
  }
}

Toast.show = show;

Toast.showSuccess = showSuccess;
Toast.success = showSuccess;

Toast.showFail = showFail;
Toast.fail = showFail;

Toast.showLoading = showLoading;
Toast.loading = showLoading;

Toast.dismissLoading = dismissLoading;
Toast.clear = dismissLoading;

export { Toast };

