import {
  computed,
  defineComponent,
  onUnmounted,
  PropType,
  ref,
  watch
} from 'vue';
// @ts-ignore
import style from './style/index.module.less';
import { ModalFuncPropsExtend } from './types';

const Progress = defineComponent({
  inheritAttrs: false,
  props: {
    fake: {
      type: Boolean
    },
    percent: {
      type: Function as PropType<ModalFuncPropsExtend['percent']>
    },
    status: {
      type: Function as PropType<ModalFuncPropsExtend['status']>
    },
    tips: {
      type: Object as PropType<ModalFuncPropsExtend['tips']>
    },
    successAutoClose: {
      type: Boolean
    },
    errorAutoClose: {
      type: Boolean
    }
  },
  emits: ['destoryModal'],
  setup(props, { emit }) {
    let fakeTimer: number;
    const fakeIncrease = () => {
      fakeTimer = setTimeout(() => {
        if (fakePercent.value < MAX_FAKE_PERCENT) {
          // 生成 [n,m] 随机数
          // parseInt(Math.random() * (m - n + 1) + n);
          fakePercent.value += parseInt(Math.random() * 5 + 1 + '', 10);
          fakeIncrease();
        } else {
          clearTimeout(fakeTimer);
        }
      }, parseInt(Math.random() * 1000 + 200 + '', 10));
    };
    // 开启虚拟递增
    props.fake && fakeIncrease();

    /**
     * 销毁当前这个 modal
     */
    const destoryModal = (delay = 1000) => {
      setTimeout(() => {
        emit('destoryModal');
      }, delay);
    };

    // 限制虚拟的最大值
    const MAX_FAKE_PERCENT = 98;
    const fakePercent = ref(0);

    const _percent = ref(0);
    const percent = computed({
      get: () => {
        // 进度为 100 时，直接返回 100
        if (_percent.value === 100) return _percent.value;
        let n = 0;
        // 判断当前是否开启虚拟进度
        if (props.fake) {
          n =
            fakePercent.value >= MAX_FAKE_PERCENT
              ? MAX_FAKE_PERCENT
              : fakePercent.value;
        } else {
          n = props.percent?.() || 0;
          n = n >= 100 ? 100 : n;
        }
        return n;
      },
      set: val => {
        _percent.value = val;
      }
    });

    /**
     * 提示
     */
    const tips = computed(() => {
      return props.tips?.[props.status?.() || 'normal'] || '&nbsp;';
    });

    const loading = computed(() => percent.value < 100);

    // 监听状态改变，状态都由外部控制
    watch(
      () => props.status?.(),
      val => {
        switch (val) {
          case 'normal':
            break;
          case 'loading':
            break;
          case 'success':
            if (props.fake) {
              clearTimeout(fakeTimer);
              percent.value = 100;
            }
            props.successAutoClose && destoryModal();
            break;
          case 'error':
            props.fake && clearTimeout(fakeTimer);
            props.errorAutoClose && destoryModal(1500);
            break;
          default:
            break;
        }
      }
    );

    onUnmounted(() => {
      // 清除计时器
      props.fake && clearTimeout(fakeTimer);
    });

    return () => (
      <div class="flex h-full justify-center items-center">
        <div class={style['progress']}>
          <div
            class={style['progress__text']}
            style={{ left: `${percent.value}%` }}
          >
            {percent.value}%
          </div>
          <div class={style['progress__outer']}>
            <div
              class={style['progress__inner']}
              style={{ left: `${percent.value - 100}%` }}
            >
              <img src={require('./assets/imgs/icon_progress.png')} />
            </div>
            {loading.value && props.status?.() !== 'error' ? (
              <div
                class={style['progress__bg']}
                style={{ width: `${percent.value}%` }}
              ></div>
            ) : null}
          </div>
          <div
            class={`${style['progress__tips']} ${
              props.status?.() === 'error' ? style['error'] : ''
            }`}
            v-html={tips.value || ''}
          ></div>
        </div>
      </div>
    );
  }
});
export default Progress;
