<template>
  <div class="slider-verification" ref="sliderContainer">
    <div class="slider-left-bg" :style="sliderLeftWidthStyle"></div>
    <div class="prompt-text" :style="verifySuccess ? promptTextStyleSuccess : {}">
      {{ verifySuccess ? '验证成功' : '向右拖动滑块进行验证' }}
    </div>
    <div
      ref="slider"
      @mousedown="mouseDownHandler($event)"
      :class="{ 'slider-verify-success': verifySuccess }"
      class="slider"
      :style="sliderToLeftStyle"
    ></div>
  </div>
</template>

<script lang="ts">
  import { defineComponent, ref, onMounted, provide, inject } from 'vue';

  /**
   * 组件名称：
   * 组件描述：
   */
  export default defineComponent({
    name: 'SliderVerification',
    components: {},
    props: {
      /**
       * 验证成功提示文字样式
       */
      promptTextStyleSuccess: {
        type: Object,
        default: {
          color: '#ffffff',
        },
      },
      /**
       * 验证成功需要拖动距离倍数，倍数越大验证成功需要拖动的距离越大
       */
      multiple: {
        type: Number,
        default: 2,
      },
    },
    setup(props, context) {
      let sliderState = ref(false);
      // let verifySuccess = ref(false);
      // provide('verifySuccess', verifySuccess);
      const verifySuccess = inject('verifySuccess');
      let beginClientX = ref(0);
      let maxWidth = ref(0);
      const slideWidth = ref(0);
      const mouseMoveHandler = (e) => {
        if (sliderState.value) {
          let width = (e.clientX - beginClientX.value) / props.multiple;
          if (width > 0 && width <= maxWidth.value) {
            slideWidth.value = width;
          } else if (width > maxWidth.value) {
            slideWidth.value = maxWidth.value;
            verifySuccessFun();
          }
        }
      };
      const moseUpHandler = (e) => {
        sliderState.value = false;
        let width = (e.clientX - beginClientX.value) / props.multiple;
        if (width < maxWidth.value) {
          slideWidth.value = 0;
        }
      };
      const verifySuccessFun = () => {
        verifySuccess.value = true;
        context.emit('statusChange', true);
        document.getElementsByTagName('html')[0].removeEventListener('mousemove', mouseMoveHandler);
        document.getElementsByTagName('html')[0].removeEventListener('mouseup', moseUpHandler);
        slideWidth.value = maxWidth.value;
      };
      const slider = ref(null);
      const sliderContainer = ref(null);
      onMounted(() => {
        maxWidth.value = sliderContainer.value.offsetWidth - slider.value.offsetWidth;
        addListener();
      });
      const addListener = () => {
        document.getElementsByTagName('html')[0].addEventListener('mousemove', mouseMoveHandler);
        document.getElementsByTagName('html')[0].addEventListener('mouseup', moseUpHandler);
      };
      return {
        sliderContainer,
        slider,
        beginClientX, // 鼠标按下的位置
        sliderState, // 滑块是否可以移动
        maxWidth, // 滑块验证成功需要移动的最大距离
        verifySuccess, // 是否验证成功
        slideWidth, // 滑块滑过的区域宽度
        reset() {
          // 重置
          addListener();
          context.emit('statusChange', false);
          beginClientX.value = 0;
          sliderState.value = false;
          verifySuccess.value = false;
          slideWidth.value = 0;
        },
        mouseDownHandler(e) {
          // 鼠标在滑块上按下事件
          if (!this.verifySuccess) {
            this.sliderState = true;
            this.beginClientX = e.clientX;
          }
        },
      };
    },
    computed: {
      sliderToLeftStyle() {
        return {
          left: this.slideWidth + 'px',
        };
      },
      sliderLeftWidthStyle() {
        return {
          width: this.slideWidth + 'px',
        };
      },
    },
  });
</script>
<style scoped lang="less">
  .slider-verification {
    position: relative;
    box-shadow: inset 0px 0px 6px 2px #16c0ff;
    width: 100%;
    height: 100%;
    line-height: 48px;
    text-align: center;
    user-select: none;
  }

  .slider {
    position: absolute;
    top: 0;
    width: 42px;
    height: 100%;
    cursor: move;
    background: #0dc9ff
      url('data:image/png;base64,[encoded data, 5620 characters]')
      no-repeat center;
    background-size: 28px 28px;
    width: 46px;
    border-radius: 2px;
    scale: 0.75;
  }

  .slider-verify-success {
    background: #0dc9ff
      url('data:image/png;base64,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')
      no-repeat center;
    background-size: 28px 28px;
  }

  //滑块滑过区域的样式
  .slider-left-bg {
    background-color: rgba(0, 235, 255, 0);
    width: 0;
    height: 100%;
  }

  //提示文本样式
  .prompt-text {
    position: absolute;
    top: 0;
    width: 100%;
    height: 100%;
    text-align: center;
    font-size: 14px;
    line-height: 1;
    padding: 13px;
    color: #16C7FD !important;;
    opacity: 1;
  }
</style>
