<template>
  <el-popover
    :visible="visible"
    popper-class="icon-select-popper"
    :width="popperWidth"
    trigger="click"
    @update:visible="handleVisibleChange"
  >
    <Scrollbar>
      <ul v-if="filteredIcons.length > 0" class="icons" :style="{ width: iconsWidth }">
        <li
          v-for="item in filteredIcons"
          :key="item.id"
          :value="item.value"
          @click="select(item)"
        >
          <Icon :value="item.value" size="22px"/>
          <label>{{item.name}}</label>
        </li>
      </ul>
      <EmptyTip
        v-else
        :description="keyword.trim() === '' ? '没有图标可选，请先添加图标' : '未搜索到图标'"
      />
    </Scrollbar>
    <template #reference>
      <div
        ref="reference"
        :class="{
          reference__expand: visible,
          'reference__with-value': modelValue != null && modelValue !== ''
        }"
      >
        <el-input
          v-model="keyword"
          :readonly="!visible"
          placeholder="搜索图标"
          @keyup.space="disallowHidden"
          @keyup.enter="disallowHidden"
          @click="disallowHidden"
        >
          <template #prefix>
            <Icon :value="selectedIcon" size="20px" @click="disallowHidden"/>
          </template>
        </el-input>
        <span class="opera-icon-wrap">
          <span v-if="clearable" class="close-icon-wrap">
            <Icon value="Close" size="12px" @click="select()"/>
          </span>
          <Icon value="ArrowDown" class="icon-arrow-down"/>
        </span>
      </div>
    </template>
  </el-popover>
</template>

<script>
import { fetchAll } from '@/api/system/icon'
import Scrollbar from '@/components/common/Scrollbar'

export default {
  name: 'IconSelect',
  components: { Scrollbar },
  props: {
    modelValue: {
      required: true
    },
    // 是否可清除
    clearable: {
      default: true
    }
  },
  data () {
    return {
      visible: false,
      // popper宽度
      popperWidth: 0,
      // ul宽度
      iconsWidth: 0,
      // 搜索关键字
      keyword: '',
      // 图标列表
      list: [],
      // 是否不允许隐藏，用于处理点击输入框等部分时不隐藏选择框
      disallow: false
    }
  },
  watch: {
    visible () {
      if (!this.visible || this.popperWidth > 0) {
        return
      }
      this.popperWidth = this.$refs.reference.getBoundingClientRect().width
      this.iconsWidth = this.calcIconsWidth()
    }
  },
  computed: {
    // 图标
    filteredIcons () {
      if (this.keyword === '') {
        return this.list
      }
      return this.list.filter(item => item.name.indexOf(this.keyword) !== -1)
    },
    // 已选图标
    selectedIcon () {
      if (this.modelValue == null) {
        return null
      }
      // 找出选中的图标
      const targetIcon = this.list.find(item => item.value === this.modelValue)
      // - 如果未找到，则返回null
      if (targetIcon == null) {
        return null
      }
      return targetIcon.value
    }
  },
  methods: {
    // 处理visible变更
    handleVisibleChange (value) {
      if (this.visible && this.disallow) {
        this.disallow = false
        return
      }
      this.visible = value
    },
    // 获取图标列表
    fetchAll () {
      fetchAll()
        .then(icons => {
          this.list = icons
        })
        .catch(e => {
          this.$tip.apiFailed(e)
        })
    },
    // 确认选择
    select (icon) {
      this.visible = false
      if (icon == null) {
        this.$emit('update:modelValue', null)
        return
      }
      this.$emit('update:modelValue', icon.value)
    },
    // 计算ul真实宽度，每个图标占据80px，计算当前popper宽度可以放下多少个图标，并得到最终宽度值
    calcIconsWidth () {
      const count = Math.floor(this.popperWidth / 85)
      return (count * 80) + 'px'
    },
    // 标记为不允许隐藏
    disallowHidden () {
      if (this.visible) {
        this.disallow = true
      }
    }
  },
  created () {
    this.fetchAll()
  },
  mounted () {
    this.popperWidth = this.$refs.reference.getBoundingClientRect().width
    this.iconsWidth = this.calcIconsWidth()
  }
}
</script>

<style scoped lang="scss">
.el-tooltip__trigger {
  // 输入框
  :deep(.el-input) {
    .icon {
      color: #333;
    }
  }
  // hover状态
  &:hover {
    // 展示清空图标
    .close-icon-wrap {
      display: inline-flex !important;
      justify-content: center;
      align-items: center;
      border: 1px solid #ccc;
      border-radius: 50%;
      i {
        font-size: 12px;
        transform: scale(0.80);
      }
    }
    // 隐藏箭头
    .icon-arrow-down {
      display: none !important;
    }
  }
  // 展开状态，旋转下拉箭头
  &.reference__expand {
    .icon-arrow-down {
      transform: rotate(-180deg);
    }
  }
  // 操作图标
  .opera-icon-wrap {
    width: 12px;
    height: 12px;
    border-radius: 50%;
    position: absolute;
    right: 10px;
    top: 50%;
    transform: translateY(-50%);
    z-index: 9;
    display: flex;
    justify-content: center;
    align-items: center;
    i {
      color: #999;
      cursor: pointer !important;
    }
    // 清空图标
    .close-icon-wrap {
      display: none;
    }
    // 下拉箭头
    .el-icon-arrow-down {
      transition: all ease .15s;
    }
  }
}
</style>

<style lang="scss">
.icon-select-popper {
  height: 300px;
  box-sizing: border-box;
  .el-scrollbar .el-scrollbar__view {
    display: flex;
    justify-content: center;
  }
  // 图标列表
  .icons {
    display: flex;
    flex-wrap: wrap;
    li {
      width: 80px;
      height: 60px;
      padding: 5px;
      box-sizing: border-box;
      border-radius: 5px;
      display: flex;
      flex-direction: column;
      justify-content: center;
      align-items: center;
      transition: background ease .1s;
      color: #777;
      .icon {
        transition: color ease .1s;
      }
      label {
        display: block;
        text-align: center;
        width: 100%;
        font-size: 12px;
        margin-top: 2px;
        overflow: hidden;
        text-overflow: ellipsis;
        white-space: nowrap;
      }
      &:hover {
        background: #eee;
        color: var(--color-primary);
      }
    }
  }
  .empty-tip {
    height: 200px;
  }
}
</style>
