<template>
  <div
    ref="dragVerify"
    :style="dragVerifyStyle"
    class="drag_verify"
    @mouseleave="dragFinish"
    @mousemove="dragMoving"
    @mouseup="dragFinish"
    @touchend="dragFinish"
    @touchmove="dragMoving"
  >

    <div
      ref="progressBar"
      :class="{goFirst2:isOk}"
      :style="progressBarStyle"
      class="dv_progress_bar"
    >

    </div>
    <div
      ref="message"
      :style="textStyle"
      class="dv_text"
    >
      <slot
        v-if="$slots.textBefore"
        name="textBefore"
      ></slot>
      {{ message }}
      <slot
        v-if="$slots.textAfter"
        name="textAfter"
      ></slot>
    </div>

    <div
      ref="handler"
      :class="{goFirst:isOk}"
      :style="handlerStyle"
      class="dv_handler dv_handler_bg"
      @mousedown="dragStart"
      @touchstart="dragStart"
    >
      <a-icon type="double-right" />
    </div>

  </div>
</template>

<script>
export default {
  name: 'DragVerify',
  props: {
    isPassing: {
      type: Boolean,
      default: false
    },
    width: {
      type: Number,
      default: 250
    },
    height: {
      type: Number,
      default: 40
    },
    text: {
      type: String,
      default: 'swiping to the right side'
    },
    successText: {
      type: String,
      default: 'success'
    },
    background: {
      type: String,
      default: '#eee'
    },
    progressBarBg: {
      type: String,
      default: '#76c61d'
    },
    completedBg: {
      type: String,
      default: '#76c61d'
    },
    circle: {
      type: Boolean,
      default: false
    },
    radius: {
      type: String,
      default: '4px'
    },
    handlerIcon: {
      type: String,
      default: ''
    },
    successIcon: {
      type: String,
      default: ''
    },
    handlerBg: {
      type: String,
      default: '#fff'
    },
    textSize: {
      type: String,
      default: '14px'
    },
    textColor: {
      type: String,
      default: '#333'
    }
  },
  mounted: function () {
    const dragEl = this.$refs.dragVerify
    dragEl.style.setProperty('--textColor', this.textColor)
    dragEl.style.setProperty('--width', Math.floor(this.width / 2) + 'px')
    dragEl.style.setProperty('--pwidth', -Math.floor(this.width / 2) + 'px')
  },
  computed: {
    handlerStyle: function () {
      return {
        left: '0px',
        width: this.height + 'px',
        height: this.height + 'px',
        background: this.handlerBg
      }
    },
    message: function () {
      return this.isPassing ? this.successText : this.text
    },
    dragVerifyStyle: function () {
      return {
        width: this.width + 'px',
        height: this.height + 'px',
        lineHeight: this.height + 'px',
        background: this.background,
        borderRadius: this.circle ? this.height / 2 + 'px' : this.radius
      }
    },
    progressBarStyle: function () {
      return {
        background: this.progressBarBg,
        height: this.height + 'px',
        borderRadius: this.circle
          ? this.height / 2 + 'px 0 0 ' + this.height / 2 + 'px'
          : this.radius
      }
    },
    textStyle: function () {
      return {
        height: this.height + 'px',
        width: this.width + 'px',
        fontSize: this.textSize
      }
    }
  },
  data () {
    return {
      isMoving: false,
      x: 0,
      isOk: false
    }
  },
  methods: {
    dragStart: function (e) {
      if (!this.isPassing) {
        this.isMoving = true
        var handler = this.$refs.handler
        this.x =
          (e.pageX || e.touches[0].pageX) -
          parseInt(handler.style.left.replace('px', ''), 10)
      }
      this.$emit('handlerMove')
    },
    dragMoving: function (e) {
      if (this.isMoving && !this.isPassing) {
        var _x = (e.pageX || e.touches[0].pageX) - this.x
        var handler = this.$refs.handler
        if (_x > 0 && _x <= this.width - this.height) {
          handler.style.left = _x + 'px'
          this.$refs.progressBar.style.width = _x + this.height / 2 + 'px'
        } else if (_x > this.width - this.height) {
          handler.style.left = this.width - this.height + 'px'
          this.$refs.progressBar.style.width =
            this.width - this.height / 2 + 'px'
          this.passVerify()
        }
      }
    },
    dragFinish: function (e) {
      if (this.isMoving && !this.isPassing) {
        var _x = (e.pageX || e.changedTouches[0].pageX) - this.x
        if (_x < this.width - this.height) {
          this.isOk = true
          var that = this
          setTimeout(function () {
            that.$refs.handler.style.left = '0'
            that.$refs.progressBar.style.width = '0'
            that.isOk = false
          }, 500)
          this.$emit('passfail')
        } else {
          var handler = this.$refs.handler
          handler.style.left = this.width - this.height + 'px'
          this.$refs.progressBar.style.width =
            this.width - this.height / 2 + 'px'
          this.passVerify()
        }
        this.isMoving = false
      }
    },
    passVerify: function () {
      this.$emit('update:isPassing', true)
      this.isMoving = false
      var handler = this.$refs.handler
      handler.children[0].className = this.successIcon
      this.$refs.progressBar.style.background = this.completedBg
      this.$refs.message.style['-webkit-text-fill-color'] = 'unset'
      this.$refs.message.style.animation = 'slidetounlock2 3s infinite'
      this.$refs.message.style.color = '#fff'
      this.$emit('passCallback')
    },
    reset: function () {
      const oriData = this.$options.data()
      for (const key in oriData) {
        if (Object.prototype.hasOwnProperty.call(oriData, key)) {
          this.$set(this, key, oriData[key])
        }
      }
      var handler = this.$refs.handler
      var message = this.$refs.message
      handler.style.left = '0'
      this.$refs.progressBar.style.width = '0'
      handler.children[0].className = this.handlerIcon
      message.style['-webkit-text-fill-color'] = 'transparent'
      message.style.animation = 'slidetounlock 3s infinite'
      message.style.color = this.background
    }
  }
}
</script>

<style scoped>
.drag_verify {
  position: relative;
  background-color: #e8e8e8;
  text-align: center;
  overflow: hidden;
}

.drag_verify .dv_handler {
  position: absolute;
  top: 0px;
  left: 0px;
  cursor: move;
}

.drag_verify .dv_handler i {
  color: #666;
  padding-left: 0;
  font-size: 16px;
}

.drag_verify .dv_handler .el-icon-circle-check {
  color: #6c6;
  margin-top: 9px;
}

.drag_verify .dv_progress_bar {
  position: absolute;
  height: 34px;
  width: 0px;
}

.drag_verify .dv_text {
  position: absolute;
  top: 0px;
  color: transparent;
  -moz-user-select: none;
  -webkit-user-select: none;
  user-select: none;
  -o-user-select: none;
  -ms-user-select: none;
  background: -webkit-gradient(
    linear,
    left top,
    right top,
    color-stop(0, var(--textColor)),
    color-stop(0.4, var(--textColor)),
    color-stop(0.5, #fff),
    color-stop(0.6, var(--textColor)),
    color-stop(1, var(--textColor))
  );
  -webkit-background-clip: text;
  -webkit-text-fill-color: transparent;
  -webkit-text-size-adjust: none;
  animation: slidetounlock 3s infinite;
}

.drag_verify .dv_text * {
  -webkit-text-fill-color: var(--textColor);
}

.goFirst {
  left: 0px !important;
  transition: left 0.5s;
}

.goFirst2 {
  width: 0px !important;
  transition: width 0.5s;
}

@-webkit-keyframes slidetounlock {
  0% {
    background-position: var(--pwidth) 0;
  }
  100% {
    background-position: var(--width) 0;
  }
}

@-webkit-keyframes slidetounlock2 {
  0% {
    background-position: var(--pwidth) 0;
  }
  100% {
    background-position: var(--pwidth) 0;
  }
}
</style>
