<template>
  <div class="folder-selector">
    <el-alert v-if="!treeData || treeData.length === 0" title="暂无可选文件夹" type="warning" :closable="false" style="margin-bottom: 10px" />
    <el-tree
      ref="treeRef"
      :data="treeData"
      :props="treeProps"
      node-key="id"
      :default-expanded-keys="defaultExpandedKeys"
      :default-checked-keys="defaultCheckedKeys"
      show-checkbox
      check-strictly
      :check-on-click-node="true"
      @check="handleCheck"
      class="folder-tree"
    >
      <template #default="{ node, data }">
        <span class="custom-tree-node">
          <el-icon v-if="data.type === 1"><OfficeBuilding /></el-icon>
          <el-icon v-else-if="data.type === 2"><Location /></el-icon>
          <el-icon v-else><Folder /></el-icon>
          <span class="node-label">{{ node.label }}</span>
        </span>
      </template>
    </el-tree>
  </div>
</template>

<script setup lang="ts">
import { ref, watch, computed } from 'vue';
import { OfficeBuilding, Location, Folder } from '@element-plus/icons-vue';

interface FolderNode {
  id: number | string;
  name: string;
  type?: number;
  children?: FolderNode[];
}

interface Props {
  treeData?: FolderNode[];
  defaultFolderId?: number | string;
}

interface Emits {
  (e: 'update:selectedFolderId', value: number | string | undefined): void;
  (e: 'change', value: number | string | undefined): void;
}

const props = withDefaults(defineProps<Props>(), {
  treeData: () => []
});
const emit = defineEmits<Emits>();

const treeRef = ref();
const selectedFolderId = ref<number | string | undefined>(undefined);
const isSettingChecked = ref(false);

// 树配置
const treeProps = {
  children: 'children',
  label: 'name'
};

// 默认展开的节点
const defaultExpandedKeys = computed(() => {
  if (props.defaultFolderId) {
    return [props.defaultFolderId];
  }
  return [];
});

// 默认选中的节点
const defaultCheckedKeys = computed(() => {
  if (props.defaultFolderId) {
    return [props.defaultFolderId];
  }
  return [];
});

// 监听默认文件夹ID变化
watch(
  () => props.defaultFolderId,
  (val) => {
    if (val) {
      selectedFolderId.value = val;
      setTimeout(() => {
        if (treeRef.value) {
          treeRef.value.setCheckedKeys([val]);
        }
      }, 100);
    }
  },
  { immediate: true }
);

// 处理复选框选中（实现单选效果）
const handleCheck = (data: FolderNode, checked: any) => {
  // 如果是程序设置的，跳过处理
  if (isSettingChecked.value) {
    return;
  }

  const clickedId = data.id;
  const checkedKeys = checked.checkedKeys || [];

  // 设置标志位，防止循环触发
  isSettingChecked.value = true;

  // 实现单选：只保留当前点击的节点
  if (checkedKeys.includes(clickedId)) {
    // 如果当前节点在选中列表中，说明是选中操作
    selectedFolderId.value = clickedId;
    // 清除所有选中，只保留当前节点
    treeRef.value?.setCheckedKeys([clickedId]);
    emit('update:selectedFolderId', clickedId);
    emit('change', clickedId);
  } else {
    // 如果当前节点不在选中列表中，说明是取消选中操作
    // 不允许取消选中，重新选中该节点
    treeRef.value?.setCheckedKeys([selectedFolderId.value || clickedId]);
  }

  // 延迟重置标志位
  setTimeout(() => {
    isSettingChecked.value = false;
  }, 100);
};

// 获取选中的文件夹ID
const getSelectedFolderId = (): number | string | undefined => {
  return selectedFolderId.value;
};

// 设置选中的文件夹
const setSelectedFolderId = (id: number | string | undefined) => {
  selectedFolderId.value = id;
  if (id && treeRef.value) {
    treeRef.value.setCheckedKeys([id]);
  }
};

// 清除选中
const clearSelection = () => {
  selectedFolderId.value = undefined;
  if (treeRef.value) {
    treeRef.value.setCheckedKeys([]);
  }
};

// 暴露方法
defineExpose({
  getSelectedFolderId,
  setSelectedFolderId,
  clearSelection
});
</script>

<style scoped lang="scss">
.folder-selector {
  .folder-tree {
    border: 1px solid #dcdfe6;
    border-radius: 4px;
    padding: 10px;
    max-height: 400px;
    overflow-y: auto;

    :deep(.el-tree-node__content) {
      height: 32px;
    }

    .custom-tree-node {
      display: flex;
      align-items: center;
      gap: 6px;
      flex: 1;

      .el-icon {
        font-size: 16px;
      }

      .node-label {
        font-size: 14px;
      }
    }
  }
}
</style>
