<template>
  <!-- 行业选择器根容器 -->
  <div class="industry-selector" ref="selectorRef">

    <!-- 触发按钮：显示已选行业名称或默认文字"行业" -->
    <div class="industry-selector__trigger" :style="{ ...triggerStyle, ...(isHovered || visible ? hoverStyle : {}) }" @click="toggleDropdown" @mouseenter="isHovered = true" @mouseleave="isHovered = false">
      <span class="industry-selector__display" :style="displayStyle" :title="displayText">{{ displayText }}</span>
      <svg
        class="industry-selector__arrow"
        :class="{ 'industry-selector__arrow--open': visible }"
        :style="(isHovered || visible) && hoverStyle?.color ? { color: hoverStyle.color } : {}"
        viewBox="0 0 12 12"
        fill="none"
      >
        <path d="M3 4.5L6 7.5L9 4.5" stroke="currentColor" stroke-width="1.2" stroke-linecap="round" stroke-linejoin="round"/>
      </svg>
    </div>

    <!-- 下拉面板 -->
    <div
      v-if="visible"
      class="industry-selector__panel"
      :class="{ 'industry-selector__panel--one-col': level === 1 }"
      @click.stop
    >

      <!-- 选中区：小方块标签展示已选中的行业名称 -->
      <div class="industry-selector__selected-area" v-if="selectedItems.length">
        <span
          class="industry-selector__tag"
          v-for="item in selectedItems"
          :key="item.id"
        >
          {{ item.name }}
          <!-- 点击关闭图标移除该选中项 -->
          <svg class="industry-selector__tag-close" viewBox="0 0 12 12" @click="removeItem(item)">
            <path d="M3 3L9 9M9 3L3 9" stroke="currentColor" stroke-width="1.2" stroke-linecap="round"/>
          </svg>
        </span>
      </div>

      <!-- 搜索输入框：输入超过 2 个字符时触发模糊匹配 -->
      <div class="industry-selector__search-wrap">
        <input
          v-model="searchText"
          class="industry-selector__search"
          placeholder="搜索行业"
        />
      </div>

      <!-- 搜索结果列表（有匹配结果时显示） -->
      <div v-if="searchText.length >= 2 && searchResults.length" class="industry-selector__search-results">
        <div
          class="industry-selector__search-item"
          v-for="r in searchResults"
          :key="r.node.id"
          @click="handleSearchItemClick(r.node)"
        >
          <span>{{ r.path }}</span>
          <!-- 已选中项显示勾选图标 -->
          <svg v-if="isSelected(r.node.id)" class="industry-selector__check" viewBox="0 0 12 12">
            <path d="M2 6L5 9L10 3" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" fill="none"/>
          </svg>
        </div>
      </div>

      <!-- 搜索无结果提示 -->
      <div v-else-if="searchText.length >= 2 && !searchResults.length" class="industry-selector__search-results">
        <div class="industry-selector__search-empty">无匹配结果</div>
      </div>

      <!-- 提示：双击选中一级（仅 allowParentSelect 开启且 allowParentSelectClick 关闭时显示） -->
      <div v-if="searchText.length < 2 && allowParentSelect && !allowParentSelectClick" class="industry-selector__hint">（双击可选中一级行业分类）</div>

      <!-- 分栏联动选择区（搜索关键词不足 2 字符时显示） -->
      <div v-if="searchText.length < 2" class="industry-selector__columns">
        <!-- 左栏：一级行业列表 -->
        <div class="industry-selector__col industry-selector__col--left" :class="{ 'industry-selector__col--full': level === 1 }">
          <div
            class="industry-selector__col-item"
            :class="{
              'industry-selector__col-item--active': level > 1 && activeParentId === parent.id,
              'industry-selector__col-item--selected': (level === 1 || allowParentSelect || allowParentSelectClick) && isSelected(parent.id)
            }"
            v-for="parent in industries"
            :key="parent.id"
            @click="selectParent(parent.id)"
          >
            {{ parent.name }}
            <svg v-if="(level === 1 || allowParentSelect || allowParentSelectClick) && isSelected(parent.id)" class="industry-selector__check" viewBox="0 0 12 12">
              <path d="M2 6L5 9L10 3" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" fill="none"/>
            </svg>
          </div>
        </div>
        <!-- 右栏：当前一级下的二级行业列表（仅 level=2 时显示） -->
        <div v-if="level === 2" class="industry-selector__col industry-selector__col--right">
          <template v-if="activeChildren.length">
            <div
              class="industry-selector__col-item"
              :class="{ 'industry-selector__col-item--selected': isSelected(child.id) }"
              v-for="child in activeChildren"
              :key="child.id"
              @click="selectChild(child)"
            >
              {{ child.name }}
              <svg v-if="isSelected(child.id)" class="industry-selector__check" viewBox="0 0 12 12">
                <path d="M2 6L5 9L10 3" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" fill="none"/>
              </svg>
            </div>
          </template>
          <div v-else class="industry-selector__col-empty">请先选择左侧行业分类</div>
        </div>
      </div>

      <!-- 底部操作按钮 -->
      <div class="industry-selector__actions">
        <button class="industry-selector__btn industry-selector__btn--reset" @click="handleReset">重置</button>
        <button class="industry-selector__btn industry-selector__btn--confirm" @click="handleConfirm">确认</button>
      </div>
    </div>
  </div>
</template>

<script setup lang="ts">
import { ref, computed, onMounted, onBeforeUnmount, watch } from 'vue'
import { useStore } from 'vuex'
import type { IndustryChild, IndustryItem } from '@/api/common'

/** 统一的选中节点类型，兼容一二级 */
type SelectedNode = { id: string; name: string; level: number }

// ==================== 事件与属性定义 ====================

/** 向父组件发送已选行业 ID 数组（integer[]） */
const emit = defineEmits<{
  (e: 'update:industryIds', ids: number[]): void
}>()

/** 接收父组件传入的已选行业 ID 数组 */
const props = withDefaults(
  defineProps<{
    industryIds?: number[]
    /** 最多可选数量 */
    maxSelect?: number
    /** 是否允许双击选中一级行业 */
    allowParentSelect?: boolean
    /** 是否允许单击选中父级（选子级时自动移除已选的父级） */
    allowParentSelectClick?: boolean
    /** 展示/选择到第几级：1=只选一级，2=选到二级 */
    level?: 1 | 2
    /** 父组件传入的触发按钮自定义样式，用于在不同场景下覆盖默认外观 */
    triggerStyle?: Record<string, string>
    /** 父组件传入的触发按钮 hover 时的自定义样式 */
    hoverStyle?: Record<string, string>
    /** 父组件传入的显示文字自定义样式，用于覆盖 max-width 等默认样式 */
    displayStyle?: Record<string, string>
  }>(),
  {
    maxSelect: 3,
    allowParentSelect: false,
    allowParentSelectClick: false,
    level: 2,
  }
)

// ==================== 基础引用 ====================

/** Vuex store 实例 */
const store = useStore()

/** 组件根元素引用，用于点击外部关闭判断 */
const selectorRef = ref<HTMLElement | null>(null)

// ==================== 响应式状态 ====================

/** 下拉面板是否可见 */
const visible = ref(false)

/** 触发按钮是否处于 hover 状态 */
const isHovered = ref(false)

/** 搜索关键词 */
const searchText = ref('')

/** 当前选中的一级行业 ID（左栏高亮项） */
const activeParentId = ref<string>('')

/** 已选中的行业列表（支持一二级混合选择） */
const selectedItems = ref<SelectedNode[]>([])

/** 一级行业上次点击时间戳，用于双击检测 */
const level1LastClickTime = ref<Record<string, number>>({})

/** 双击判定间隔（毫秒） */
const DOUBLE_CLICK_DELAY = 500

// ==================== 计算属性 ====================

/** 从全局 store 获取行业树分类数据 */
const industries = computed<IndustryItem[]>(() => store.state.industries)

/** 已选中行业 ID 集合，用于快速判断某项是否选中 */
const selectedIdSet = computed(() => new Set(selectedItems.value.map(i => i.id)))

/** 触发按钮显示文字：无选中显示"行业"，有选中则用逗号拼接名称 */
const displayText = computed(() => {
  if (!selectedItems.value.length) return '行业'
  return selectedItems.value.map(i => i.name).join('，')
})

/** 当前左栏选中的一级行业对应的二级子项列表 */
const activeChildren = computed<IndustryChild[]>(() => {
  if (!activeParentId.value) return []
  const parent = industries.value.find(p => p.id === activeParentId.value)
  return parent ? parent.children : []
})

/** 搜索结果：根据 level 和 allowParentSelect/allowParentSelectClick 匹配对应级别 */
const searchResults = computed(() => {
  if (searchText.value.length < 2) return []
  const keyword = searchText.value.toLowerCase()
  const results: { path: string; node: SelectedNode }[] = []
  /** 是否允许选中父级 */
  const canSelectParent = props.allowParentSelect || props.allowParentSelectClick
  for (const parent of industries.value) {
    // 一级：level=1 时作为末级可搜索，或允许选中父级且 level=2 时可搜索
    if ((props.level === 1 || canSelectParent) && parent.name.toLowerCase().includes(keyword)) {
      results.push({ path: parent.name, node: { id: parent.id, name: parent.name, level: parent.level } })
    }
    if (props.level === 2) {
      for (const child of parent.children) {
        if (child.name.toLowerCase().includes(keyword)) {
          results.push({ path: `${parent.name} → ${child.name}`, node: { id: child.id, name: child.name, level: child.level } })
        }
      }
    }
  }
  return results
})

// ==================== 方法 ====================

/** 判断指定行业 ID 是否已被选中 */
function isSelected(id: string) {
  return selectedIdSet.value.has(id)
}

/** 点击左栏一级行业 */
function selectParent(id: string) {
  // level=1 时，一级就是末级，单击直接选中
  if (props.level === 1) {
    const l1 = industries.value.find(c => c.id === id)
    if (l1) toggleItem({ id: l1.id, name: l1.name, level: l1.level })
    return
  }
  // allowParentSelectClick 模式：单击直接选中一级，同时展开子级
  if (props.allowParentSelectClick) {
    const l1 = industries.value.find(c => c.id === id)
    if (l1) toggleItemWithHierarchy({ id: l1.id, name: l1.name, level: l1.level })
    activeParentId.value = id
    return
  }
  if (props.allowParentSelect) {
    const now = Date.now()
    const lastTime = level1LastClickTime.value[id] || 0

    if (now - lastTime < DOUBLE_CLICK_DELAY) {
      const l1 = industries.value.find(c => c.id === id)
      if (l1) toggleItem({ id: l1.id, name: l1.name, level: l1.level })
      level1LastClickTime.value[id] = 0
    } else {
      activeParentId.value = id
      level1LastClickTime.value[id] = now
    }
  } else {
    activeParentId.value = id
  }
}

/** 切换某个行业节点的选中/取消状态（支持一二级），超过上限时提示 */
function toggleItem(node: SelectedNode) {
  const idx = selectedItems.value.findIndex(i => i.id === node.id)
  if (idx >= 0) {
    selectedItems.value.splice(idx, 1)
  } else {
    if (selectedItems.value.length >= props.maxSelect) {
      ElMessage.warning(`最多只能选择${props.maxSelect}个行业`)
      return
    }
    selectedItems.value.push({ ...node })
  }
}

/**
 * allowParentSelectClick 模式下的选中/取消逻辑：
 * - 选中子级时，移除已选中的父级
 * - 选中父级时，移除已选中的该父级下的所有子级
 */
function toggleItemWithHierarchy(node: SelectedNode) {
  const idx = selectedItems.value.findIndex(i => i.id === node.id)
  if (idx >= 0) {
    // 取消选中
    selectedItems.value.splice(idx, 1)
    return
  }
  // 获取祖先和后代 ID
  const ancestorIds = getAncestorIds(node.id)
  const descendantIds = getDescendantIds(node.id)
  // 移除已选中的祖先和后代
  selectedItems.value = selectedItems.value.filter(
    i => !ancestorIds.has(i.id) && !descendantIds.has(i.id)
  )
  // 检查数量限制
  if (selectedItems.value.length >= props.maxSelect) {
    ElMessage.warning(`最多只能选择${props.maxSelect}个行业`)
    return
  }
  selectedItems.value.push({ ...node })
}

/** 获取某个节点的所有祖先 ID（向上查找） */
function getAncestorIds(nodeId: string): Set<string> {
  const ancestors = new Set<string>()
  for (const parent of industries.value) {
    for (const child of parent.children) {
      if (child.id === nodeId) {
        ancestors.add(parent.id)
        return ancestors
      }
    }
  }
  return ancestors
}

/** 获取某个节点的所有后代 ID（向下查找） */
function getDescendantIds(nodeId: string): Set<string> {
  const descendants = new Set<string>()
  for (const parent of industries.value) {
    if (parent.id === nodeId) {
      for (const child of parent.children) {
        descendants.add(child.id)
      }
      return descendants
    }
  }
  return descendants
}

/** 点击右栏二级行业 */
function selectChild(child: { id: string; name: string; level: number }) {
  if (props.allowParentSelectClick) {
    toggleItemWithHierarchy({ id: child.id, name: child.name, level: child.level })
  } else {
    toggleItem({ id: child.id, name: child.name, level: child.level })
  }
}

/** 搜索结果项点击处理 */
function handleSearchItemClick(node: SelectedNode) {
  if (props.allowParentSelectClick) {
    toggleItemWithHierarchy(node)
  } else {
    toggleItem(node)
  }
}

/** 从选中区移除指定行业 */
function removeItem(item: SelectedNode) {
  selectedItems.value = selectedItems.value.filter(i => i.id !== item.id)
}

/** 重置：清空所有已选项 */
function handleReset() {
  selectedItems.value = []
}

/** 确认：将当前选中结果发送给父组件并关闭面板 */
function handleConfirm() {
  emitIds()
  visible.value = false
}

/** 向父组件发送当前选中的行业 ID 数组（转为整数） */
function emitIds() {
  emit('update:industryIds', selectedItems.value.map(i => Number(i.id)))
}

/** 切换下拉面板的显示/隐藏，打开时清空搜索词并默认选中第一个一级行业 */
function toggleDropdown() {
  visible.value = !visible.value
  if (visible.value) {
    searchText.value = ''
    // 默认选中第一个一级行业
    if (industries.value.length && !activeParentId.value) {
      activeParentId.value = industries.value[0].id
    }
  }
}

/** 点击组件外部时关闭下拉面板 */
function onClickOutside(e: MouseEvent) {
  if (selectorRef.value && !selectorRef.value.contains(e.target as Node)) {
    visible.value = false
  }
}

// ==================== 生命周期 ====================

onMounted(() => {
  document.addEventListener('click', onClickOutside)
})

onBeforeUnmount(() => {
  document.removeEventListener('click', onClickOutside)
})

// ==================== 监听器 ====================

/** 同步外部传入的 industryIds 到内部选中状态（支持一二级） */
function syncFromProps() {
  const ids = props.industryIds
  if (!ids || !industries.value.length) return
  const nodeMap = new Map<string, SelectedNode>()
  for (const p of industries.value) {
    nodeMap.set(p.id, { id: p.id, name: p.name, level: p.level })
    for (const c of p.children) {
      nodeMap.set(c.id, { id: c.id, name: c.name, level: c.level })
    }
  }
  selectedItems.value = ids
    .map(id => nodeMap.get(String(id)))
    .filter(Boolean) as SelectedNode[]
}

watch(
  () => props.industryIds,
  () => syncFromProps(),
  { immediate: true }
)

/** 树数据加载完成后重新同步选中项 */
watch(industries, () => syncFromProps())
</script>
