import { ref, reactive, computed, watch, onUnmounted, onMounted, h } from "vue";
import { defineVxeComponent } from "../../ui/src/comp.mjs";
import "../../ui/index.mjs";
import { getSlotVNs } from "../../ui/src/vn.mjs";
import VxeTextComponent from "../../text/src/text.mjs";
import XEUtils from "xe-utils";
import { getConfig } from "../../../../@vxe-ui/core/es/src/config.mjs";
import { useSize } from "../../../../@vxe-ui/core/es/src/useFns.mjs";
import { createEvent } from "../../../../@vxe-ui/core/es/src/event.mjs";
import { renderEmptyElement } from "../../../../@vxe-ui/core/es/index.esm.mjs";
import { getI18n } from "../../../../@vxe-ui/core/es/src/i18n.mjs";
const VxeCountdownComponent = defineVxeComponent({
  name: "VxeCountdown",
  props: {
    modelValue: [Number, String],
    format: String,
    prefixConfig: Object,
    suffixConfig: Object,
    size: {
      type: String,
      default: () => getConfig().countdown.size || getConfig().size
    }
  },
  emits: [
    "update:modelValue",
    "start",
    "end"
  ],
  setup(props, context) {
    const { slots, emit } = context;
    const xID = XEUtils.uniqueId();
    const refElem = ref();
    const { computeSize } = useSize(props);
    const reactData = reactive({
      currNum: 0,
      secondNum: 0
    });
    const internalData = {
      dnTimeout: void 0
    };
    const refMaps = {
      refElem
    };
    const computeTimeFormats = computed(() => {
      const { secondNum } = reactData;
      if (secondNum >= 316224e5) {
        return ["yyyy", "MM", "dd", "HH", "mm", "ss"];
      }
      if (secondNum >= 26784e5) {
        return ["MM", "dd", "HH", "mm", "ss"];
      }
      if (secondNum >= 864e5) {
        return ["dd", "HH", "mm", "ss"];
      }
      if (secondNum >= 36e5) {
        return ["HH", "mm", "ss"];
      }
      if (secondNum >= 6e4) {
        return ["mm", "ss"];
      }
      return ["ss"];
    });
    const computeDiffConf = computed(() => {
      const { currNum } = reactData;
      const diffRest = XEUtils.getDateDiff(Date.now(), Date.now() + currNum);
      return Object.assign(diffRest, { done: !(XEUtils.isBoolean(diffRest.status) ? diffRest.status : diffRest.done) });
    });
    const computeFormatLabel = computed(() => {
      const { format } = props;
      const diffConf = computeDiffConf.value;
      let rest = "";
      if (format) {
        rest = `${format}`;
        XEUtils.each(diffConf, (val, key) => {
          rest = rest.replace(new RegExp(key, "g"), XEUtils.padStart(val, key.length, "0"));
        });
        return rest;
      }
      return rest;
    });
    const computePrefixOpts = computed(() => {
      return Object.assign({}, props.prefixConfig, getConfig().countdown.prefixConfig);
    });
    const computeSuffixOpts = computed(() => {
      return Object.assign({}, props.suffixConfig, getConfig().countdown.suffixConfig);
    });
    const computeMaps = {
      computeSize
    };
    const $xeCountdown = {
      xID,
      props,
      context,
      reactData,
      internalData,
      getRefMaps: () => refMaps,
      getComputeMaps: () => computeMaps
    };
    const dispatchEvent = (type, params, evnt) => {
      emit(type, createEvent(evnt, { $carousel: $xeCountdown }, params));
    };
    const updateCount = () => {
      const secondNum = XEUtils.toNumber(props.modelValue || 0);
      reactData.secondNum = secondNum;
      reactData.currNum = secondNum;
    };
    const handleTime = () => {
      const { currNum } = reactData;
      if (currNum > 1e3) {
        reactData.currNum -= 1e3;
        internalData.dnTimeout = setTimeout(() => {
          handleTime();
        }, 1e3);
      } else {
        reactData.currNum = 0;
        handleStop();
      }
    };
    const countdownMethods = {
      dispatchEvent
    };
    const handleStart = () => {
      dispatchEvent("start", {}, null);
      handleTime();
    };
    const handleStop = () => {
      const { dnTimeout } = internalData;
      if (dnTimeout) {
        clearTimeout(dnTimeout);
        internalData.dnTimeout = void 0;
        dispatchEvent("end", {}, null);
      }
    };
    const countdownPrivateMethods = {};
    Object.assign($xeCountdown, countdownMethods, countdownPrivateMethods);
    const renderDefaultContentVNs = () => {
      const { format } = props;
      const timeFormats = computeTimeFormats.value;
      const diffConf = computeDiffConf.value;
      const formatLabel = computeFormatLabel.value;
      if (format) {
        return [
          h("div", {
            key: "format",
            class: "vxe-countdown--content-format"
          }, formatLabel)
        ];
      }
      return timeFormats.map((key, index) => {
        return h("div", {
          key: index,
          class: "vxe-countdown--content-item"
        }, [
          h("div", {
            class: "vxe-countdown--content-num"
          }, `${diffConf[key] || 0}`),
          h("div", {
            class: "vxe-countdown--content-unit"
          }, getI18n(`vxe.countdown.formats.${key}`))
        ]);
      });
    };
    const renderVN = () => {
      const { prefixConfig, suffixConfig } = props;
      const { currNum } = reactData;
      const vSize = computeSize.value;
      const diffConf = computeDiffConf.value;
      const prefixOpts = computePrefixOpts.value;
      const suffixOpts = computeSuffixOpts.value;
      const prefixSlot = slots.prefix;
      const suffixSlot = slots.suffix;
      const defaultSlot = slots.default;
      return h("div", {
        ref: refElem,
        class: ["vxe-countdown", diffConf.done ? "is--progress" : "is-end", {
          [`size--${vSize}`]: vSize
        }]
      }, [
        prefixSlot || prefixConfig ? h("div", {
          class: "vxe-countdown--prefix"
        }, prefixSlot ? getSlotVNs(prefixSlot({ currentValue: currNum, diffConf })) : [
          h(VxeTextComponent, {
            content: prefixOpts.content,
            icon: prefixOpts.icon,
            status: prefixOpts.status
          })
        ]) : renderEmptyElement(),
        h("div", {
          class: "vxe-countdown--content"
        }, defaultSlot ? getSlotVNs(defaultSlot({ currentValue: currNum, diffConf })) : renderDefaultContentVNs()),
        suffixSlot || suffixConfig ? h("div", {
          class: "vxe-countdown--suffix"
        }, suffixSlot ? getSlotVNs(suffixSlot({ currentValue: currNum, diffConf })) : [
          h(VxeTextComponent, {
            content: suffixOpts.content,
            icon: suffixOpts.icon,
            status: suffixOpts.status
          })
        ]) : renderEmptyElement()
      ]);
    };
    watch(() => props.modelValue, () => {
      updateCount();
      handleStop();
      handleStart();
    });
    onUnmounted(() => {
      handleStop();
    });
    onMounted(() => {
      handleStart();
    });
    updateCount();
    $xeCountdown.renderVN = renderVN;
    return $xeCountdown;
  },
  render() {
    return this.renderVN();
  }
});
export {
  VxeCountdownComponent as default
};
