<template>
  <div style="position: relative;">
    <div class="tree-wrapper">
      <div class="search-container">
        <div class="search-wrapper">
          <q-input
            v-model="searchText"
            clearable
            class="search-input"
            label="搜索部门"
            placeholder="输入部门名称搜索"
            @input="onSearchInput"
            @focus="showSearchMenu = true"
            @blur="hideSearchMenu"
          >
            <template v-slot:prepend>
              <q-icon name="search" class="search-icon" />
            </template>
          </q-input>

          <!-- 搜索结果菜单 -->
          <div v-show="showSearchMenu" class="search-menu">
            <div class="search-results" v-if="searchResults.length > 0">
              <div
                v-for="item in searchResults"
                :key="item.key"
                class="search-result-item"
                @click="onSearchResultClick(item)"
              >
                <div class="search-result-avatar">
                  <q-icon name="business" color="primary" size="sm" />
                </div>
                <div class="search-result-content">
                  <div class="search-result-label">{{ item.title }}</div>
                </div>
                <div class="search-result-side">
                  <q-icon name="keyboard_arrow_right" size="sm" color="grey-5" />
                </div>
              </div>
            </div>
            <div v-else-if="searchText && searchText.length > 0" class="no-results">
              没有找到匹配的部门
            </div>
          </div>
        </div>
      </div>

      <div style="padding-top: 6vh;">
        <Tree
          v-if="treeData.length > 0"
          :expandedKeys="expandedKeys"
          :autoExpandParent="autoExpandParent"
          :treeData="treeData"
          @expand="onExpand"
        >
          <template slot="title" slot-scope="node">
            <span style="display: inline-flex; align-items: center; width: 100%;">
              <span style="flex: 1;">{{ node.title }}</span>
              <!-- 编辑按钮 -->
              <q-btn
                flat
                round
                dense
                icon="edit"
                size="sm"
                class="dept-edit-btn"
                @click.stop="onDeptBtnClick(node)"
              />
            </span>
          </template>
        </Tree>
      </div>
    </div>

    <div v-show="!treeData.length">
      正在加载组织机构...
    </div>

    <!-- 部门用户选择弹窗 -->
    <q-modal v-model="deptModal" maximized>
      <q-modal-layout>
        <q-toolbar slot="header" color="primary">
          <q-btn flat round dense @click="deptModal = false" icon="reply" />
          <q-toolbar-title>
            {{ currentDept ? currentDept.title : '' }} — 部门用户
          </q-toolbar-title>
        </q-toolbar>
        <q-toolbar slot="footer">
          <q-toolbar-title></q-toolbar-title>
          <q-btn round color="red" @click="confirmDeptSelection">确认</q-btn>
          <q-btn round @click="deptModal = false">取消</q-btn>
        </q-toolbar>

        <div class="q-pa-md">
          <q-input
            v-model="deptUserSearchText"
            clearable
            outlined
            dense
            placeholder="搜索部门用户..."
            class="q-mb-md"
          >
            <template v-slot:prepend>
              <q-icon name="search" />
            </template>
          </q-input>

          <div class="select-all-row">
            <q-checkbox
              :value="filteredDeptUsers.length > 0 && filteredDeptUsers.every(u => getCurrentCheckedSet().has(u.key))"
              :indeterminate="filteredDeptUsers.some(u => getCurrentCheckedSet().has(u.key)) && !filteredDeptUsers.every(u => getCurrentCheckedSet().has(u.key))"
              @input="toggleSelectAll"
            />
            <span class="select-all-label">全选</span>
          </div>

          <div v-if="deptUserLoading" class="text-center q-pa-md text-grey-6">
            <q-spinner-dots size="32px" /> 加载中...
          </div>

          <div v-else-if="filteredDeptUsers.length === 0" class="text-center q-pa-md text-grey-5">
            该部门下暂无用户
          </div>

          <div v-else class="dept-user-list">
            <div
              v-for="user in filteredDeptUsers"
              :key="user.key"
              class="dept-user-item"
              @click="toggleTempUser(user.key)"
            >
              <q-checkbox
                :value="deptUserSearchText ? searchCheckedUsers.has(user.key) : tempCheckedUsers.has(user.key)"
                @input="toggleTempUser(user.key)"
              />
              <div class="dept-user-info">
                <div class="dept-user-name">{{ user.title }}</div>
                <div class="dept-user-no" v-if="user.no">{{ user.no }}</div>
              </div>
            </div>
          </div>

          <div class="text-grey-6 text-center q-mt-md">
            已选 {{ tempCheckedUsers.size }} 人/ {{ deptUsers.length }} 人
          </div>
        </div>
      </q-modal-layout>
    </q-modal>
  </div>
</template>

<script>
  import Tree from 'ant-design-vue/lib/tree';
  import 'ant-design-vue/dist/antd.css';
  import {deptTree, getDeptUsers, getDeptUsersWithChildren} from "@/service/user/user";

  let cachedTreeData = null;

  export default {
    name: "organization-dept-panel",
    components: {Tree},
    props: {
      value: {
        type: Array,
        default: () => []
      }
    },
    data() {
      return {
        treeData: [],
        expandedKeys: [],
        autoExpandParent: true,
        searchText: '',
        showSearchMenu: false,
        searchResults: [],

        // 部门弹窗
        deptModal: false,
        currentDept: null,
        deptUsers: [],       // 部门下的所有用户
        deptUserSearchText: '',
        deptUserLoading: false,
        tempCheckedUsers: new Set(), // 弹窗内临时勾选状态
        searchCheckedUsers: new Set(), // 搜索框内临时勾选状态

        // 已选用户集合（主数据源，同步 orgList）
        selectedUserIds: new Set(),
      };
    },
    computed: {
      filteredDeptUsers() {
        if (!this.deptUserSearchText) return this.deptUsers;
        const kw = this.deptUserSearchText.toLowerCase();
        return this.deptUsers.filter(u =>
          (u.title || '').toLowerCase().includes(kw) ||
          (u.no || '').toLowerCase().includes(kw)
        );
      }
    },
    watch: {
      value: {
        handler(newVal) {
          this.selectedUserIds = new Set(newVal || []);
        },
        immediate: true
      }
    },
    created() {
      this.initTree();
    },
    methods: {
      async initTree() {
        if (cachedTreeData) {
          this.treeData = cachedTreeData;
          this.expandedKeys = this.treeData.length > 0 ? [this.treeData[0].key] : [];
          return;
        }
        let Res = await deptTree();
        cachedTreeData = [Res.data.data];
        this.treeData = cachedTreeData;
        this.expandedKeys = this.treeData.length > 0 ? [this.treeData[0].key] : [];
      },

      onExpand(expandedKeys) {
        this.expandedKeys = expandedKeys;
        this.autoExpandParent = false;
      },

      // 搜索部门
      onSearchInput(value) {
        if (!value || value.length < 1) {
          this.searchResults = [];
          return;
        }
        const kw = value.toLowerCase();
        const results = [];
        const searchTree = (nodes) => {
          for (const node of nodes) {
            if ((node.title || '').toLowerCase().includes(kw)) {
              results.push({key: node.key, title: node.title});
            }
            if (node.children) searchTree(node.children);
          }
        };
        searchTree(this.treeData);
        this.searchResults = results.slice(0, 20);
      },

      hideSearchMenu() {
        setTimeout(() => { this.showSearchMenu = false; }, 200);
      },

      onSearchResultClick(item) {
        this.searchText = item.title;
        this.showSearchMenu = false;
        // 展开到该节点
        if (!this.expandedKeys.includes(item.key)) {
          this.expandedKeys.push(item.key);
        }
        this.onDeptBtnClick(item);
      },

      // 点击部门编辑按钮
      async onDeptBtnClick(dept) {
        this.currentDept = dept;
        this.deptUserSearchText = '';
        this.deptModal = true;
        this.tempCheckedUsers = new Set();
        // 懒加载部门用户（包括子部门）
        if (dept.key >= 1000000) {
          const realDeptId = dept.key - 1000000;
          this.deptUserLoading = true;
          this.deptUsers = [];
          try {
            // 修改：调用新 API，查询部门及子部门用户
            let res = await getDeptUsersWithChildren(realDeptId);
            let users = (res.data.data && res.data.data.list) || res.data.data || [];
            this.deptUsers = users.map(u => ({
              key: u.id,
              title: u.username || u.title || '',
              no: u.account || u.number || ''
            }));
          } catch (e) {
            console.error('loadDeptUsers error:', e);
            this.deptUsers = [];
          } finally {
            this.deptUserLoading = false;
            // deptUsers 填充后再初始化勾选状态
            this.tempCheckedUsers = new Set(
              [...this.selectedUserIds].filter(id => this.deptUsers.some(u => u.key === id))
            );
          }
        } else {
          // 部门key < 1000000，直接从树节点 children 取
          this.deptUsers = (dept.children || []).map(u => ({
            key: u.key,
            title: u.title || u.label || '',
            no: u.no || ''
          }));
          // deptUsers 填充后再初始化勾选状态
          this.tempCheckedUsers = new Set(
            [...this.selectedUserIds].filter(id => this.deptUsers.some(u => u.key === id))
          );
        }
      },

      toggleTempUser(userKey) {
        const currentSet = this.deptUserSearchText ? this.searchCheckedUsers : this.tempCheckedUsers;
        const newSet = new Set(currentSet);
        if (newSet.has(userKey)) {
          newSet.delete(userKey);
        } else {
          newSet.add(userKey);
        }
        if (this.deptUserSearchText) {
          this.searchCheckedUsers = newSet;
        } else {
          this.tempCheckedUsers = newSet;
        }
      },

      getCurrentCheckedSet() {
        return this.deptUserSearchText ? this.searchCheckedUsers : this.tempCheckedUsers;
      },

      toggleSelectAll(checked) {
        const currentSet = this.deptUserSearchText ? this.searchCheckedUsers : this.tempCheckedUsers;
        if (checked) {
          this.filteredDeptUsers.forEach(u => currentSet.add(u.key));
        } else {
          this.filteredDeptUsers.forEach(u => currentSet.delete(u.key));
        }
        if (this.deptUserSearchText) {
          this.searchCheckedUsers = new Set(currentSet);
        } else {
          this.tempCheckedUsers = new Set(currentSet);
        }
      },

      confirmDeptSelection() {
        const prevInDept = new Set([...this.selectedUserIds].filter(id => this.deptUsers.some(u => u.key === id)));

        // 添加本次新增的
        const newSelected = new Set([...this.selectedUserIds]);
        this.tempCheckedUsers.forEach(id => newSelected.add(id));
        this.searchCheckedUsers.forEach(id => newSelected.add(id));

        // 移除本次取消的
        prevInDept.forEach(id => {
          if (!this.tempCheckedUsers.has(id) && !this.searchCheckedUsers.has(id)) {
            newSelected.delete(id);
          }
        });

        this.selectedUserIds = newSelected;
        this.$emit('change', [...this.selectedUserIds]);
        this.deptModal = false;
      }
    }
  };
</script>

<style scoped>
.search-container {
  position: fixed;
  width: 17vw;
  z-index: 9999;
  padding: 0 1vh;
}

.search-wrapper {
  position: relative;
}

.search-input {
  padding-top: 10px;
  padding-left: 5px;
  border-radius: 4px !important;
  background: linear-gradient(135deg, #f8f9fa 0%, #ffffff 100%);
  transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
}

.search-input:hover {
  box-shadow: 0 6px 20px rgba(0, 0, 0, 0.12);
  transform: translateY(-1px);
}

.search-input:focus-within {
  box-shadow: 0 8px 25px rgba(33, 150, 243, 0.15);
  transform: translateY(-2px);
}

.search-input >>> .q-field__control {
  border-radius: 12px;
  padding: 8px 16px;
}

.search-input >>> .q-field__label {
  font-weight: 500;
  color: #666;
  font-size: 12px;
}

.search-input >>> .q-field__native {
  font-size: 14px;
  font-weight: 400;
  padding-left: 12px !important;
  padding-top: 2px !important;
  padding-bottom: 2px !important;
}

.search-input >>> .q-field__native::placeholder {
  font-size: 14px;
  color: #999;
}

.search-icon {
  color: #999;
  transition: color 0.3s ease;
}

.search-input:hover .search-icon {
  color: #1976d2;
}

.search-menu {
  border-radius: 12px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.12);
  border: 1px solid rgba(255, 255, 255, 0.2);
  backdrop-filter: blur(8px);
  background: rgba(255, 255, 255, 0.95);
  min-width: 16vw;
  max-width: 16vw;
  max-height: 300px;
  overflow-y: auto;
  position: absolute;
  top: 100%;
  left: 0;
  right: 0;
  z-index: 1000;
  margin-top: 8px;
}

.search-results {
  padding: 8px 0;
}

.search-result-item {
  display: flex;
  align-items: center;
  padding: 12px 16px;
  border-radius: 8px;
  margin: 2px 8px;
  cursor: pointer;
  transition: all 0.2s ease;
  border: 1px solid transparent;
}

.search-result-item:hover {
  background-color: rgba(25, 118, 210, 0.08);
  transform: translateX(2px);
  border-color: rgba(25, 118, 210, 0.1);
}

.search-result-avatar {
  flex-shrink: 0;
  width: 40px;
  height: 40px;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 50%;
  background-color: rgba(0, 0, 0, 0.04);
  margin-right: 12px;
}

.search-result-content {
  flex: 1;
  min-width: 0;
}

.search-result-side {
  flex-shrink: 0;
  width: 24px;
  height: 24px;
  display: flex;
  align-items: center;
  justify-content: center;
  opacity: 0.5;
}

.search-result-label {
  font-weight: 500;
  color: #333;
  font-size: 14px;
}

.no-results {
  padding: 16px;
  text-align: center;
  color: #999;
  font-size: 14px;
}

.dept-edit-btn {
  transition: opacity 0.2s;
}

.dept-user-list {
  max-height: 60vh;
  overflow-y: auto;
  border: 1px solid #e0e0e0;
  border-radius: 8px;
}

.select-all-row {
  display: flex;
  align-items: center;
  padding: 6px 0;
  margin-bottom: 4px;
}

.select-all-label {
  font-size: 14px;
  color: #333;
  user-select: none;
}

.dept-user-item {
  display: flex;
  align-items: center;
  padding: 12px 16px;
  cursor: pointer;
  border-bottom: 1px solid #f0f0f0;
  transition: background-color 0.15s;
}

.dept-user-item:last-child {
  border-bottom: none;
}

.dept-user-item:hover {
  background-color: #f5f5f5;
}

.dept-user-info {
  margin-left: 12px;
  flex: 1;
}

.dept-user-name {
  font-size: 14px;
  color: #333;
}

.dept-user-no {
  font-size: 12px;
  color: #999;
  margin-top: 2px;
}

.dept-edit-btn {
  transition: opacity 0.2s;
}

:deep(.ant-tree-title:hover) .dept-edit-btn {
  opacity: 1;
}

.tree-wrapper {
  transition: opacity 0.2s ease;
}
</style>
