<template>
  <view>
    <view @tap="handleOpen">
      <slot></slot>
    </view>
    <uni-popup ref="popup">
      <view class="popup-content" :style="props.popupStyle">
        <view class="popup-content-label">
          <view class="popup-content-label-item active">{{ label }}</view>
        </view>
        <view class="popup-content-body">
          <view v-for="(arr, i) in showList" :key="i" class="popup-content-body-list">
            <!-- <view class="popup-content-body-list-label" :class="active === i ? 'active' : ''">{{ arr.label }}</view> -->
            <view class="popup-content-body-list-items">
              <view class="content">
                <view
                  v-for="_arr in arr.data"
                  :key="_arr[props.itemValue]"
                  class="py-1 dFlex"
                  :class="arr.choose === _arr[props.itemValue] || (Array.isArray(arr.choose) && arr.choose.includes(_arr[props.itemValue]))? 'active' : ''"
                  @tap="handleNext(_arr, i)"
                >
                  {{ _arr[props.itemLabel] }}
                  <uni-icons
                    v-if="Array.isArray(arr.choose) && arr.choose.includes(_arr[props.itemValue])"
                    type="checkmarkempty"
                    color="#00B760"
                    size="16"
                  />
                </view>
              </view>
            </view>
          </view>
        </view>
        <view class="popup-content-footer">
          <button class="btn cancel" @tap="reset">重置</button>
          <button class="btn submit" @tap="submit">确定</button>
        </view>
      </view>
    </uni-popup>
  </view>
</template>

<script setup>
import { ref, watch } from 'vue'

const emit = defineEmits(['change', 'init'])
const props = defineProps({
  popupStyle: {
    type: [String, Object],
    default: ''
  },
  value: {
    type: [String, Array, Number, Object],
    default: null
  },
  items: {  // 树结构
    type: Array,
    default: () => []
  },
  label: {
    type: String,
    default: ''
  },
  multiple: {
    type: Boolean,
    default: false
  },
  itemLabel: {
    type: String,
    default: 'label'
  },
  itemValue: {
    type: String,
    default: 'value'
  },
  children: {
    type: String,
    default: 'children'
  }
})

const popup = ref()
const showList = ref([])

watch(
  () => props.items,
  (val) => {
    // 初始化赋值
    showList.value = [{
      choose: -1,
      data: val
    }]
  },
  {
    immediate: true,
    deep: true
  }
)

const handleData = (val) => {
  if (!val) {
      showList.value = [{
        choose: -1,
        data: props.items
      }]
      return
    }
    // 单选 设置回显
    if (!props.multiple) {
      const item = findItem(val, props.items)
      if (!item) {
        showList.value = [{
          choose: -1,
          data: props.items
        }]
        return
      }
      showList.value = item.map(e => {
        return {
          choose: e[props.itemValue],
          data: e.data
        }
      })
      emit('init', item[item.length - 1][props.itemLabel])
      return
    }
    if (!Array.isArray(val)) {
      showList.value = [{
        choose: -1,
        data: props.items
      }]
      return
    }
    // 多选 设置回显
    const arr = []
    const label = []
    val.forEach(e => {
      const item = findItem(e, props.items)
      if (!item) {
        return
      }
      label.push(item[item.length - 1][props.itemLabel])
      if (!arr.length) {
        arr.push(...item.map((e, i) => {
          return {
            choose: i === item.length - 1 ? [e[props.itemValue]] : e[props.itemValue],
            data: e.data
          }
        }))
        return
      }
      arr[arr.length - 1].choose.push(item[item.length - 1][props.itemValue])
    })
    if (!arr.length) {
      showList.value = [{
        choose: -1,
        data: props.items
      }]
      return
    }
    showList.value = arr
    emit('init', label)
}

const findItem = (value, lists) => {
  let level = -1
  return check(value, lists)
  function check (val, items, arr = []) {
    let i = 0
    level++
    while (i < items.length) {
      arr[level] = {
        ...items[i],
        data: items
      }
      if (items[i][props.itemValue] === val) {
        return arr
      }
      if (items[i][props.children] && items[i][props.children].length > 0) {
        const data = check(val, items[i][props.children], arr)
        if (data) {
          return data
        }
      }
      i++
    }
    level--
    return false
  }
}

const handleOpen = () => {
  handleData(props.value)
  popup.value.open('bottom')
}

const handleNext = (item, index) => {
  const _i = index + 1
  // active.value = _i
  showList.value.splice(_i, showList.value.length - _i)
  showList.value[index].label = item[props.itemLabel]
  if (item[props.children] && item[props.children].length) {
    showList.value[index].choose = item[props.itemValue]
    showList.value.push({
      choose: -1,
      data: item[props.children]
    })
    return
  }
  if (!props.multiple) {
    showList.value[index].choose = item[props.itemValue]
    return
  }
  if (!Array.isArray(showList.value[index].choose)) {
    showList.value[index].choose = [item[props.itemValue]]
    return
  }
  if (!showList.value[index].choose.includes(item[props.itemValue])) {
    showList.value[index].choose.push(item[props.itemValue])
    return
  }
  const _index = showList.value[index].choose.indexOf(item[props.itemValue])
  showList.value[index].choose.splice(_index, 1)
}

const reset = () => {
  showList.value = [{
    choose: -1,
    data: props.items
  }]
  emit('change', props.multiple ? [] : null)
  popup.value.close()
}
const submit = () => {
  const item = showList.value[showList.value.length - 1]
  if (item.choose === -1) {
    const _item = showList.value[showList.value.length - 2]
    if (!item) {
      emit('change', props.multiple ? [] : null)
      popup.value.close()
      return
    }
    emit('change', props.multiple ? [_item.choose] : _item.choose, props.multiple ? showList.value[0].label : _item.label, item)
    popup.value.close()
    return
  }
  emit('change', item.choose, props.multiple ? showList.value[0].label : item.label, item)
  popup.value.close()
}

</script>

<style lang="scss" scoped>
.popup-content {
  height: 580px;
  background: #FFF;
  border-radius: 20rpx 20rpx 0 0;
  padding: 10px;
  box-sizing: border-box;
  display: flex;
  flex-direction: column;
  &-label {
    height: 50px;
    display: flex;
    font-size: 32rpx;
    font-weight: bold;
    margin-bottom: 10px;
    border-bottom: 2rpx solid #EEE;
    &-item {
      display: flex;
      align-items: center;
      padding: 0 15px;
      box-sizing: border-box;
      &.active {
        border-bottom: 2px solid #00B760;
      }
    }
  }
  &-body {
    flex: 1;
    height: 0;
    display: flex;
    &-list {
      height: 100%;
      min-width: 100px;
      margin-right: 20px;
      display: flex;
      flex-direction: column;
      &-label {
        border-bottom: 1px solid #eee;
        display: flex;
        align-items: center;
        justify-content: center;
        height: 50px;
        box-sizing: border-box;
        margin-bottom: 10px;
        &.active {
          border-bottom: 2px solid #00B760;
        }
      }
      &-items {
        flex: 1;
        height: 0;
        .content {
          height: 100%;
          overflow-x: hidden;
          overflow-y: auto;
          .active {
            color: #00B760;
          }
        }
      }
    }
  }
  &-footer {
    height: 50px;
    display: flex;
    align-items: center;
    .btn {
      font-size: 28rpx;
      height: 30px;
      line-height: 30px;
      &.cancel {
        width: 40%;
        margin-right: 10px;
      }
      &.submit {
        flex: 1;
        background: #00B760;
        color: #FFF ;
      }
    }
  }
}
.dFlex {
  display: flex;
  justify-content: space-between;
  height: 20px;
}
.py-1 {
  padding: 10px 0;
}
</style>