<template>
  <div class="path-breadcrumb">
    <div class="breadcrumb-items">
      <template v-for="(segment, index) in segments" :key="index">
        <!-- 路径段 -->
        <div
          class="breadcrumb-segment"
          :class="{ 'is-hoverable': index < segments.length - 1 || segments.length === 1 }"
          @mouseenter="onHover(segment, index)"
          @mouseleave="onLeave"
          @click="onClick(segment)"
        >
          <span class="segment-text">{{ segment.name }}</span>

          <!-- 悬停弹出菜单 -->
          <Transition name="dropdown-fade">
            <div
              v-if="activeIndex === index"
              class="siblings-dropdown main-dropdown"
              @mouseenter="onMenuEnter"
              @mouseleave="onMenuLeave"
            >
              <div v-if="loading" class="dropdown-loading">
                <a-spin :size="16" />
                <span>加载中...</span>
              </div>
              <div v-else-if="error" class="dropdown-error">
                <icon-exclamation-circle />
                <span>{{ error }}</span>
              </div>
              <div v-else-if="!children.length" class="dropdown-empty">
                <icon-folder />
                <span>空文件夹</span>
              </div>
              <template v-else>
                <DropdownItem
                  v-for="child in children"
                  :key="child.path"
                  :item="child"
                  :level="1"
                  @navigate="onNavigate"
                  @openFile="onOpenFile"
                />
              </template>
            </div>
          </Transition>
        </div>

        <!-- 分隔符 -->
        <icon-right v-if="index < segments.length - 1" class="breadcrumb-separator" />
      </template>
    </div>
  </div>
</template>

<script setup lang="ts">
import { ref, computed, watch, provide, type Ref } from 'vue'
import { IconRight, IconFolder } from '@arco-design/web-vue/es/icon'
import { listDir } from '@/api/system'
import { sortFileList } from '@/utils/fileUtils'
import { useTimeout } from '@/composables/useTimeout'
import DropdownItem from './DropdownItem.vue'

const { setTimeout: delay, clearTimeout } = useTimeout()

const openMenus = ref<Map<number, string>>(new Map())

const closeMenu = (level: number) => {
  const newMap = new Map(openMenus.value)
  newMap.delete(level)
  openMenus.value = newMap
}

const closeAllMenus = () => {
  openMenus.value = new Map()
}

provide('openMenus', openMenus)
provide('closeMenu', closeMenu)
provide('closeAllMenus', closeAllMenus)

interface Props {
  path: string
}

const props = defineProps<Props>()

interface Emits {
  (e: 'navigate', path: string): void
  (e: 'openFile', path: string): void
}

const emit = defineEmits<Emits>()

interface PathSegment {
  name: string
  path: string
}

const segments = computed<PathSegment[]>(() => {
  if (!props.path) return []

  const path = props.path.replace(/\\/g, '/')

  // 根目录
  if (/^[A-Za-z]:\/?$/.test(path)) {
    const drive = path[0] + ':'
    return [{ name: drive, path: drive + '/' }]
  }

  return path.split('/').filter(Boolean).reduce<PathSegment[]>((acc, part, i) => {
    const prev = acc[i - 1]?.path || ''
    const current = part.endsWith(':') ? part + '/' : prev + (prev.endsWith('/') ? '' : '/') + part
    acc.push({ name: part, path: current })
    return acc
  }, [])
})

const activeIndex = ref<number | null>(null)
const hoverTimer = ref<NodeJS.Timeout | null>(null)
const closeTimer = ref<NodeJS.Timeout | null>(null)
const children = ref<Array<{ name: string; path: string; isDir: boolean }>>([])
const loading = ref(false)
const error = ref('')
const lastLoadedPath = ref('')

const loadChildren = async (path: string) => {
  if (path === lastLoadedPath.value) return

  loading.value = true
  error.value = ''

  try {
    const files = await listDir(path)
    lastLoadedPath.value = path
    children.value = sortFileList(files.map(f => ({
      name: f.name,
      path: f.path,
      isDir: f.isDir
    })))
  } catch (err) {
    console.error('[Breadcrumb] 加载子目录失败:', err)
    error.value = '加载失败'
  } finally {
    loading.value = false
  }
}

const resetAndClose = () => {
  activeIndex.value = null
  closeAllMenus()
}

const onHover = (segment: PathSegment, index: number) => {
  // 根目录（如 C:）只有一段，也允许悬停弹出子目录
  if (index === segments.value.length - 1 && segments.value.length > 1) return

  if (hoverTimer.value) clearTimeout(hoverTimer.value)
  if (closeTimer.value) clearTimeout(closeTimer.value)

  hoverTimer.value = delay(() => {
    activeIndex.value = index
    loadChildren(segment.path)
  }, 200)
}

const onMenuEnter = () => {
  if (hoverTimer.value) clearTimeout(hoverTimer.value)
  if (closeTimer.value) clearTimeout(closeTimer.value)
}

const onMenuLeave = () => {
  if (hoverTimer.value) clearTimeout(hoverTimer.value)
  closeTimer.value = delay(() => {
    resetAndClose()
  }, 100)
}

const onClick = (segment: PathSegment) => {
  emit('navigate', segment.path)
  resetAndClose()
}

const onNavigate = (path: string) => {
  emit('navigate', path)
  resetAndClose()
}

const onOpenFile = (path: string) => {
  emit('openFile', path)
  resetAndClose()
}

watch(() => props.path, () => {
  activeIndex.value = null
  children.value = []
  lastLoadedPath.value = ''
  openMenus.value = new Map()
})
</script>

<style scoped>
.path-breadcrumb {
  display: flex;
  align-items: center;
  flex: 1;
  min-width: 0;
}

.breadcrumb-items {
  display: flex;
  align-items: center;
  gap: 2px;
  flex-wrap: wrap;
}

.breadcrumb-segment {
  position: relative;
  display: inline-flex;
  align-items: center;
  padding: 4px 8px;
  border-radius: 4px;
  cursor: default;
  transition: background 0.2s;
  user-select: none;
}

.breadcrumb-segment.is-hoverable {
  cursor: pointer;
}

.breadcrumb-segment.is-hoverable:hover {
  background: var(--color-fill-2);
}

.segment-text {
  font-size: 13px;
  color: var(--color-text-1);
  white-space: nowrap;
}

.breadcrumb-separator {
  color: var(--color-text-3);
  font-size: 12px;
  flex-shrink: 0;
  margin: 0 1px;
}

/* 弹出菜单 */
.siblings-dropdown {
  position: absolute;
  top: calc(100% + 4px);
  left: 0;
  min-width: 200px;
  max-width: 280px;
  max-height: 320px;
  overflow-y: auto;
  background: var(--color-bg-popup);
  border: 1px solid var(--color-border);
  border-radius: var(--border-radius-small);
  box-shadow: var(--shadow2-dropdown);
  z-index: 1000;
  padding: 4px;
}

.dropdown-loading,
.dropdown-error,
.dropdown-empty {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  padding: 16px;
  color: var(--color-text-3);
  font-size: 13px;
}

/* 动画 */
.dropdown-fade-enter-active,
.dropdown-fade-leave-active {
  transition: opacity 0.15s, transform 0.15s;
}

.dropdown-fade-enter-from,
.dropdown-fade-leave-to {
  opacity: 0;
  transform: translateY(-4px);
}

/* 滚动条样式 */
.siblings-dropdown::-webkit-scrollbar {
  width: 6px;
}

.siblings-dropdown::-webkit-scrollbar-track {
  background: transparent;
}

.siblings-dropdown::-webkit-scrollbar-thumb {
  background: var(--color-fill-3);
  border-radius: 3px;
}

.siblings-dropdown::-webkit-scrollbar-thumb:hover {
  background: var(--color-fill-4);
}
</style>
