<template>
  <div class="task-select-tree" :style="{ width: componentWidth }">
    <el-popover
      ref="popover"
      placement="bottom-start"
      :width="popoverComputedWidth"
      trigger="click"
      v-model="popoverVisible"
      popper-class="task-select-tree-popper"
      :disabled="disabled"
      @show="onPopoverShow"
    >
      <div class="popover-content-wrapper">
        <el-input
          v-if="filterable"
          placeholder="输入关键字过滤"
          v-model="filterText"
          size="mini"
          clearable
          class="filter-input"
          @input="handleFilterDebounced"
        >
        </el-input>

        <div class="tree-container" :style="{ height: treeHeight + 'px' }">
          <div
            ref="virtualList"
            class="virtual-tree-list"
            @scroll="handleScroll"
            :style="{ height: treeHeight + 'px', overflow: 'auto' }"
          >
            <div
              class="virtual-content"
              :style="{
                height: totalHeight + 'px',
                position: 'relative',
                paddingTop: offsetY + 'px'
              }"
            >
              <div
                v-for="(item, index) in visibleItems"
                :key="`${item.key}-${item.level}-${index}`"
                :style="{
                  height: itemHeight + 'px',
                  paddingLeft: (item.level * indentSize) + 'px',
                  display: 'flex',
                  alignItems: 'center',
                  position: 'relative'
                }"
                :class="[
                  'virtual-tree-node',
                  {
                    'is-leaf': item.isLeaf,
                    'is-checked': checkedKeysSet.has(item.key) && (item.isLeaf || parentSelectable || !checkStrictly),
                    'is-disabled': item.nodeDisabled || checkboxDisabled(item) // Combined disabled state for row styling
                  }
                ]"
                @click="handleNodeClick(item)"
              >
                <div class="node-expand-container">
                  <i
                    v-if="!item.isLeaf"
                    :class="[
                      'node-expand-icon',
                      item.expanded ? 'el-icon-caret-bottom' : 'el-icon-caret-right'
                    ]"
                    @click.stop="toggleNodeExpand(item)"
                  ></i>
                  <span v-else class="node-expand-placeholder"></span>
                </div>

                <el-checkbox
                  :value="checkedKeysSet.has(item.key)"
                  :disabled="checkboxDisabled(item)"
                  @change="handleCheckboxChange(item, $event)"
                  @click.stop
                  class="node-checkbox"
                ></el-checkbox>

                <span class="node-label" :title="item.label">{{ item.label }}</span>

                <span v-if="item.isLeaf && showNodeDetail" class="node-detail-text">
                  (ID: {{ item.originalData.qwUserId || item.originalData.id }}{{ item.originalData.taskExecDate ? ' ' + item.originalData.taskExecDate : '' }})
                </span>
              </div>
            </div>
          </div>
        </div>

        <div class="popover-footer">
          <span class="selected-count">已选择: {{ displaySelectedCount }}</span>
          <el-button size="mini" @click="handleClearInPopover">清空</el-button>
          <el-button
            size="mini"
            :type="isAllCurrentResultsSelected ? 'warning' : 'info'"
            @click="handleSelectAllToggle"
          >
            {{ isAllCurrentResultsSelected ? '取消全选' : '全选' }}
          </el-button>
          <el-button type="primary" size="mini" @click="handleConfirm">确定</el-button>
        </div>
      </div>

      <div
        slot="reference"
        :class="['select-trigger-wrapper', { 'is-disabled': disabled, 'is-active': popoverVisible }]"
        @mouseenter="inputHovering = true"
        @mouseleave="inputHovering = false"
      >
        <div class="tags-or-value-container">
          <template v-if="multiple && displaySelectedNodes.length > 0">
            <el-tag
              v-for="node in displaySelectedNodes"
              :key="node.key"
              type="info"
              size="small"
              closable
              :disable-transitions="true"
              @close.stop="removeTag(node)"
              class="trigger-tag"
            >
              {{ node.label }}
            </el-tag>
            <el-tag
              v-if="displaySelectedCount > maxDisplayTags && displaySelectedNodes.length === maxDisplayTags"
              type="info"
              size="small"
              class="trigger-tag"
            >
              + {{ displaySelectedCount - maxDisplayTags }}
            </el-tag>
          </template>
          <span v-else-if="!multiple && displaySelectedCount > 0" class="single-value-display">
            {{ singleSelectedLabel }}
          </span>
          <span v-else class="placeholder-text">{{ placeholder }}</span>
        </div>

        <span class="icons-container">
          <i
            v-if="showClearIcon"
            class="el-icon-circle-close clear-icon"
            @click.stop="handleClearOnTrigger"
          ></i>
          <i :class="['el-icon-arrow-up', 'arrow-icon', { 'is-reverse': !popoverVisible }]"></i>
        </span>
      </div>
    </el-popover>
  </div>
</template>

<script>
// 防抖函数
function debounce(func, wait) {
  let timeout;
  return function executedFunction(...args) {
    const later = () => {
      clearTimeout(timeout);
      func(...args);
    };
    clearTimeout(timeout);
    timeout = setTimeout(later, wait);
  };
}

export default {
  name: 'OptimizedSelectTree',
  props: {
    value: {
      type: Array,
      default: () => []
    },
    rawData: {
      type: Array,
      required: true
    },
    placeholder: {
      type: String,
      default: '请选择'
    },
    multiple: {
      type: Boolean,
      default: false
    },
    disabled: { // Global disabled for the component
      type: Boolean,
      default: false
    },
    checkStrictly: {
      type: Boolean,
      default: false // Important for parent-child linkage
    },
    filterable: {
      type: Boolean,
      default: true
    },
    maxDisplayTags: {
      type: Number,
      default: 2
    },
    componentWidth: {
      type: String,
      default: '100%'
    },
    popoverWidth: {
      type: [String, Number],
      default: 'auto'
    },
    treeProps: {
      type: Object,
      default: () => ({
        children: 'children',
        label: 'label',
        isLeaf: 'isLeaf',
        disabled: 'disabled' // Key for disabled state in rawData
      })
    },
    nodeKey: {
      type: String,
      default: 'id'
    },
    defaultExpandAll: {
      type: Boolean,
      default: false
    },
    showNodeDetail: {
      type: Boolean,
      default: true
    },
    treeHeight: {
      type: Number,
      default: 280
    },
    returnLeafOnly: {
      // This prop's effect on output is now overridden.
      // It might still be used by consumers for other logic if they rely on its original meaning.
      type: Boolean,
      default: true
    },
    parentSelectable: {
      type: Boolean,
      default: false
    }
  },
  data() {
    return {
      popoverVisible: false,
      filterText: '',
      inputHovering: false,
      triggerElRect: null,
      itemHeight: 36,
      indentSize: 24,
      startIndex: 0,
      endIndex: 0,
      scrollTop: 0,
      visibleItemCount: 0,
      flattenedNodes: [],
      nodeMap: new Map(),
      checkedKeysSet: new Set(),
      expandedKeysSet: new Set(),
      updateTimer: null
    };
  },
  computed: {
    popoverComputedWidth() {
      if (this.popoverWidth === 'auto') {
        return this.triggerElRect ? this.triggerElRect.width : 300;
      }
      return parseInt(this.popoverWidth, 10);
    },
    totalHeight() {
      return this.visibleNodes.length * this.itemHeight;
    },
    offsetY() {
      return this.startIndex * this.itemHeight;
    },
    visibleNodes() {
      let nodes = this.flattenedNodes;
      if (this.filterText.trim()) {
        nodes = this.applyFilter(this.flattenedNodes);
      }

      const visible = [];
      for (const node of nodes) {
        if (this.isNodeCurrentlyVisible(node)) {
          visible.push(node);
        }
      }
      return visible;
    },
    visibleItems() {
      const items = this.visibleNodes.slice(this.startIndex, this.endIndex);
      return items.map(node => ({
        ...node,
        expanded: this.expandedKeysSet.has(node.key)
      }));
    },
    // Actual count of selected leaf items
    displaySelectedCount() {
      let leafCount = 0;
      this.checkedKeysSet.forEach(key => {
        const node = this.nodeMap.get(key);
        if (node && node.isLeaf) {
          leafCount++;
        }
      });
      return leafCount;
    },
    displaySelectedNodes() {
      if (!this.multiple) return [];
      const resultNodes = [];
      Array.from(this.checkedKeysSet)
        .map(key => this.nodeMap.get(key))
        .filter(Boolean)
        .forEach(node => {
          // Always display tags for leaf nodes that are selected.
          if (node.isLeaf) {
            resultNodes.push(node);
          }
        });
      return resultNodes.slice(0, this.maxDisplayTags);
    },
    singleSelectedLabel() {
      if (this.multiple || this.value.length === 0) return '';
      // 'value' prop should only contain leaf keys due to emitChange modification.
      // For single select, value should have at most one key.
      const selectedKey = String(this.value[0]);
      const node = this.nodeMap.get(selectedKey);
      // We expect 'value' to contain a leaf key.
      return node ? node.label : '';
    },
    showClearIcon() {
      return (
        !this.disabled &&
        this.inputHovering &&
        this.displaySelectedCount > 0 && // Based on leaf count now
        !this.multiple
      );
    },
    // 计算当前搜索结果中的所有叶子节点
    currentResultLeafNodes() {
      return this.visibleNodes.filter(node => node.isLeaf && !this.checkboxDisabled(node));
    },
    // 判断当前搜索结果是否全部选中
    isAllCurrentResultsSelected() {
      const leafNodes = this.currentResultLeafNodes;
      if (leafNodes.length === 0) return false;
      return leafNodes.every(node => this.checkedKeysSet.has(node.key));
    }
  },
  watch: {
    rawData: {
      handler(newData) {
        this.processRawData(newData);
        this.syncCheckedKeysFromValue();
      },
      immediate: true
    },
    value: {
      handler() {
        this.syncCheckedKeysFromValue();
      },
      deep: true,
    },
    filterText: {
      handler() {
        this.resetScroll();
      }
    },
    popoverVisible(isVisible) {
      if (isVisible) {
        this.$nextTick(() => {
          this.calculateVisibleRange();
        });
      }
    }
  },
  created() {
    this.handleFilterDebounced = debounce(this.filterTextChange, 300);
    this.visibleItemCount = Math.ceil(this.treeHeight / this.itemHeight) + 5;
  },
  methods: {
    filterTextChange() {
      this.resetScroll();
    },
    processRawData(data) {
      if (!Array.isArray(data)) {
        this.flattenedNodes = [];
        this.nodeMap.clear();
        return;
      }

      const flattened = [];
      const nodeMap = new Map();
      const expandedKeys = new Set();

      const processNode = (node, level = 0, parentKey = null) => {
        const children = node[this.treeProps.children] || [];
        const hasChildren = children.length > 0;
        const key = node[this.nodeKey];

        if (key === undefined || key === null) {
          console.warn('Node lacks a unique key:', node);
          return;
        }
        const strKey = String(key);

        let label = node[this.treeProps.label];
        if (typeof label !== 'string' || label.trim() === '') {
          label = node.name || node.title || node.text || `Node-${strKey}`;
        }

        const nodeDisabledByData = !!node[this.treeProps.disabled];

        const processedNode = {
          key: strKey,
          label: String(label).trim(),
          level,
          isLeaf: !hasChildren,
          nodeDisabled: nodeDisabledByData,
          parentKey: parentKey ? String(parentKey) : null,
          childrenKeys: hasChildren ? children.map(child => String(child[this.nodeKey])).filter(k => k !== undefined && k !== null) : [],
          originalData: node,
          hasChildren
        };

        flattened.push(processedNode);
        nodeMap.set(processedNode.key, processedNode);

        if (this.defaultExpandAll && hasChildren && !nodeDisabledByData) {
          expandedKeys.add(processedNode.key);
        }

        if (hasChildren) {
          children.forEach(child => processNode(child, level + 1, strKey));
        }
      };

      data.forEach(node => processNode(node));

      this.flattenedNodes = flattened;
      this.nodeMap = nodeMap;
      this.expandedKeysSet = new Set(expandedKeys);
    },

    isNodeCurrentlyVisible(node, currentExpandedSet = this.expandedKeysSet) {
      if (node.level === 0) return true;
      let current = node;
      while (current.parentKey) {
        const parent = this.nodeMap.get(current.parentKey);
        if (!parent || !currentExpandedSet.has(parent.key)) {
          return false;
        }
        current = parent;
      }
      return true;
    },

    applyFilter(nodesToFilter) {
      const searchText = this.filterText.toLowerCase().trim();
      if (!searchText) return nodesToFilter;

      const matchedNodeKeys = new Set();
      const newExpandedKeys = new Set(this.expandedKeysSet);

      nodesToFilter.forEach(node => {
        if (node.label.toLowerCase().includes(searchText)) {
          matchedNodeKeys.add(node.key);
          let parentKey = node.parentKey;
          while (parentKey) {
            const parentNode = this.nodeMap.get(parentKey);
            if (parentNode) {
              newExpandedKeys.add(parentKey);
              parentKey = parentNode.parentKey;
            } else {
              break;
            }
          }
        }
      });

      const filteredResult = nodesToFilter.filter(node => {
        return this.hasMatchInSubtreeOrSelf(node, searchText);
      });

      this.expandedKeysSet = newExpandedKeys;
      return filteredResult;
    },
    hasMatchInSubtreeOrSelf(node, searchText) {
      if (node.label.toLowerCase().includes(searchText)) {
        return true;
      }
      if (!node.isLeaf) {
        for (const childKey of node.childrenKeys) {
          const childNode = this.nodeMap.get(childKey);
          if (childNode && this.hasMatchInSubtreeOrSelf(childNode, searchText)) {
            return true;
          }
        }
      }
      return false;
    },
    checkboxDisabled(item) {
      if (item.nodeDisabled) return true;
      if (this.checkStrictly && !item.isLeaf && !this.parentSelectable) {
        return true;
      }
      return false;
    },

    calculateVisibleRange() {
      const containerHeight = this.treeHeight;
      const totalItems = this.visibleNodes.length;

      const newStartIndex = Math.floor(this.scrollTop / this.itemHeight);
      const visibleCountInViewport = Math.ceil(containerHeight / this.itemHeight);

      const buffer = 5;
      this.startIndex = Math.max(0, newStartIndex - buffer);
      this.endIndex = Math.min(totalItems, newStartIndex + visibleCountInViewport + buffer);
    },
    handleScroll(e) {
      const newScrollTop = e.target.scrollTop;
      if (newScrollTop !== this.scrollTop) {
        this.scrollTop = newScrollTop;
        if (!this.scrollRAF) {
          this.scrollRAF = requestAnimationFrame(() => {
            this.calculateVisibleRange();
            this.scrollRAF = null;
          });
        }
      }
    },
    resetScroll() {
      this.scrollTop = 0;
      if (this.$refs.virtualList) {
        this.$refs.virtualList.scrollTop = 0;
      }
      this.$nextTick(() => {
        this.calculateVisibleRange();
      });
    },
    toggleNodeExpand(node) {
      if (node.isLeaf || node.nodeDisabled) return;
      const key = node.key;
      if (this.expandedKeysSet.has(key)) {
        this.expandedKeysSet.delete(key);
      } else {
        this.expandedKeysSet.add(key);
      }
      this.expandedKeysSet = new Set(this.expandedKeysSet);
      this.$nextTick(() => this.calculateVisibleRange());
    },
    handleNodeClick(node) {
      if (node.nodeDisabled) return;

      if (!node.isLeaf && !this.parentSelectable) {
        this.toggleNodeExpand(node);
        return;
      }
      if (!node.isLeaf) {
        this.toggleNodeExpand(node);
        return;
      }

      if (!this.checkboxDisabled(node)) {
        const isCurrentlyChecked = this.checkedKeysSet.has(node.key);
        this.handleCheckboxChange(node, !isCurrentlyChecked);
      }
    },
    handleCheckboxChange(node, checked) {
      if (this.checkboxDisabled(node)) return;

      const newCheckedKeys = new Set(this.checkedKeysSet);
      const canNodeItselfBeInSet = node.isLeaf || this.parentSelectable || !this.checkStrictly;

      if (checked) {
        if (!this.multiple) {
          newCheckedKeys.clear();
        }
        if (canNodeItselfBeInSet) {
          newCheckedKeys.add(node.key);
        }
        if (!this.checkStrictly) {
          this.selectAllChildren(node, newCheckedKeys);
          this.checkParentSelection(node, newCheckedKeys);
        }
      } else {
        if (canNodeItselfBeInSet) {
          newCheckedKeys.delete(node.key);
        }
        if (!this.checkStrictly) {
          this.unselectAllChildren(node, newCheckedKeys);
          this.uncheckParentSelection(node, newCheckedKeys);
        }
      }
      this.checkedKeysSet = newCheckedKeys;
      this.emitChange();
    },
    selectAllChildren(node, checkedKeys) {
      if (node.childrenKeys && node.childrenKeys.length > 0) {
        node.childrenKeys.forEach(childKey => {
          const childNode = this.nodeMap.get(childKey);
          if (childNode && !childNode.nodeDisabled) {
            const canChildBeInSet = childNode.isLeaf || this.parentSelectable || !this.checkStrictly;
            if(canChildBeInSet){
              checkedKeys.add(childKey);
            }
            if (!childNode.isLeaf) {
              this.selectAllChildren(childNode, checkedKeys);
            }
          }
        });
      }
    },
    unselectAllChildren(node, checkedKeys) {
      if (node.childrenKeys && node.childrenKeys.length > 0) {
        node.childrenKeys.forEach(childKey => {
          const childNode = this.nodeMap.get(childKey);
          if (childNode) {
            const canChildBeInSet = childNode.isLeaf || this.parentSelectable || !this.checkStrictly;
            if(canChildBeInSet){
              checkedKeys.delete(childKey);
            }
            if (!childNode.isLeaf) {
              this.unselectAllChildren(childNode, checkedKeys);
            }
          }
        });
      }
    },
    checkParentSelection(node, checkedKeys) {
      if (!node.parentKey || this.checkStrictly) return;

      const parentNode = this.nodeMap.get(node.parentKey);
      if (parentNode && !parentNode.nodeDisabled && (this.parentSelectable || !this.checkStrictly)) {
        const allChildrenChecked = parentNode.childrenKeys.every(childKey => {
          const child = this.nodeMap.get(childKey);
          return !child || child.nodeDisabled || checkedKeys.has(childKey);
        });

        if (allChildrenChecked) {
          checkedKeys.add(parentNode.key);
          this.checkParentSelection(parentNode, checkedKeys);
        }
      }
    },
    uncheckParentSelection(node, checkedKeys) {
      if (!node.parentKey || this.checkStrictly) return;
      const parentNode = this.nodeMap.get(node.parentKey);
      if (parentNode && (this.parentSelectable || !this.checkStrictly)) {
        if (checkedKeys.has(parentNode.key)) {
          checkedKeys.delete(parentNode.key);
          this.uncheckParentSelection(parentNode, checkedKeys);
        }
      }
    },
    emitChange() {
      let finalKeys = [];
      const currentInternalCheckedKeys = Array.from(this.checkedKeysSet);

      // ALWAYS return only leaf nodes in the emitted value.
      currentInternalCheckedKeys.forEach(key => {
        const node = this.nodeMap.get(key);
        if (node && node.isLeaf) {
          finalKeys.push(key);
        }
      });

      finalKeys = [...new Set(finalKeys)]; // Deduplicate
      const finalNodes = finalKeys.map(k => this.nodeMap.get(k)).filter(Boolean);

      this.$emit('input', finalKeys);
      this.$emit('change', finalKeys, finalNodes);
    },
    syncCheckedKeysFromValue() {
      const newCheckedKeys = new Set();
      if (Array.isArray(this.value)) {
        this.value.forEach(key => {
          const strKey = String(key);
          const node = this.nodeMap.get(strKey);
          if (node) {
            // Value should ideally contain leaf keys if controlled by this component.
            // If an external value has a parent key, handle it for internal consistency.
            newCheckedKeys.add(strKey);
            if (!node.isLeaf && !this.checkStrictly) {
              this.selectAllChildren(node, newCheckedKeys);
              this.checkParentSelection(node, newCheckedKeys);
            } else if (node.isLeaf && !this.checkStrictly) {
              // If a leaf is added from value, ensure its parent's state is updated
              this.checkParentSelection(node, newCheckedKeys);
            }
          }
        });
      }
      this.checkedKeysSet = newCheckedKeys;

      if(this.popoverVisible) {
        this.$nextTick(() => this.calculateVisibleRange());
      }
    },
    handleConfirm() {
      this.emitChange(); // emitChange now handles filtering for leaf nodes
      this.popoverVisible = false;
    },
    handleClearInPopover() {
      this.checkedKeysSet.clear();
      this.emitChange();
    },
    handleClearOnTrigger() {
      if (this.disabled) return;
      this.checkedKeysSet.clear();
      this.emitChange();
      this.popoverVisible = false;
    },
    // 新增：处理全选/取消全选功能
    handleSelectAllToggle() {
      if (this.disabled) return;

      const leafNodes = this.currentResultLeafNodes;
      if (leafNodes.length === 0) return;

      const newCheckedKeys = new Set(this.checkedKeysSet);

      if (this.isAllCurrentResultsSelected) {
        // 取消全选：移除当前搜索结果中的所有叶子节点
        leafNodes.forEach(node => {
          if (!this.checkStrictly) {
            // 如果不是严格模式，需要处理父子节点关系
            this.handleCheckboxChange(node, false);
          } else {
            // 严格模式下直接移除
            newCheckedKeys.delete(node.key);
          }
        });

        if (this.checkStrictly) {
          this.checkedKeysSet = newCheckedKeys;
          this.emitChange();
        }
      } else {
        // 全选：选择当前搜索结果中的所有叶子节点
        if (!this.multiple) {
          // 单选模式下，只选择第一个叶子节点
          const firstLeaf = leafNodes[0];
          if (firstLeaf) {
            this.handleCheckboxChange(firstLeaf, true);
          }
        } else {
          // 多选模式下，选择所有叶子节点
          leafNodes.forEach(node => {
            if (!this.checkStrictly) {
              // 如果不是严格模式，需要处理父子节点关系
              if (!this.checkedKeysSet.has(node.key)) {
                this.handleCheckboxChange(node, true);
              }
            } else {
              // 严格模式下直接添加
              newCheckedKeys.add(node.key);
            }
          });

          if (this.checkStrictly) {
            this.checkedKeysSet = newCheckedKeys;
            this.emitChange();
          }
        }
      }
    },
    removeTag(nodeToRemove) {
      if (this.disabled || this.checkboxDisabled(nodeToRemove)) return;
      // nodeToRemove here will be a leaf node because displaySelectedNodes only gives leaf nodes
      this.handleCheckboxChange(nodeToRemove, false);
    },
    onPopoverShow() {
      if (this.$refs.popover && this.$refs.popover.$refs.reference) {
        this.triggerElRect = this.$refs.popover.$refs.reference.getBoundingClientRect();
      }
      this.$nextTick(() => {
        this.resetScroll();
        if (this.filterable && this.$refs.popover && this.$refs.popover.$el) {
          const inputEl = this.$refs.popover.$el.querySelector('.filter-input input');
          if (inputEl) inputEl.focus();
        }
      });
    }
  },
  beforeDestroy() {
    if (this.updateTimer) clearTimeout(this.updateTimer);
    if (this.scrollRAF) cancelAnimationFrame(this.scrollRAF);
  }
};
</script>

<style scoped>
.task-select-tree {
  display: inline-block;
  position: relative;
  font-size: 14px;
}

.select-trigger-wrapper {
  background-color: #fff;
  border-radius: 4px;
  border: 1px solid #dcdfe6;
  box-sizing: border-box;
  color: #606266;
  display: flex;
  align-items: center;
  min-height: 32px; /* Element UI default input height */
  padding: 0 30px 0 10px;
  position: relative;
  transition: border-color .2s cubic-bezier(.645,.045,.355,1);
  width: 100%;
  cursor: pointer;
  overflow: hidden; /* To contain tags */
}

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

.select-trigger-wrapper:hover:not(.is-disabled) {
  border-color: #c0c4cc;
}

.select-trigger-wrapper.is-active:not(.is-disabled) {
  border-color: #409eff;
}

.tags-or-value-container {
  flex-grow: 1;
  display: flex;
  flex-wrap: wrap; /* Allow tags to wrap */
  gap: 4px; /* Space between tags */
  align-items: center;
  overflow: hidden; /* Hide overflowed tags/text */
  padding: 2px 0; /* Minimal padding for tags */
  min-height: 28px; /* Ensure container has some height */
}


.single-value-display,
.placeholder-text {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  line-height: 28px; /* Align with tags/input field */
}

.single-value-display {
  color: #606266;
}

.placeholder-text {
  color: #c0c4cc;
}

.icons-container {
  position: absolute;
  right: 8px;
  top: 50%;
  transform: translateY(-50%);
  display: flex;
  align-items: center;
  color: #c0c4cc;
  height: 100%;
}

.clear-icon {
  cursor: pointer;
  margin-right: 5px;
  display: none; /* Hidden by default */
  font-size: 14px;
}

.select-trigger-wrapper:hover .clear-icon {
  display: inline-block; /* Show on hover */
}
.select-trigger-wrapper.is-disabled .clear-icon {
  display: none !important; /* Never show if component is disabled */
}


.arrow-icon {
  transition: transform .3s;
  font-size: 14px;
}

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

.tree-container {
  border: 1px solid #ebeef5;
  border-radius: 4px;
  background-color: #fff;
  margin-top: 8px; /* If filter input is present */
}

.virtual-tree-list {
  position: relative; /* For absolute positioning of virtual-content if needed */
}

.virtual-content {
  width: 100%; /* Ensure full width */
}

.virtual-tree-node {
  box-sizing: border-box;
  cursor: pointer;
  user-select: none;
  border-bottom: 1px solid #f5f7fa; /* Lighter border */
  transition: background-color 0.2s;
  min-height: 36px; /* Ensure consistency with itemHeight */
}
.virtual-tree-node:last-child {
  border-bottom: none;
}

.virtual-tree-node:hover:not(.is-disabled) {
  background-color: #f5f7fa;
}

.virtual-tree-node.is-checked:not(.is-disabled) {
  /* color: #409eff; */
}
.virtual-tree-node.is-checked .node-label {
  /* font-weight: bold; */
}


.virtual-tree-node.is-disabled {
  color: #c0c4cc;
  cursor: not-allowed;
  background-color: #f5f7fa;
}
.virtual-tree-node.is-disabled .node-label {
  color: #c0c4cc;
}


.node-expand-container {
  width: 20px;
  height: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
}

.node-expand-icon {
  cursor: pointer;
  color: #c0c4cc;
  transition: transform 0.2s, color 0.2s;
  font-size: 12px;
}

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

.node-expand-placeholder {
  width: 12px;
  height: 12px;
  display: block;
}


.node-checkbox {
  margin: 0 8px 0 4px;
  flex-shrink: 0;
}

.node-label {
  flex: 1;
  text-overflow: ellipsis;
  white-space: nowrap;
  line-height: 1.4;
  font-weight: normal;
  padding-right: 5px;
}

.node-detail-text {
  font-size: 12px;
  color: #909399;
  margin-left: 8px;
  flex-shrink: 0;
  white-space: nowrap;
}

.popover-content-wrapper {
  max-width: 100%;
}

.popover-footer {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding-top: 10px;
  border-top: 1px solid #ebeef5;
  margin-top: 10px;
}

.selected-count {
  font-size: 12px;
  color: #909399;
}

.filter-input {
  margin-bottom: 8px;
}

.trigger-tag {
  margin: 1px 0;
  max-width: 150px;
}

.trigger-tag >>> .el-tag__content {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
</style>

<style>
/* Global styles for popper, if needed */
.task-select-tree-popper.el-popover {
  padding: 12px;
}

.task-select-tree-popper .el-checkbox__input.is-disabled .el-checkbox__inner {
  background-color: #edf2fc;
  border-color: #dcdfe6;
  cursor: not-allowed;
}

.task-select-tree-popper .el-checkbox__input.is-checked .el-checkbox__inner {
  background-color: #409eff;
  border-color: #409eff;
}
.task-select-tree-popper .el-checkbox__input.is-disabled.is-checked .el-checkbox__inner {
  background-color: #f2f6fc;
  border-color: #dcdfe6;
}
</style>
