<template>
  <view>
    <!-- 表单输入框 -->
    <view v-if="formInput">
      <uni-easyinput
        v-model="inputVal"
        type="text"
        :placeholder="placeholder"
        :clearable="clearable"
        :readonly="readonly"
        @focus.stop="handleOpen('focus')"
      ></uni-easyinput>
    </view>
    <!-- 插槽 -->
    <view v-else @tap="handleOpen('slot')">
      <slot></slot>
    </view>
    <!-- 弹窗 -->
    <uni-popup ref="popup">
      <view class="popup-content" :style="popupStyle">
        <view class="popup-header">
          <view class="popup-title">{{ label }}</view>
          <uni-icons 
            type="closeempty" 
            size="24" 
            color="#999" 
            @tap="closePopup"
          />
        </view>
        
        <view class="popup-search" v-if="filter">
          <uni-easyinput
            v-model="keyword"
            type="text"
            :placeholder="searchPlaceholder"
            @input="inputChange"
            suffixIcon="search"
          ></uni-easyinput>
        </view>
        
        <scroll-view 
          class="popup-body" 
          scroll-y 
          :style="{ height: bodyHeight + 'px' }"
        >
          <view
            v-for="(level, levelIndex) in showList" 
            :key="levelIndex" 
            class="level-container"
          >
            <view v-if="!level.data?.length">
              {{ keyword ? '没有匹配的数据' : '暂无数据' }}
            </view>
            <template v-else>
              <view
                v-for="item in level.data" 
                :key="item[itemValue]" 
                class="item-container"
                :class="calcClass(item, levelIndex)"
                @tap="handleItemClick(item, levelIndex)"
              >
                <text class="item-label">{{ item[itemLabel] }}</text>
                <view class="item-icons">
                  <uni-icons 
                    v-if="isItemActive(item, levelIndex) && !hasChildren(item)"
                    type="checkmarkempty" 
                    color="#00B760" 
                    size="16"
                  />
                  <uni-icons 
                    v-if="hasChildren(item)"
                    type="arrowright" 
                    color="#999" 
                    size="16"
                  />
                </view>
              </view>
            </template>
          </view>
        </scroll-view>
        
        <view class="popup-footer" v-if="showFooter || multiple || isTreeData">
          <button 
            v-if="clearable" 
            class="btn cancel" 
            @tap="handleClear"
          >
            {{ clearText }}
          </button>
          <button 
            class="btn confirm" 
            @tap="handleConfirm"
            :disabled="!hasSelection"
          >
            {{ submitText }}
          </button>
        </view>
      </view>
    </uni-popup>
  </view>
</template>

<script setup>
import { ref, computed, watch, nextTick } from 'vue'
import { debounce } from 'lodash-es'

const emit = defineEmits(['update:value', 'update:text', 'change', 'search'])

const props = defineProps({
  // 基础属性
  value: [String, Number, Array, Object],
  text: String,
  items: {
    type: Array,
    default: () => []
  },
  label: {
    type: String,
    default: '请选择'
  },
  placeholder: {
    type: String,
    default: '请选择'
  },
  
  // 字段映射
  itemLabel: {
    type: String,
    default: 'label'
  },
  itemValue: {
    type: String,
    default: 'value'
  },
  children: {
    type: String,
    default: 'children'
  },
  
  // 功能开关
  multiple: Boolean,
  formInput: Boolean, // 表单右侧输入框
  filter: Boolean, // 可检索
  clearable: Boolean,
  readonly: Boolean,
  oneLevel: Boolean, // 不展示子级
  showFooter: { 
    type: Boolean,
    default: false
  },
  
  // 搜索相关
  searchPlaceholder: {
    type: String,
    default: '请输入'
  },
  searchDebounceTime: {
    type: Number,
    default: 500
  },
  
  // 样式
  popupStyle: [String, Object],
  
  // 文本自定义
  clearText: {
    type: String,
    default: '清除'
  },
  submitText: {
    type: String,
    default: '确定'
  }
})

  // 使用 lodash 的防抖
  const debouncedSearch = debounce((value) => {
  if (value = '') {
    showList.value = [{
      choose: props.multiple ? [] : -1,
      data: props.items
    }]
  } else {
    showList.value = [{
      choose: showList.value?.choose || -1,
      data: props.items?.length && props.items.map(j => j[props.itemLabel] && j[props.itemLabel].includes(value))
    }]
  }
  emit('search', value)
  }, props.searchDebounceTime)

const isTreeData = ref(false)

// 组件引用
const popup = ref()
const popupContent = ref()

// 数据状态
const inputVal = ref('')
const keyword = ref('')
const showList = ref([])
const bodyHeight = ref(400)

// 计算属性
const hasSelection = computed(() => {
  if (props.multiple) {
    return showList.value.some(level => Array.isArray(level.choose) && level.choose.length > 0)
  }
  return showList.value.some(level => level.choose !== -1)
})

// 初始化
const initShowList = () => {
  showList.value = [{
    choose: props.multiple ? [] : -1,
    data: props.items
  }]
}


const isItemActive = (item, levelIndex) => {
  const level = showList.value[levelIndex]
  if (!level) return false
  
  if (Array.isArray(level.choose)) {
    return level.choose.includes(item[props.itemValue])
  }
  return level.choose === item[props.itemValue]
}

const hasChildren = (item) => {
  return props.oneLevel ? false : Boolean(item[props.children] && item[props.children].length > 0)
}

// 方法
const calcClass = (item, levelIndex) => {
  return `${isItemActive(item, levelIndex) ? 'active' : ''}${hasChildren(item) ? 'has-children' : ''}`
}

const handleOpen = async () => {
  popup.value.open('bottom')
  await nextTick()
  calculateBodyHeight()
}

const closePopup = () => {
  popup.value.close()
}

const calculateBodyHeight = () => {
  if (!popupContent.value) return
  const query = uni.createSelectorQuery().in(popupContent.value)
  query.select('.popup-content').boundingClientRect(data => {
    if (data) {
      bodyHeight.value = data.height - 120 // 减去头部和底部高度
    }
  }).exec()
}

const handleItemClick = (item, levelIndex) => {
  // if ((!props.multiple && !item?.children?.length) || props.oneLevel) {
  //   inputVal.value = item[props.itemLabel]
  //   emit('update:value', item[props.itemValue])
  //   emit('change', item[props.itemValue], item)
  //   closePopup()
  //   return
  // }

  // 处理多选
  if (props.multiple) {
    handleMultiSelect(item, levelIndex)
    return
  }
  
  // 处理单选
  handleSingleSelect(item, levelIndex)
}

const handleSingleSelect = (item, levelIndex) => {
  const newShowList = [...showList.value]
  
  // 更新当前级别的选择
  newShowList[levelIndex].choose = item[props.itemValue]
  
  // 如果有子级，添加下一级
  if (!props.oneLevel && hasChildren(item)) {
    newShowList.splice(levelIndex + 1)
    newShowList.push({
      choose: -1,
      data: item[props.children]
    })
  } else {
    // 没有子级，截断后面的级别
    newShowList.splice(levelIndex + 1)
    // 最后一级，更新输出文本
    inputVal.value = item[props.itemLabel]
    emit('update:value', item[props.itemValue])
    emit('change', item[props.itemValue], item)
    closePopup()
  }
  
  showList.value = newShowList
}

const handleMultiSelect = (item, levelIndex) => {
  const newShowList = [...showList.value]
  const currentLevel = newShowList[levelIndex]
  
  // 初始化选择数组
  if (!Array.isArray(currentLevel.choose)) {
    currentLevel.choose = []
  }
  
  // 切换选择状态
  const index = currentLevel.choose.indexOf(item[props.itemValue])
  if (index === -1) {
    currentLevel.choose.push(item[props.itemValue])
  } else {
    currentLevel.choose.splice(index, 1)
  }
  
  showList.value = newShowList
}

const inputChange = () => {
  debouncedSearch(keyword.value)
}

const handleClear = () => {
  initShowList()
  inputVal.value = ''
  emit('update:value', props.multiple ? [] : null)
  emit('update:text', '')
  emit('change', props.multiple ? [] : null)
  closePopup()
}

const handleConfirm = () => {
  if (props.multiple) {
    const selectedValues = []
    const selectedLabels = []
    
    showList.value.forEach(level => {
      if (Array.isArray(level.choose)) {
        level.data.forEach(item => {
          if (level.choose.includes(item[props.itemValue])) {
            selectedValues.push(item[props.itemValue])
            selectedLabels.push(item[props.itemLabel])
          }
        })
      }
    })
    
    emit('update:value', selectedValues)
    emit('update:text', selectedLabels.join(','))
    emit('change', selectedValues)
  } else {
    const lastLevel = showList.value[showList.value.length - 1]
    const selectedItem = lastLevel.data.find(item => item[props.itemValue] === lastLevel.choose)
    
    if (selectedItem) {
      emit('update:value', selectedItem[props.itemValue])
      emit('update:text', selectedItem[props.itemLabel])
      emit('change', selectedItem[props.itemValue])
    }
  }
  
  closePopup()
}

// 监听props变化
watch(() => props.items, initShowList, { immediate: true })

watch(() => props.value, (newVal) => {
  // if (!newVal) {
  //   initShowList()
  //   inputVal.value = ''
  //   return
  // }
  // TODO: 实现回显逻辑
}, { immediate: true })

watch(() => props.text, (newVal) => {
  inputVal.value = newVal || ''
}, { immediate: true })
</script>

<style lang="scss" scoped>
.popup-content {
  background: #fff;
  border-radius: 16rpx 16rpx 0 0;
  padding: 24rpx;
  box-sizing: border-box;
  display: flex;
  flex-direction: column;
}

.popup-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding-bottom: 16rpx;
  border-bottom: 1rpx solid #eee;
}

.popup-title {
  font-size: 32rpx;
  font-weight: bold;
  color: #333;
}

.popup-search {
  padding: 24rpx 0;
}

.popup-body {
  flex: 1;
  overflow: hidden;
}

.level-container {
  margin-bottom: 16rpx;
}

.item-container {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 20rpx 16rpx;
  border-radius: 8rpx;
  margin-bottom: 8rpx;
  
  &.active {
    background-color: #f5fff9;
    color: #00B760;
  }
  
  &.has-children {
    background-color: #f9f9f9;
  }
}

.item-label {
  flex: 1;
  font-size: 28rpx;
}

.item-icons {
  margin-left: 16rpx;
}

.popup-footer {
  display: flex;
  justify-content: space-between;
  padding-top: 24rpx;
  border-top: 1rpx solid #eee;
  
  .btn {
    flex: 1;
    height: 80rpx;
    line-height: 80rpx;
    font-size: 28rpx;
    border-radius: 8rpx;
    
    &.cancel {
      background: #f5f5f5;
      color: #666;
      margin-right: 16rpx;
    }
    
    &.confirm {
      background: #00B760;
      color: #fff;
      
      &[disabled] {
        opacity: 0.6;
      }
    }
  }
}
</style>