import { defineComponent, reactive, ref, watch } from 'vue';
import styles from './index.module.less';

const refAnimation = (callback: any) => {
  requestAnimationFrame(() => {
    requestAnimationFrame(() => {
      callback();
    });
  });
};

export default defineComponent({
  name: 'TheNoticeBar',
  props: {
    text: {
      type: String,
      default: ''
    },
    isAnimation: {
      type: Boolean,
      default: false
    },
    time: {
      type: Number,
      default: 5
    }
  },
  setup(props) {
    const wrapRef = ref();
    const contentRef = ref();
    const notiData = reactive({
      isActive: false,
      wrapWidth: 0,
      contentWidth: 0,
      contentStyle: {
        transitionDuration: '0s',
        transform: 'translateX(0px)'
      },
      time: null as any
    });
    const init = () => {
      if (notiData.isActive || !contentRef.value || !wrapRef.value) return;
      notiData.isActive = true;
      notiData.contentWidth = contentRef.value.getBoundingClientRect().width;
      notiData.wrapWidth = wrapRef.value.getBoundingClientRect().width;
      startAnimate();
    };
    const startAnimate = () => {
      if (notiData.contentWidth <= notiData.wrapWidth || !notiData.isActive) {
        notiData.contentStyle.transitionDuration = '0s';
        notiData.contentStyle.transform = 'translateX(0px)';
        return;
      }

      notiData.contentStyle.transitionDuration = props.time + 's';
      notiData.contentStyle.transform = 'translateX(-100%)';

      notiData.time = setTimeout(() => {
        notiData.contentStyle.transitionDuration = '0s';
        notiData.contentStyle.transform = `translateX(${notiData.wrapWidth}px)`;
        refAnimation(startAnimate);
      }, 5 * 1000);
    };
    const stopAnimate = () => {
      clearTimeout(notiData.time);
      notiData.isActive = false;
      notiData.contentStyle.transitionDuration = '0s';
      notiData.contentStyle.transform = 'translateX(0px)';
      notiData.time = null;
    };
    watch(
      () => props.isAnimation,
      val => {
        if (val) {
          refAnimation(init);
        } else {
          refAnimation(stopAnimate);
        }
      }
    );
    return () => (
      <div
        ref={wrapRef}
        class={[styles.wrap, props.isAnimation ? styles.isAnitaion : '']}
        onMouseenter={() => !props.isAnimation && init()}
        onMouseleave={() => !props.isAnimation && stopAnimate()}>
        <div
          ref={contentRef}
          style={notiData.contentStyle}
          class={styles.notice}>
          {props.text}
        </div>
      </div>
    );
  }
});
