<template>
  <div class="warehouse-selector">
    <el-input
      :model-value="modelValue"
      readonly
      placeholder="请选择库位"
      @click="handleOpen"
      clearable
      @clear="handleClear"
    >
      <template #suffix>
        <el-icon class="clear-icon" @click.stop="handleOpen">
          <ArrowDown />
        </el-icon>
      </template>
    </el-input>

    <el-popover
      ref="popoverRef"
      :visible="popoverVisible"
      placement="bottom-start"
      :width="380"
      trigger="click"
      @update:visible="handleVisibleChange"
    >
      <template #reference>
        <div ref="triggerRef" style="width: 0; height: 0; overflow: hidden;"></div>
      </template>

      <div class="selector-container">
        <!-- 顶部导航区 -->
        <div class="selector-header">
          <div class="header-left">
            <el-button
              v-if="currentPath.length > 0"
              type="primary"
              link
              size="small"
              @click="handleBack"
            >
              <el-icon><ArrowLeft /></el-icon>
              返回上一级
            </el-button>
          </div>
          <div class="header-right">
            <el-breadcrumb separator="/">
              <el-breadcrumb-item>
                <span class="breadcrumb-root" @click="handleGoHome">全部</span>
              </el-breadcrumb-item>
              <el-breadcrumb-item v-for="(item, index) in currentPath" :key="index">
                <span class="breadcrumb-item">{{ item.name }}</span>
              </el-breadcrumb-item>
            </el-breadcrumb>
          </div>
        </div>

        <!-- 列表展示区 -->
        <div class="selector-body">
          <div v-if="currentList.length === 0" class="empty-tip">
            当前层级无库位数据
          </div>
          <ul v-else class="location-list">
            <li
              v-for="item in currentList"
              :key="item.id"
              class="location-item"
              :class="{ 'is-selected': item.full_path === modelValue }"
            >
              <!-- 左侧热区：点击进入下级或选中 -->
              <div
                class="item-main"
                :class="{ 'has-children': item.children && item.children.length > 0 }"
                @click="handleItemClick(item)"
              >
                <el-icon class="item-icon"><Location /></el-icon>
                <span class="item-name">{{ item.name }}</span>
                <el-icon v-if="item.children && item.children.length > 0" class="item-arrow">
                  <ArrowRight />
                </el-icon>
              </div>
              <!-- 右侧操作区 -->
              <div class="item-actions">
                <el-tag v-if="!item.children || item.children.length === 0" type="info" size="small">
                  末级
                </el-tag>
                <el-button
                  v-else
                  type="primary"
                  size="small"
                  @click.stop="handleDrillDown(item)"
                >
                  进入下级
                  <el-icon><ArrowRight /></el-icon>
                </el-button>
              </div>
            </li>
          </ul>
        </div>
      </div>
    </el-popover>
  </div>
</template>

<script setup lang="ts">
import { ref, computed, watch } from 'vue'
import { ArrowDown, ArrowLeft, ArrowRight, Location } from '@element-plus/icons-vue'
import { ElMessage } from 'element-plus'

interface WarehouseItem {
  id: number
  name: string
  full_path: string
  level: number
  children?: WarehouseItem[]
}

interface Props {
  modelValue?: string
  options: WarehouseItem[]
}

const props = withDefaults(defineProps<Props>(), {
  modelValue: '',
  options: () => []
})

const emit = defineEmits<{
  'update:modelValue': [value: string]
}>()

const popoverRef = ref()
const popoverVisible = ref(false)
const triggerRef = ref<HTMLElement>()

// 当前导航路径（保存每一层的节点信息）
const currentPath = ref<WarehouseItem[]>([])

// 当前显示的列表数据
const currentList = computed(() => {
  if (currentPath.value.length === 0) {
    // 顶层：显示根节点列表
    return props.options
  }
  // 非顶层：显示当前层级最后一个节点的 children
  const lastNode = currentPath.value[currentPath.value.length - 1]
  return lastNode?.children || []
})

// 监听弹窗显示状态，恢复选中层级
watch(popoverVisible, (visible) => {
  if (visible) {
    restoreSelection()
  }
})

// 根据 modelValue 恢复选择状态
const restoreSelection = () => {
  if (!props.modelValue) {
    // 无选中值，重置到顶层
    currentPath.value = []
    return
  }

  // 根据 full_path 查找父级路径
  const path = findPathByFullPath(props.options, props.modelValue)
  if (path) {
    // 找到路径：还原 currentPath（不包含最后一个节点，因为它是当前选中的节点）
    currentPath.value = path
  } else {
    // 未找到（可能树结构已变化），重置到顶层
    currentPath.value = []
  }
}

// 根据 full_path 在树中查找从根到目标节点的路径
const findPathByFullPath = (
  tree: WarehouseItem[],
  targetFullPath: string,
  currentPath: WarehouseItem[] = []
): WarehouseItem[] | null => {
  for (const node of tree) {
    // 检查当前节点是否匹配
    if (node.full_path === targetFullPath) {
      return currentPath
    }

    // 递归检查子节点
    if (node.children && node.children.length > 0) {
      const result = findPathByFullPath(node.children, targetFullPath, [...currentPath, node])
      if (result) {
        return result
      }
    }
  }
  return null
}

// 处理弹窗显示/隐藏
const handleVisibleChange = (visible: boolean) => {
  popoverVisible.value = visible
  if (!visible) {
    // 关闭时重置导航
    currentPath.value = []
  }
}

// 打开弹窗
const handleOpen = () => {
  popoverVisible.value = true
}

// 清空选择
const handleClear = () => {
  emit('update:modelValue', '')
  currentPath.value = []
}

// 返回上一级
const handleBack = () => {
  if (currentPath.value.length > 0) {
    currentPath.value.pop()
  }
}

// 返回顶层
const handleGoHome = () => {
  currentPath.value = []
}

// 进入下一级
const handleDrillDown = (item: WarehouseItem) => {
  currentPath.value.push(item)
}

// 点击列表项 - 左侧热区逻辑
const handleItemClick = (item: WarehouseItem) => {
  if (item.children && item.children.length > 0) {
    // 有子节点：进入下一级
    handleDrillDown(item)
  } else {
    // 末级：直接选中
    handleSelect(item)
  }
}

// 选择当前项
const handleSelect = (item: WarehouseItem) => {
  emit('update:modelValue', item.full_path)
  popoverVisible.value = false
  currentPath.value = []
  ElMessage.success(`已选择库位：${item.full_path}`)
}
</script>

<style scoped>
.warehouse-selector {
  width: 100%;
}

.clear-icon {
  cursor: pointer;
}

.clear-icon:hover {
  color: #409eff;
}

.selector-container {
  margin: -12px;
}

.selector-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 12px;
  border-bottom: 1px solid #ebeef5;
  background: #f5f7fa;
}

.header-left {
  flex-shrink: 0;
}

.header-right {
  flex: 1;
  overflow: hidden;
}

.breadcrumb-root {
  cursor: pointer;
  color: #409eff;
}

.breadcrumb-root:hover {
  text-decoration: underline;
}

.breadcrumb-item {
  max-width: 150px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.selector-body {
  max-height: 320px;
  overflow-y: auto;
}

.empty-tip {
  padding: 40px 0;
  text-align: center;
  color: #909399;
}

.location-list {
  list-style: none;
  margin: 0;
  padding: 0;
}

.location-item {
  display: flex;
  align-items: center;
  justify-content: space-between;
  border-bottom: 1px solid #f0f0f0;
  transition: background 0.2s;
}

.location-item:last-child {
  border-bottom: none;
}

.location-item:hover {
  background: #f5f7fa;
}

/* 选中高亮样式 */
.location-item.is-selected {
  background: rgba(64, 158, 255, 0.1);
}

.location-item.is-selected .item-name {
  color: #409eff;
  font-weight: 500;
}

/* 左侧主热区 - 占80%宽度 */
.item-main {
  flex: 1;
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 14px 12px;
  cursor: pointer;
  min-width: 0;
}

.item-main.has-children {
  cursor: pointer;
}

.item-main:hover {
  background: rgba(64, 158, 255, 0.08);
}

.item-icon {
  color: #409eff;
  flex-shrink: 0;
}

.item-name {
  font-size: 14px;
  color: #303133;
  flex: 1;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.item-arrow {
  color: #c0c4cc;
  font-size: 12px;
  flex-shrink: 0;
}

/* 右侧操作区 */
.item-actions {
  display: flex;
  align-items: center;
  padding-right: 12px;
  flex-shrink: 0;
}
</style>
