<template>
  <div
    class="sv-index-item"
    :class="[{'is-link': isLink, 'is-divider': isDivider, 'slidable': slidable}, itemIconClass]"
    @click="handleClick">
    <div class="sv-item-main" ref="itemMainRef">
      <!-- avatar thumb back  -->
      <div class="sv-item-icon" ref="itemIconRef">
        <slot name="icon"></slot>
      </div>
      <!-- title subtitle content -->
      <div class="sv-item-section">
        <div class="sv-item-section-text" :style="{'margin-right': itemSectionRightWidth === 0 ? 0 : (itemSectionRightWidth + 20 + 'px')}">
          <p class="title">
            <slot name="title">{{title}}</slot>
          </p>
          <p class="subtitle">
            <slot name="subtitle">{{subtitle}}</slot>
          </p>
          <div class="content">
            <slot></slot>
          </div>
        </div>
        <!-- value note -->
        <div class="sv-item-section-value" ref="itemSectionValueRef">
          <slot name="value">{{value}}</slot>
        </div>
        <div class="sv-item-section-note" ref="itemSectionNoteRef">
          <slot name="note">{{note}}</slot>
        </div>
      </div>
      <!-- arrow -->
      <div class="sv-item-arrow" v-if="isLink">
        <i class="sv-icon-arrow-right" v-if="isLink"></i>
      </div>
    </div>
    <div class="sv-item-options" ref="itemOptionsRef" v-if="slidable && options && options.length > 0">
      <button class="button-option" v-for="option in options" :style="option.style" @click="handleOptionClick(option)">{{option.text}}</button>
    </div>
  </div>
</template>

<script type="text/ecmascript-6">
  export default {
    name: 'svIndexItem',
    data () {
      return {
        accordionIsActive: false,
        itemSectionRightWidth: 0,
        hasIcon: false,
        slideHandler: {
          itemMainTranslateX: 0,
          itemOptionsTranslateX: 0,
          threshold: 40 // 阈值
        }
      }
    },
    props: {
      isLink: {
        type: Boolean,
        default: false
      },
      to: String,
      title: String,
      subtitle: String,
      value: String,
      note: String,
      notePosition: {
        type: String,
        default: 'top'
      },
      isDivider: {
        type: Boolean,
        default: false
      },
      iconType: {
        type: String,
        default: '',
        validator (val) {
          if (val && val !== 'avatar' && val !== 'thumbnail') {
            console.error(`icon-type属性只有avatar和thumbnail两种取值，你指定的${val}为无效值，将被忽略`)
            return false
          }
          return true
        }
      },
      iconPosition: {
        type: String,
        default: 'left',
        validator (val) {
          if (val !== 'left' && val !== 'right') {
            console.error(`icon-position属性只有left和right两种取值，你指定的${val}为无效值，将被忽略`)
            return false
          }
          return true
        }
      },
      iconStyle: {
        type: [Object, String],
        default: '',
        validator (val) {
          let evil = (fn) => {
            fn = '(' + fn + ')'
            let Fn = Function // 一个变量指向Function，防止有些前端编译工具报错
            return new Fn('return ' + fn)()
          }

          if (!val) {
            return true
          }
          if (typeof val === 'string') {
            try {
              val = evil(val)
            } catch (e) {
              return false
            }
            return (typeof val === 'object')
          }
          return true
        }
      },
      slidable: {
        type: Boolean,
        default: false
      },
      options: {
        type: Array,
        default () {
          return []
        }
      }
    },
    computed: {
      itemIconClass () {
        let className = ''
        if (this.hasIcon) {
          className += 'has-icon'
          className += ` icon-position-${this.iconPosition} icon-type-${this.iconType}`
        }
        return className
      }
    },
    methods: {
      handleClick (event) {
        this.isLink && this.$router.push(this.to)
        if (this.isAccordion) {
          this.accordionIsActive = !this.accordionIsActive
        }
        this.$emit('click', event)
      },
      toObject (fn) {
        fn = '(' + fn + ')'
        let Fn = Function // 一个变量指向Function，防止有些前端编译工具报错
        try {
          return new Fn('return ' + fn)()
        } catch (e) {
          console.error(`${fn}不是一个JS字符串对象`)
          return null
        }
      },
      handleSlide () {
        let $el = this.$el
        let $itemOptions = this.$refs.itemOptionsRef
        let [beginX, currentX, endX, itemOptionsWidth] = [0, 0, 0, $itemOptions.clientWidth]
        let [beginTranslateX, endTranslateX] = [0, 0]
        this.slideHandler.itemOptionsTranslateX = itemOptionsWidth
        this.slideHandler.threshold = (itemOptionsWidth / 5).toFixed(2)
        console.log(this.slideHandler.threshold)
//        this.slide(this.slideHandler.itemOptionsTranslateX, $itemOptions)

        $el.addEventListener('touchstart', event => {
          beginX = event.touches[0].pageX
          beginTranslateX = this.slideHandler.itemMainTranslateX
        })
        $el.addEventListener('touchmove', event => {
          currentX = event.touches[0].pageX

          this.slideHandler.itemMainTranslateX += (currentX - beginX) / 2
          this.slideHandler.itemOptionsTranslateX += (currentX - beginX) / 2

          if (currentX < beginX) { // 向左滑动
            if (this.slideHandler.itemOptionsTranslateX > 0) {
              this.slide(this.slideHandler.itemMainTranslateX)
              this.slide(this.slideHandler.itemOptionsTranslateX, $itemOptions)
            } else {
              this.slideHandler.itemMainTranslateX = -itemOptionsWidth
              this.slideHandler.itemOptionsTranslateX = 0

              this.slide(this.slideHandler.itemMainTranslateX)
              this.slide(this.slideHandler.itemOptionsTranslateX, $itemOptions)
            }
          } else { // 向右滑动
            if (this.slideHandler.itemOptionsTranslateX < itemOptionsWidth) {
              this.slide(this.slideHandler.itemMainTranslateX)
              this.slide(this.slideHandler.itemOptionsTranslateX, $itemOptions)
            } else {
              this.slideHandler.itemMainTranslateX = 0
              this.slideHandler.itemOptionsTranslateX = itemOptionsWidth

              this.slide(this.slideHandler.itemMainTranslateX)
              this.slide(this.slideHandler.itemOptionsTranslateX, $itemOptions)
            }
          }
        })
        $el.addEventListener('touchend', event => {
          endX = event.changedTouches[0].pageX
          endTranslateX = this.slideHandler.itemMainTranslateX

          if (endX < beginX) { // 向左滑动
            if (Math.abs(endTranslateX - beginTranslateX) > this.slideHandler.threshold) {
              this.slideHandler.itemMainTranslateX = -itemOptionsWidth
              this.slideHandler.itemOptionsTranslateX = 0

              this.slide(-itemOptionsWidth)
              this.slide(0, $itemOptions)
            } else {
              this.slideHandler.itemMainTranslateX = 0
              this.slideHandler.itemOptionsTranslateX = itemOptionsWidth

              this.slide(0)
              this.slide(itemOptionsWidth, $itemOptions)
            }
          } else { // 向右滑动
            this.slideHandler.itemMainTranslateX = 0
            this.slideHandler.itemOptionsTranslateX = itemOptionsWidth

            this.slide(0)
            this.slide(itemOptionsWidth, $itemOptions)
          }
        })
      },
      slide (distance, target = this.$refs.itemMainRef, duration = 1) {
        target.style.transform = `translate3d(${distance}px, 0, 0)`
        target.style.transition = `transform ${duration}s ease-out`
      },
      handleOptionClick (option) {
        option.handler(this)
      },
      /**
       * 删除dom
       * 当用户左滑或者右滑添加删除按钮，点击删除按钮时，删除当前Item
       * 供外部调用
       */
      remove () {
        this.$el.remove()
      }
    },
    mounted () {
      if (!this.isAccordion) { // 不是二级列表时，计算section右侧的宽度
        let [itemSectionValueWidth, itemSectionNoteWidth] = [this.$refs.itemSectionValueRef.offsetWidth, this.$refs.itemSectionNoteRef.offsetWidth]
        this.itemSectionRightWidth = itemSectionValueWidth > itemSectionNoteWidth ? itemSectionValueWidth : itemSectionNoteWidth

        /*
         没有指定icon时，隐藏
         不加这段代码，用户需要展示图文时就需要在Item组件上传入 :has-icon="true"
         但是为了更加简单，有了这段代码，就不需要指定has-icon属性了
         */
        if (!this.$slots.icon || this.$slots.icon.length === 0) {
          this.hasIcon = false
          this.$refs.itemIconRef.style.display = 'none'
        } else {
          this.hasIcon = true
          this.$slots.icon.forEach(icon => {
            if (this.iconStyle) {
              let iconStyle = this.toObject(this.iconStyle)
              Object.keys(iconStyle).forEach(key => {
                this.$refs.itemIconRef.style[key] = iconStyle[key]
              })
            }
            icon.elm.style.width = '100%'
            icon.elm.style.height = '100%'
          })
        }
      }

      if (this.slidable && this.options && this.options.length > 0) {
        this.handleSlide()
      }
    }
  }
</script>

<style lang="scss" rel="stylesheet/scss">
  @import "../../styles/base";
  .sv-index-list{
    .sv-index-item{
      position: relative;
      display: flex;
      flex-flow: nowrap;
      list-style: none;
      margin-top:-1px;
      border-top:1px solid #e8e8e8;
      border-bottom:1px solid #e8e8e8;
      transition: background .2s;
      overflow: hidden;
      &.is-link{
        .sv-item-section{
          margin-right:pxToRem(60px);
        }
        &:active{
          background: #f2f2f2;
        }
      }
      &.is-divider{
        .sv-item-main{
          background: #f2f2f2;
        }
        .sv-item-section {
          .sv-item-section-text {
            .content {
              color: #222;
              font-weight: bold;
            }
          }
        }
      }
      &.has-icon{
        &.icon-type-avatar{
          .sv-item-icon{
            width: pxToRem(80);
            height: pxToRem(80);
            border-radius: pxToRem(10);
          }
        }
        &.icon-type-thumbnail{
          .sv-item-icon{
            width: pxToRem(160);
            height: pxToRem(160);
          }
        }
        &.icon-position-right{
          flex-direction: row-reverse;
          .sv-item-icon{
            margin-left: pxToRem(20);
          }
        }
        &.icon-position-left{
          .sv-item-icon{
            margin-right: pxToRem(20);
          }
        }
        .sv-item-section{
          align-self: flex-start;
        }
      }
      &.slidable{
        user-select: none;
      }
      .sv-item-main{
        flex-shrink: 0;
        width: 100%;
        padding:pxToRem(20px 30px);
        background: #fff;
        .sv-item-icon{
          width: pxToRem(100);
          height: pxToRem(100);
          overflow: hidden;
        }
        .sv-item-section{
          flex: 1;
          display: flex;
          justify-content: space-between;
          align-items: center;
          overflow: hidden;
          .sv-item-section-text{
            max-width: 100%;
            &.has-right{
              margin-right: pxToRem(80);
            }
            .title{
              line-height: 1.5;
              font-size: pxToRem(30);
              color:#000;
            }
            .subtitle{
              white-space: nowrap;
              overflow: hidden;
              text-overflow:ellipsis;
              font-size: pxToRem(26);
              color:#999;
            }
            .content{
              font-size: pxToRem(28);
              color:#333;
            }
          }
          .sv-item-section-value{
            flex-shrink: 0;
            display: flex;
            justify-content: center;
            align-items: center;
            max-width: pxToRem(200);
            white-space: nowrap;
            overflow: hidden;
            text-overflow: ellipsis;
            color:#999;
            font-size: pxToRem(26);
          }
          .sv-item-section-note{
            position: absolute;
            top: pxToRem(20);
            right: pxToRem(30);
            max-width: pxToRem(200);
            white-space: nowrap;
            overflow: hidden;
            text-overflow: ellipsis;
            color:#999;
            font-size: pxToRem(22);
          }
        }
        .sv-item-arrow{
          position: absolute;
          top:0;
          bottom:0;
          right:pxToRem(20px);
          display: flex;
          align-items: center;
          justify-content: center;
          width:pxToRem(40px);
          font-size: pxToRem(30px);
          color:#c3c3c3;
        }
      }
      .sv-item-options{
        position: absolute;
        top:0;
        right:0;
        bottom:0;
        display: flex;
        white-space: nowrap;
        transform: translate3d(100%, 0, 0);
        .button-option{
          flex: 1;
          padding: pxToRem(0 20);
          border: none;
          outline: none;
          background: $color-danger;
          font-size: pxToRem(28);
          color:$color-light;
          letter-spacing: pxToRem(4);
        }
      }
    }
  }
</style>
