<template>
  <div class="GuiLeftSider">
    <p class="nameList">文件列表</p>
    <div class="el-treecontain" v-if="data && data.length > 0">
      <el-tree ref="treeRef" :data="data" :props="defaultProps" class="el-treemain" highlight-current
        :expand-on-click-node="false" :default-expanded-keys="defaultExpandedKeys" @node-click="handleNodeClick"
        node-key="id">
        <template #default="{ node, data }">
          <div class="fileitem1" v-if="data.isFolder">
            <img src="../assets/文件夹图标.png">
            {{ node.label }}
          </div>
          <div class="fileitem2" v-else-if="data.isLeaf">
            <img src="../assets/文件图标-线.png">
            {{ node.label }}
          </div>
        </template>
      </el-tree>
    </div>
    <!-- <div class="defaultList" v-else>
      <button @click="onopendata">选择文件夹</button>
    </div> -->
  </div>


</template>

<script>
import EventBus from "../../eventBus.js"

export default {
  name: "GuiLeftSider",

  data() {
    return {
      data: [],
      defaultProps: {
        children: 'children',
        label: 'label',
      },
      DefualtPath: "",
      showButton: true,
      ctrlKeyPressed: false,
      shiftKeyPressed: false,
      shiftKeyField: [],
      selectNodes: [],
      includeChildren: true,
      allFiles: [], // 存储所有解析出的文件
      lastClickedNode: null, // 记录最后点击的节点
      lastClickTime: 0, // 记录最后点击时间
      defaultExpandedKeys: [],
    }
  },
  async mounted() {
    window.addEventListener("keydown", this.handleKeyDown);
    window.addEventListener("keyup", this.handleKeyUp);
    // 额外增加：用鼠标事件同步按键状态，防止 keyup 丢失导致“多选卡住”
    window.addEventListener("mousedown", this.handleMouseDown, true); // 捕获阶段更稳妥
    window.addEventListener("mouseup", this.handleMouseUp, true);
    window.addEventListener("blur", this.resetModifierKeys); // 窗口失焦时重置
    document.addEventListener("visibilitychange", this.handleVisibilityChange);
    // 事件总线
    EventBus.on('triggerOpenFolder', this.onopendata);
    EventBus.on('triggerSaveFiles', this.handleSaveFiles);
    EventBus.on('triggerClearData', this.clearData);
  },
  beforeUnmount() {
    window.removeEventListener("keydown", this.handleKeyDown);
    window.removeEventListener("keyup", this.handleKeyUp);
    // 配套移除新增的监听
    window.removeEventListener("mousedown", this.handleMouseDown, true);
    window.removeEventListener("mouseup", this.handleMouseUp, true);
    window.removeEventListener("blur", this.resetModifierKeys);
    document.removeEventListener("visibilitychange", this.handleVisibilityChange);
    EventBus.off('triggerOpenFolder', this.onopendata);
    EventBus.off('triggerSaveFiles', this.handleSaveFiles);
    EventBus.off('triggerClearData', this.clearData);
  },
  methods: {
    handleKeyDown(event) {
      if (event.key == "Control") {
        this.ctrlKeyPressed = true;
      }
      if (event.key == "Shift") {
        this.shiftKeyPressed = true;
      }
    },
    handleKeyUp(event) {
      if (event.key == "Control") {
        this.ctrlKeyPressed = false;
      }
      if (event.key == "Shift") {
        this.shiftKeyPressed = false;
      }
    },
    // 新增：鼠标按下/松开时同步 Ctrl/Shift 状态（点击流程更可靠）
    handleMouseDown(e) {
      this.ctrlKeyPressed = !!e.ctrlKey;
      this.shiftKeyPressed = !!e.shiftKey;
    },
    handleMouseUp(e) {
      // 鼠标抬起时再次以实际状态为准（若用户已松开 Ctrl/Shift，这里会回到 false）
      this.ctrlKeyPressed = !!e.ctrlKey;
      this.shiftKeyPressed = !!e.shiftKey;
    },
    // 新增：窗口不可见/失焦时，重置修饰键，避免卡住
    handleVisibilityChange() {
      if (document.visibilityState !== 'visible') {
        this.resetModifierKeys();
      }
    },
    resetModifierKeys() {
      this.ctrlKeyPressed = false;
      this.shiftKeyPressed = false;
    },
    collectAllFiles(node) {
      const files = [];

      if (node.isLeaf) {
        files.push({
          id: node.id,
          path: node.path,
          label: node.label
        });
        return files;
      }

      if (node.children && node.children.length > 0) {
        for (const child of node.children) {
          const childFiles = this.collectAllFiles(child);
          files.push(...childFiles);
        }
      }

      return files;
    },
    isFolder(nodeData) {
      return nodeData.isFolder === true || (nodeData.children && Array.isArray(nodeData.children));
    },

    // 添加双击事件处理
    handleNodeDblClick(nodeData, node) {
      if (nodeData.isLeaf && !this.isFolder(nodeData)) {
        // 双击文件时，发送NodeDblClicked事件
        this.$emit("NodeDblClicked", nodeData.path);
      } else if (this.isFolder(nodeData)) {
        // 双击文件夹时，收集所有文件并发送FolderDblClicked事件
        this.allFiles = this.collectAllFiles(nodeData);
        const allPaths = this.allFiles.map(file => file.path);
        this.$emit("FolderDblClicked", nodeData.path, allPaths);
      }
    },
    // 节点点击事件处理
    handleNodeClick(nodeData, node) {
      const treeRef = this.$refs.treeRef;
      if (!treeRef) return;

      const nodes = treeRef.store._getAllNodes(); // 所有node节点
      const ishas = this.selectNodes.includes(node.id);
      const isSameLevel = (node1, node2) => node1.parent === node2.parent;
      const isNodeFolder = this.isFolder(nodeData);

      // 实现双击检测
      const now = new Date().getTime();
      const isDoubleClick = this.lastClickedNode === nodeData.path && (now - this.lastClickTime) < 300; // 300ms内的点击视为双击

      // 更新最后点击的节点和时间
      this.lastClickedNode = nodeData.path;
      this.lastClickTime = now;

      // 如果是双击，则发送双击事件
      if (isDoubleClick) {
        if (nodeData.isLeaf && !isNodeFolder) {
          this.$emit("NodeDblClicked", nodeData.path);
          return; // 双击时不执行单击逻辑
        } else if (isNodeFolder) {
          // 双击文件夹时，收集所有文件并发送FolderDblClicked事件
          this.allFiles = this.collectAllFiles(nodeData);
          const allPaths = this.allFiles.map(file => file.path);
          this.$emit("FolderDblClicked", nodeData.path, allPaths);
          return; // 双击时不执行单击逻辑
        }
      }

      // 单选模式
      if (!this.ctrlKeyPressed && !this.shiftKeyPressed) {
        // 清空之前的选择
        this.shiftKeyField = [];
        this.selectNodes = [];

        // 如果是文件，直接选中
        if (nodeData.isLeaf && !isNodeFolder) {
          this.selectNodes = [node.id];
          this.$emit("NodeClicked", nodeData.path);
        }
        // 如果是文件夹，解析所有子文件
        else if (isNodeFolder) {
          this.selectNodes = [node.id];
          // 收集文件夹下所有文件
          this.allFiles = this.collectAllFiles(nodeData);
          // console.log('文件夹下所有文件:', this.allFiles);
          // 可以发送所有文件路径给父组件
          const allPaths = this.allFiles.map(file => file.path);
          this.$emit("FolderClicked", nodeData.path, allPaths);
        }
      }
      // Shift多选模式
      else if (this.shiftKeyPressed) {
        if (isNodeFolder) {
          this.shiftKeyField = [];
          this.selectNodes = [];

          for (const item of nodes) {
            item.isCurrent = false;
          }
          return;
        }

        // 如果selectNodes有值但shiftKeyField为空，说明是从单选模式切换到Shift多选模式
        // 需要将已选中的节点ID添加到shiftKeyField中
        if (this.selectNodes.length > 0 && this.shiftKeyField.length === 0) {
          const firstSelectedNodeId = this.selectNodes[0];
          this.shiftKeyField.push(firstSelectedNodeId);
        }

        if (this.selectNodes.length > 0) {
          const firstSelectedNodeId = this.selectNodes[0];
          const firstSelectedNode = nodes.find(x => x.id == firstSelectedNodeId);

          if (firstSelectedNode && !isSameLevel(firstSelectedNode, node)) {
            this.shiftKeyField = [];
            this.selectNodes = [];

            for (const item of nodes) {
              item.isCurrent = false;
            }
            return;
          }
        }

        this.shiftKeyField.push(node.id);

        if (this.shiftKeyField.length > 1) {
          const firstNodeId = this.shiftKeyField[0];
          const firstNode = nodes.find(x => x.id == firstNodeId);

          if (!isSameLevel(firstNode, node)) {
            this.shiftKeyField = [];
            this.selectNodes = [];

            for (const item of nodes) {
              item.isCurrent = false;
            }
            return;
          }

          const sIndex = nodes.findIndex(x => x.id == this.shiftKeyField[0]);
          const eIndex = nodes.findIndex(x => x.id == this.shiftKeyField[this.shiftKeyField.length - 1]);
          const s = sIndex < eIndex ? sIndex : eIndex; // 取小值当开头索引
          const e = sIndex < eIndex ? eIndex : sIndex; // 取大值当结尾索引

          for (let i = s; i <= e; i++) {
            const currentNode = nodes[i];
            if (!this.isFolder(currentNode.data) && isSameLevel(currentNode, firstNode)) {
              if (!this.selectNodes.includes(currentNode.id)) {
                this.selectNodes.push(currentNode.id);
              }
            }
          }
        } else {
          if (!isNodeFolder) {
            if (!this.selectNodes.includes(node.id)) {
              this.selectNodes.push(node.id);
            }
          } else {
            this.shiftKeyField = [];
            this.selectNodes = [];
          }
        }
      }
      // ctrl多选模式
      else if (this.ctrlKeyPressed) {
        if (isNodeFolder) {
          this.shiftKeyField = [];
          this.selectNodes = [];

          for (const item of nodes) {
            item.isCurrent = false;
          }
          return;
        }

        if (ishas) {
          const index = this.selectNodes.findIndex(x => x == node.id);
          this.selectNodes.splice(index, 1);
        } else {
          this.selectNodes.push(node.id);
        }
      }

      for (const item of nodes) {
        if (this.selectNodes.includes(item.id)) {
          item.isCurrent = true;
        } else {
          item.isCurrent = false;
        }
      }

      const selectedNodesInfo = nodes
        .filter(item => this.selectNodes.includes(item.id))
        .map(item => ({
          id: item.id,
          label: item.label,
          path: item.data.path || '',
          isFolder: this.isFolder(item.data)
        }));

      const selectedFiles = selectedNodesInfo.filter(item => !item.isFolder);
      if (selectedFiles.length > 0) {
        const filePaths = selectedFiles.map(file => file.path);
        this.$emit("FilesSelected", filePaths);
      }
    },

    async onopendata() {
      try {
        // 获取文件夹列表
        this.$emit("reset");
        this.data = []
        const folderTree = await this.$tauriApi.getFolderList(this.DefualtPath);

        const getComparableLabel = (node) => {
          if (typeof node?.label !== "string") return "";
          if (node.isLeaf) {
            return node.label.replace(/\.[^/.]+$/, "");
          }
          return node.label;
        };

        // 工具：从名称中提取日期（YYYY[_-]M[M]?[_-]D[D]?），返回时间戳，未匹配返回 null
        const extractDateStamp = (node) => {
          const base = getComparableLabel(node);
          // 支持 2025_9_3、2025-9-3、2025_09_03、2025-09-03
          const m = base.match(/(\d{4})[_-](\d{1,2})[_-](\d{1,2})/);
          if (!m) return null;
          const y = parseInt(m[1], 10);
          const M = parseInt(m[2], 10);
          const d = parseInt(m[3], 10);
          const dt = new Date(y, M - 1, d);
          if (
            Number.isNaN(dt.getTime()) ||
            dt.getFullYear() !== y ||
            dt.getMonth() !== (M - 1) ||
            dt.getDate() !== d
          ) {
            return null;
          }
          return dt.getTime();
        };

        // 添加唯一ID，并进行过滤 + 排序（同级文件夹与文件按日期由近到远，无日期排后且保持原序）
        let idCounter = 1;
        const addUniqueIdsAndFilter = (node) => {
          node.id = idCounter++;
          if (node.isFolder) {
            if (Array.isArray(node.children) && node.children.length) {
              // 过滤：仅保留文件夹与 .iris 文件
              node.children = node.children.filter(child => {
                if (child.isFolder) return true;
                if (child.isLeaf && typeof child.label === "string") {
                  return child.label.endsWith(".iris");
                }
                return false;
              });

              // 排序：按包含的日期（忽略后缀）由近到远；无日期排在后面并保持原有顺序
              const decorated = node.children.map((child, idx) => ({
                child,
                idx,
                stamp: extractDateStamp(child) // number | null
              }));
              decorated.sort((a, b) => {
                const aHas = typeof a.stamp === "number";
                const bHas = typeof b.stamp === "number";
                if (aHas && bHas) {
                  return b.stamp - a.stamp; // 近(新) -> 远(旧)
                }
                if (aHas && !bHas) return -1; // 有日期在前
                if (!aHas && bHas) return 1;  // 无日期在后
                // 都没有日期：保持原有顺序（稳定）
                return a.idx - b.idx;
              });
              node.children = decorated.map(d => d.child);

              // 递归处理
              node.children.forEach(child => addUniqueIdsAndFilter(child));
            }
          } else {
            // 非文件夹无需处理子项
          }
        };

        addUniqueIdsAndFilter(folderTree);

        if (folderTree && folderTree.label != "请选择") {
          this.data = [folderTree];
        }

        // 收集所有id用于默认展开
        const expandedKeys = [];
        this.collectAllNodeIds(folderTree, expandedKeys);
        this.defaultExpandedKeys = expandedKeys;
      } catch (error) {
        console.error("打开文件夹失败:", error);
      }
    },

    // 整合所有节点id，默认显示使用
    collectAllNodeIds(node, arr) {
      arr.push(node.id);
      if (node.children && node.children.length > 0) {
        node.children.forEach(child => this.collectAllNodeIds(child, arr));
      }
    },
    // 处理保存文件事件
    handleSaveFiles() {
      const selectedFiles = this.getSelectedFiles();
      if (selectedFiles.length === 0) {
        alert('请先打开文件后再保存')
        return;
      }
      // 触发保存文件请求事件，传递选中的文件
      this.$emit('SaveFilesRequested', selectedFiles);
    },

    // 获取文件
    getSelectedFiles() {
      const treeRef = this.$refs.treeRef;
      if (!treeRef) return [];
      const nodes = treeRef.store._getAllNodes();
      const allFiles = [];

      // 遍历所有节点，收集所有文件
      nodes.forEach(node => {
        if (node.data && node.data.isLeaf && !node.data.isFolder) {
          allFiles.push({
            id: node.id,
            label: node.data.label,
            path: node.data.path,
            name: node.data.label
          });
        }
      });

      return allFiles;
    },

    // 清空数据
    clearData() {
      this.$emit("reset");
      this.data = []
    }
  }


}
</script>

<style scoped lang="less">
el-tree {
  height: 100vh;
  overflow: auto;
}

.el-treemain {
  min-width: 100%;
  white-space: nowrap;
  /* 不换行，使树节点水平排列 */
  display: inline-block;
  /* 横向排列 */
  text-align: left;
}

.el-treecontain {
  width: 100%;
  text-align: left;
  max-height: 88vh;
  overflow-y: auto;
}

.fileitem1 {
  width: 100%;
  height: 20px;
  display: flex;
  align-items: center;

  &>img {
    width: 18px;
    height: 18px;
    margin-right: 5px;
  }
}

.fileitem2 {
  width: 100%;
  height: 18px;
  display: flex;
  align-items: center;

  &>img {
    margin-right: 5px;

    width: 13px;
    height: 13px;
  }
}

.fileitem:nth-child(2) {
  width: 13px;
  height: 13px;
}

.GuiLeftSider {
  padding: 17px 24px;
}

.GuiLeftSider p {
  font-size: 18px;
  color: #434959;
  text-align: left;
  font-weight: 600;
}

.defaultList button {
  width: 100%;
  height: 40px;
  border-radius: 4px;
  border: 1.4px solid #4271EE;
  box-shadow: none;
  font-size: 16px;
  color: #4271EE;
}
</style>