<template>
  <div class="ellipsis">
    <div class="ellipsis__container" :style="{ 'font-size': `${fontSize}px`, 'line-height': lineHeight, color }">
      <div class="ellipsis__content" ref="contentEl" :style="{ height: `${preHeight}px`, 'align-items': alignItems }">{{ preContent }}</div>
      <div class="ellipsis__last-line" ref="lastLineEl" :style="{ height: `${lastLineHeight}px` }">{{ restContent }}
        <span v-if="isShowIconMethod()" :class="iconName"></span>
      </div>
    </div>
  </div>
</template>

<script>
export default {
  name: 'MultilineEllipsis',
  props: {
    fontSize: {
      type: Number,
      default: 12
    },
    color: {
      type: String,
      default: '#000000'
    },
    lineCount: {
      type: Number,
      default: 1
    },
    content: {
      type: String,
      default: ''
    },
    isOverflow: {
      type: Boolean,
      default: false
    },
    iconName: {
      type: String,
      default: 'el-icon-arrow-down'
    },
    overCountTip: {
      type: Object,
    },
    showIconObj: {
      type: Object,
      default: () => {
        return {
          isShowIcon: false,
          length: 0,
        }
      },
    },
  },
  data () {
    return {
      restContent: '',
      preContent: '',
      lastLineHeight: 0,
      alignItems: 'center'
    }
  },
  computed: {
    preHeight () {
      return (this.fontSize + 2) * (this.lineCount - 1)
    },
    lineHeight () {
      return `${this.fontSize + 2}px`
    }
  },
  mounted () {
    // 由于在 element table 中，渲染计算时的宽度可能与实际展示时的宽度可能存在偏差，在此把宽度固定为组件挂载时获取到的宽度
    this.$refs.contentEl.style.width = `${this.$refs.contentEl.offsetWidth}px`
    // 处理长度为1的数据不用走截取逻辑减少计算
    if (this.content.length === 1) {
      this.restContent = this.content;
      this.$refs.contentEl.remove();
      this.lastLineHeight = (this.fontSize + 2);
      return;
    }
    this.bsearch(this.content)
    this.lastLineHeight = (this.fontSize + 2)
  },
  methods: {
    bsearch (data, pre = 0) {
      const len = data.length
      const half = Math.floor((len - pre) / 2) + pre
      if (len - pre <= 1) {
        const restContent = pre === 0 ? this.content.slice(pre) : this.content.slice(pre + 1)
        this.preContent = pre === 0 ? '' : data.slice(0, pre + 1)
        if (!restContent) {
          this.lastLineHeight = 0
          this.$emit('update:isOverflow', false)
          return false
        }
        this.restContent = restContent
        this.$nextTick(() => {
          this.$emit('update:isOverflow', this.$refs.lastLineEl.scrollWidth !== this.$refs.lastLineEl.offsetWidth)
        })
        return true
      }
      this.preContent = data.slice(0, half + 1)
      this.$nextTick(() => {
        const isEqual = this.$refs.contentEl.scrollHeight === this.preHeight
        if (isEqual) {
          this.alignItems = 'center'
          return this.bsearch(data, half)
        }
        this.alignItems = 'flex-start'
        return this.bsearch(data.slice(0, half), pre)
      })
      return true
    },
    isShowIconMethod() {
      /**
       * 1、isShowIcon--是否展示icon; length-- 所有传入数据总数量
       * 2、this.overCountTip.index === this.overCountTip.length 当前列表展示个数(最后一个列)
       * 3、length > this.overCountTip.length 满足总个数大于当前列表展示个数
      **/ 
      const { isShowIcon, length } = this.showIconObj;
      return (isShowIcon && this.overCountTip.index === this.overCountTip.length && this.content.length && (length > this.overCountTip.length));
    }
  }
}
</script>

<style lang="less">
  .ellipsis {
    width: 100%;
    margin: 5px auto;
    &__content {
      width: 100%;
      overflow: hidden;
      display: flex;
    }
    &__last-line {
      width: 100%;
      overflow: hidden;
      white-space: nowrap;
      text-overflow: ellipsis;
    }
  }
</style>
