<template>
  <div class="custom-cascader-wrapper">
    <el-input
      v-model="displayText"
      placeholder="请选择分类"
      size="medium"
      :clearable="clearable"
      @focus="toggleDropdown">
      <i
        slot="suffix"
        class="el-input__icon el-icon-arrow-up"
        :style="{
          transform: isVisible ? 'rotate(0deg)' : 'rotate(180deg)',
          transition: 'transform 0.2s'
        }"></i>
    </el-input>

    <transition name="cascader-dropdown">
      <div v-show="isVisible" class="cascader-dropdown">
        <div class="cascader-panels" v-if="panels.length > 0">
          <div
            v-for="(panel, panelIndex) in panels"
            :key="panelIndex"
            class="cascader-panel">
            <div class="search-container">
              <el-input
                v-model="panel.searchText"
                type="text"
                class="search-input"
                placeholder="搜索内容"
                @input="handleSearch(panelIndex)"
                @focus="handlePanelFocus"
                size="small">
                <i slot="suffix" class="el-input__icon el-icon-search"></i>
              </el-input>
            </div>
            <div class="options-container">
              <div
                v-for="(option, optionIndex) in panel.filteredOptions"
                :key="optionIndex"
                class="option-item"
                :class="{
                  selected: panel.selectedIndex === optionIndex,
                  'has-children':
                    option.childId ||
                    (option.children && option.children.length > 0)
                }"
                @click="handleOptionClick(panelIndex, optionIndex, option)">
                <div class="option-item-left">
                  <span class="option-text">{{ option.browseNodeName }}</span>
                  <div v-if="option.productType" class="product-type">
                    Product Type: {{ option.productType }}
                  </div>
                </div>
                <i
                  v-if="
                    option.childId ||
                    (option.children && option.children.length > 0)
                  "
                  class="el-icon-arrow-right expand-icon"></i>
              </div>
            </div>
          </div>
        </div>
        <div v-else class="no-data">暂无数据</div>
      </div>
    </transition>
  </div>
</template>

<script>
export default {
  name: 'CustomCascader',
  model: {
    prop: 'value',
    event: 'change'
  },
  props: {
    value: {
      type: Array,
      default: () => []
    },
    // 数据源
    options: {
      type: Array,
      default: () => []
    },
    // 是否支持搜索
    searchable: {
      type: Boolean,
      default: true
    },
    // 加载子节点的回调函数
    loadData: {
      type: Function,
      default: null
    },
    // 占位符
    placeholder: {
      type: String,
      default: '请选择'
    },
    // 是否禁用
    disabled: {
      type: Boolean,
      default: false
    },
    // 分隔符
    separator: {
      type: String,
      default: ' / '
    },
    clearable: {
      type: Boolean,
      default: true
    }
  },
  data() {
    return {
      panels: [],
      selectedPath: [],
      isVisible: false,
      selectedLabels: [],
      displayText: '',
      lastSelectedPathId: '',
      isInternalChange: false
    }
  },
  watch: {
    options: {
      handler() {
        if (!this.value || this.value.length === 0) {
          this.initPanels()
        } else {
          this.updatePanelsFromValue(this.value)
        }
      },
      immediate: true
    },
    value: {
      handler(newValue) {
        if (!this.isInternalChange) {
          this.updatePanelsFromValue(newValue)
        }
        this.isInternalChange = false
      },
      immediate: true
    }
  },
  mounted() {
    document.addEventListener('click', this.handleDocumentClick, true)
  },
  methods: {
    async updatePanelsFromValue(value) {
      if (!value || value.length === 0) {
        this.panels = []
        this.selectedPath = []
        this.selectedLabels = []
        this.displayText = ''
        this.lastSelectedPathId = ''
        this.initPanels()
        return
      }

      // 清空所有状态
      this.panels = []
      this.selectedPath = []
      this.selectedLabels = []
      this.displayText = ''

      if (!this.options || this.options.length === 0) {
        return
      }

      this.initPanels()

      // 逐级构建面板
      for (let i = 0; i < value.length; i++) {
        const currentValue = value[i]
        const currentPanel = this.panels[i]

        if (!currentPanel || !currentPanel.options) {
          break
        }

        // 在当前面板中查找对应的选项
        const currentOption = currentPanel.options.find(
          (option) => option.browseNodeId === currentValue
        )
        if (!currentOption) {
          break
        }

        // 更新选中状态
        const optionIndex = currentPanel.options.findIndex(
          (option) => option.browseNodeId === currentValue
        )
        currentPanel.selectedIndex = optionIndex

        // 更新路径和标签
        this.selectedPath = this.selectedPath.slice(0, i)
        this.selectedPath.push(currentValue)
        this.selectedLabels = this.selectedLabels.slice(0, i)
        this.selectedLabels.push(currentOption.browseNodeName)

        if (i < value.length - 1 && currentOption.childId) {
          try {
            await this.loadChildPanel(currentOption)
          } catch (error) {
            console.error('加载子面板失败:', error)
            break
          }
        } else {
          // 最后一级或没有子节点
          this.lastSelectedPathId = currentValue
          this.$emit('onUpdataValue', {
            val: this.selectedPath,
            resetCategoryAttributes: false
          })
          this.displayText = this.selectedLabels.join(this.separator)
          break
        }
      }
    },

    // 加载子面板
    loadChildPanel(parentOption) {
      return new Promise((resolve, reject) => {
        if (!this.loadData) {
          reject(new Error('loadData方法未提供'))
          return
        }

        this.loadData(parentOption, (children) => {
          if (children && children.length > 0) {
            const currentPanelIndex = this.panels.length - 1
            const expectedPanelIndex = this.selectedPath.length
            if (currentPanelIndex >= expectedPanelIndex) {
              this.panels[expectedPanelIndex] = {
                options: children,
                filteredOptions: [...children],
                searchText: '',
                selectedIndex: -1
              }
            } else {
              this.addPanel(children)
            }
            resolve()
          } else {
            reject(new Error('没有子节点数据'))
          }
        })
      })
    },
    toggleDropdown() {
      if (this.disabled) return
      this.isVisible = true
    },
    handlePanelFocus() {
      this.isVisible = true
    },

    // 初始化面板
    initPanels() {
      if (this.panels.length === 0 && this.options && this.options.length > 0) {
        this.panels.push({
          options: [...this.options],
          filteredOptions: [...this.options],
          searchText: '',
          selectedIndex: -1
        })
      }
    },
    handleSearch(panelIndex) {
      const panel = this.panels[panelIndex]
      if (!panel.searchText.trim()) {
        panel.filteredOptions = [...panel.options]
      } else {
        panel.filteredOptions = panel.options.filter((option) =>
          option.browseNodeName
            .toLowerCase()
            .includes(panel.searchText.toLowerCase())
        )
      }
    },

    async handleOptionClick(panelIndex, optionIndex, option) {
      const panel = this.panels[panelIndex]
      panel.selectedIndex = optionIndex
      this.selectedPath = this.selectedPath.slice(0, panelIndex)
      this.selectedPath.push(option.browseNodeId)
      this.selectedLabels = this.selectedLabels.slice(0, panelIndex)
      this.selectedLabels.push(option.browseNodeName)
      this.panels = this.panels.slice(0, panelIndex + 1)
      if (option.childId && this.lastSelectedPathId !== option.browseNodeId) {
        this.loadData(option, (children) => {
          if (children && children.length > 0) {
            this.addPanel(children)
          } else {
            this.lastSelectedPathId = option.browseNodeId
            this.isInternalChange = true
            this.$emit('change', this.selectedPath)
            this.displayText = this.selectedLabels.join(this.separator)
            this.isVisible = false
          }
        })
      } else {
        this.lastSelectedPathId = option.browseNodeId
        this.isInternalChange = true
        this.$emit('change', this.selectedPath)
        this.displayText = this.selectedLabels.join(this.separator)
        this.isVisible = false
      }
    },

    addPanel(options) {
      const existingPanel = this.panels.find(
        (panel) =>
          panel.options &&
          panel.options.length > 0 &&
          panel.options[0].browseNodeId === options[0].browseNodeId
      )

      if (!existingPanel) {
        this.panels.push({
          options: options,
          filteredOptions: [...options],
          searchText: '',
          selectedIndex: -1
        })

        // 添加面板后自动滚动到新面板
        this.$nextTick(() => {
          this.scrollToNewPanel()
        })
      }
    },

    // 滚动到新添加的面板
    scrollToNewPanel() {
      const panelsContainer = this.$el.querySelector('.cascader-panels')
      if (panelsContainer) {
        const newPanel = panelsContainer.lastElementChild
        if (newPanel) {
          const containerWidth = panelsContainer.clientWidth
          const newPanelLeft = newPanel.offsetLeft
          if (
            newPanelLeft + newPanel.offsetWidth >
            panelsContainer.scrollLeft + containerWidth
          ) {
            panelsContainer.scrollTo({
              left: newPanelLeft - containerWidth + newPanel.offsetWidth,
              behavior: 'smooth'
            })
          }
        }
      }
    },
    handleDocumentClick(event) {
      if (this.$el.contains(event.target)) {
        return
      }
      const target = event.target
      const isModal =
        target.closest('.el-message-box') ||
        target.closest('.el-dialog') ||
        target.closest('.el-message') ||
        target.closest('[role="dialog"]') ||
        target.closest('.modal') ||
        target.closest('.error-modal')
      if (isModal) {
        return
      }

      // 其他情况关闭级联选择器
      this.isVisible = false
    },
    getCheckedNodes() {
      return this.panels.map((panel, index) => {
        return panel.options.find(
          (option) => option.browseNodeId === this.selectedPath[index]
        )
      })
    }
  },
  beforeDestroy() {
    document.removeEventListener('click', this.handleDocumentClick, true)
  }
}
</script>

<style lang="scss" scoped>
.custom-cascader-wrapper {
  position: relative;
  display: inline-block;
  width: 100%;
}

.cascader-input {
  position: relative;
  display: flex;
  align-items: center;
  width: 100%;
  height: 32px;
  padding: 0 12px;
  border: 1px solid #dcdfe6;
  border-radius: 4px;
  background-color: #fff;
  cursor: pointer;
  transition: border-color 0.2s;

  &:hover {
    border-color: #c0c4cc;
  }

  &.is-focus {
    border-color: #409eff;
  }

  &.is-disabled {
    background-color: #f5f7fa;
    border-color: #e4e7ed;
    color: #c0c4cc;
    cursor: not-allowed;
  }
}

.input-content {
  flex: 1;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.selected-text {
  color: #606266;
  font-size: 14px;
}

.placeholder {
  color: #c0c4cc;
  font-size: 14px;
}

.arrow-icon {
  margin-left: 8px;
  font-size: 12px;
  color: #c0c4cc;
  transition: transform 0.2s;

  &.is-reverse {
    transform: rotate(180deg);
  }
}

.cascader-dropdown {
  position: absolute;
  top: 100%;
  left: 0;
  right: 0;
  z-index: 2000;
  margin-top: 4px;
  border: 1px solid #dcdfe6;
  border-radius: 4px;
  background: #fff;
  box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
}

.cascader-panels {
  display: flex;
  overflow-x: auto;
}

.cascader-panel {
  // flex: 1;
  width: 300px;
  min-width: 300px;
  border-right: 1px solid #ebeef5;
}

.search-container {
  position: relative;
  padding: 8px;
  border-bottom: 1px solid #ebeef5;
}

.search-icon {
  position: absolute;
  right: 16px;
  top: 50%;
  transform: translateY(-50%);
  font-size: 12px;
  color: #c0c4cc;
}

.options-container {
  max-height: 360px;
  overflow-y: auto;
}

.option-item {
  padding: 8px 12px;
  cursor: pointer;
  display: flex;
  justify-content: space-between;

  &:hover {
    background-color: #f5f7fa;
  }

  &.selected {
    background-color: #e6f7ff;
    color: #1890ff;
  }
  &.selected i {
    color: #1890ff;
  }
  &.has-children {
    .option-text {
      flex: 1;
    }
  }
}
.option-item-left {
  display: flex;
  flex-direction: column;
  flex: 1;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.option-text {
  font-size: 14px;
  line-height: 1.4;
}

.expand-icon {
  color: #333;
  font-size: 14px;
  margin-left: 8px;
}

.product-type {
  font-size: 10px;
  color: #909399;
  background: #f5f7fa;
  padding: 1px 4px;
  border-radius: 2px;
}

// 滚动条样式
.options-container::-webkit-scrollbar {
  width: 6px;
}

.options-container::-webkit-scrollbar-track {
  background: #f1f1f1;
}

.options-container::-webkit-scrollbar-thumb {
  background: #c1c1c1;
  border-radius: 3px;
}

.options-container::-webkit-scrollbar-thumb:hover {
  background: #a8a8a8;
}

// 下拉动画
.cascader-dropdown-enter-active,
.cascader-dropdown-leave-active {
  transition: opacity 0.2s, transform 0.2s;
}

.cascader-dropdown-enter,
.cascader-dropdown-leave-to {
  opacity: 0;
  transform: translateY(-10px);
}
.no-data {
  padding: 10px;
  text-align: center;
  color: #999;
}
</style>
