import { defineComponent, ref, onUnmounted, onMounted } from 'vue';
import { countdownProps, CountdownProps } from './countdown-types';
import { getFormatTime, getLegalTime, getTimeSplit, getDeduplication, numFormat, intervalTimer } from './utils';
import './countdown.scss';

export default defineComponent({
  name: 'DCountdown',
  props: countdownProps,
  emits: ['onChange', 'onFinish'],
  setup(props: CountdownProps, ctx) {
    const timerCleaner = ref<(() => void) | undefined | null>();
    const s = getDeduplication(props.format);
    const timeFormat = getTimeSplit(props.format);
    const timeStr = ref('');

    const getTimeStr = (legalTime: Map<string, number>) => {
      const fomatMap = new Set(['Y', 'M', 'D', 'H', 'm', 's', 'S']);
      const t = timeFormat.reduce((pre, cur) => {
        if (fomatMap.has(cur.k)) {
          return pre + numFormat(legalTime.get(cur.k) || 0, cur.n);
        }
        return pre + cur.k;
      }, '');
      timeStr.value = t;
    };

    const getTime = () => {
      const value = new Date(props.value).getTime();
      const leftTime = value > new Date().getTime() ? value - new Date().getTime() : 0;
      const formatTime = getFormatTime(leftTime);
      const legalTime = getLegalTime(s, formatTime);
      !ctx.slots.default && getTimeStr(legalTime);
      ctx.emit('onChange', {
        leftTime,
        formatTime,
        legalTime,
      });
      return leftTime;
    };

    const startTime = () => {
      getTime();
      if (timerCleaner.value) {
        return;
      }
      timerCleaner.value = intervalTimer(
        () => {
          const t = getTime();
          if (t === 0) {
            ctx.emit('onFinish');
            timerCleaner.value?.();
            timerCleaner.value = null;
          }
        },
        s.has('S') ? 100 : 1000
      );
    };

    onMounted(() => {
      startTime();
    });
    onUnmounted(() => {
      timerCleaner.value?.();
    });
    return () => {
      return (
        <div class="devui-countdown">
          {ctx.slots.default ? (
            ctx.slots.default()
          ) : (
            <div class="countdown-content" style={props.valueStyle}>
              <span class="countdown-prefix">{props.prefix}</span>
              <span class="countdown-value">{timeStr.value}</span>
              <span class="countdown-suffix">{props.suffix}</span>
            </div>
          )}
        </div>
      );
    };
  },
});