<template>
  <div class="app-container addrbook-page">
    <!-- 左列：组织架构树 -->
    <div class="addrbook-left">
      <div
        class="latest-contacts"
        :class="{ active: isLatestContacts }"
        @click="showLatestContacts"
      >
        <i class="el-icon-time" />
        <span>常用联系人</span>
      </div>
      <div class="latest-contacts">
        <span>组织架构</span>
      </div>
      <el-tree
        ref="orgTree"
        :data="treeData"
        :props="treeProps"
        :default-expanded-keys="expandedKeys"
        :highlight-current="true"
        node-key="id"
        @node-click="handleNodeClick"
      />
    </div>
    <!-- 中列：成员列表 -->
    <div class="addrbook-center">
      <div class="search-box">
        <el-input
          v-model="searchText"
          placeholder="搜索联系人"
          suffix-icon="el-icon-search"
          clearable
          @keyup.enter.native="handleSearch"
          @clear="handleClearSearch"
        />
      </div>
      <div class="center-header">
        <span class="structure-name">{{ currentStructureName }}</span>
        <i
          class="el-icon-refresh refresh-btn"
          title="刷新"
          @click="handleRefresh"
        />
      </div>
      <div v-loading="loading" class="member-list">
        <div
          v-for="member in displayMembers"
          :key="member.id"
          :class="[
            'member-item',
            {
              active: currentUser && currentUser.id === member.id,
              offline: !member.online,
            },
          ]"
          @click="handleMemberClick(member)"
        >
          <el-avatar
            :size="32"
            :src="member.avatar | avatarFilter"
            icon="el-icon-user-solid"
          />
          <span class="member-name">{{ member.name }}</span>
          <span v-if="member.online" class="online-dot" />
        </div>
        <el-empty
          v-if="!loading && displayMembers.length === 0"
          description="暂无成员"
        />
      </div>
    </div>
    <!-- 右列：详情面板 -->
    <div class="addrbook-right">
      <div v-if="currentUser" class="detail-panel">
        <div class="avatar-section">
          <el-avatar
            :size="80"
            :src="currentUser.avatar | avatarFilter"
            icon="el-icon-user-solid"
          />
        </div>
        <div class="info-section">
          <div class="info-row">
            <i class="el-icon-user" />
            <span class="label">姓名</span>
            <el-tooltip :content="currentUser.name" placement="top">
              <span class="value">{{ currentUser.name }}</span>
            </el-tooltip>
          </div>
          <div class="info-row">
            <i class="el-icon-message" />
            <span class="label">邮箱</span>
            <el-tooltip :content="currentUser.email || ''" placement="top">
              <span class="value">{{ currentUser.email }}</span>
            </el-tooltip>
          </div>
          <div class="info-row">
            <i class="el-icon-office-building" />
            <span class="label">部门</span>
            <el-tooltip :content="currentUser.department || ''" placement="top">
              <span class="value">{{ currentUser.department }}</span>
            </el-tooltip>
          </div>
          <div class="info-row">
            <i class="el-icon-s-custom" />
            <span class="label">职位</span>
            <el-tooltip :content="currentUser.role || ''" placement="top">
              <span class="value">{{ currentUser.role }}</span>
            </el-tooltip>
          </div>
          <div class="info-row">
            <i class="el-icon-phone" />
            <span class="label">手机</span>
            <span class="value">{{ currentUser.phone }}</span>
          </div>
          <div class="info-row">
            <i class="el-icon-info" />
            <span class="label">状态</span>
            <span
              class="value"
              :class="currentUser.online ? 'online' : 'offline'"
            >
              {{ currentUser.online ? "正常" : "离线" }}
            </span>
          </div>
        </div>
        <div class="action-section">
          <el-button
            type="success"
            icon="el-icon-chat-dot-round"
            @click="sendMessage"
          >
            发消息
          </el-button>
        </div>
      </div>
      <div v-else class="empty-detail">
        <el-empty description="请选择联系人" />
      </div>
    </div>
  </div>
</template>

<script>
import EventBus from "@/utils/eventBus";
import { getAddrBook, listUsers } from "@/api/addressBook/index.js";
import { getLatestContacts, searchUsers } from "@/api/message/index.js";
export default {
  name: "AddressBook",
  filters: {
    avatarFilter(avatar) {
      if (!avatar) return "";
      if (avatar.startsWith("http")) return avatar;
      // 尝试拼接 MinIO 访问路径，实际项目中应根据 netConfig 动态生成
      return avatar;
    },
  },
  data() {
    return {
      treeData: [],
      treeProps: {
        label: "name",
        children: "children",
      },
      expandedKeys: [],
      currentGroupId: null,
      currentStructureName: "",
      memberList: [],
      offlineMemberList: [],
      currentUser: null,
      searchText: "",
      loading: false,
      isLatestContacts: false,
      userGroupId: null,
    };
  },
  computed: {
    displayMembers() {
      // 在线在前，离线在后，与 Qt 代码逻辑一致
      const online = this.memberList.filter((m) => m.online);
      const offline = this.memberList.filter((m) => !m.online);
      return [...online, ...offline];
    },
    currentUserInfo() {
      return this.$store.state.user.userInfo;
    },
  },
  mounted() {
    this.initUserInfo();
    this.fetchOrgTree();
  },
  methods: {
    // 初始化当前用户信息，与 Qt SetCurDetailInfo 对应
    initUserInfo() {
      const info = this.currentUserInfo;
      if (info) {
        this.currentUser = {
          id: info.id,
          name: info.name,
          role: info.role,
          phone: info.phone,
          status: info.status,
          email: info.email,
          group: info.group,
          full_group: info.full_group || info.group,
          avatar: info.avatar,
          online: info.status === 0,
        };
        this.userGroupId = info.group_id || info.grp_id;
      }
    },

    // 获取组织架构树，与 Qt Cmd_addr_book_addr 对应，POST 空 body
    async fetchOrgTree() {
      try {
        const res = await getAddrBook();
        const list = res.data?.list || [];
        this.treeData = this.buildTree(list);
        // 自动展开当前用户所在组
        if (this.userGroupId) {
          this.expandedKeys = this.findParentKeys(
            this.treeData,
            this.userGroupId
          );
          this.$nextTick(() => {
            this.$refs.orgTree.setCurrentKey(this.userGroupId);
            if (this.userGroupId) {
              this.fetchMembers(this.userGroupId);
              const node = this.findNodeById(this.treeData, this.userGroupId);
              if (node) {
                this.currentStructureName = node.name;
              }
            }
          });
        }
      } catch (e) {
        console.error("获取组织架构失败", e);
      }
    },

    // 构建树形数据
    buildTree(list) {
      return list.map((item) => ({
        id: item.id,
        name: item.name,
        level: item.level,
        children:
          item.child && item.child.length > 0
            ? this.buildTree(item.child)
            : undefined,
      }));
    },

    // 查找父节点路径
    findParentKeys(tree, targetId, parents = []) {
      for (const node of tree) {
        if (node.id === targetId) {
          return [...parents, node.id];
        }
        if (node.children && node.children.length > 0) {
          const found = this.findParentKeys(node.children, targetId, [
            ...parents,
            node.id,
          ]);
          if (found.length > 0) return found;
        }
      }
      return [];
    },

    // 根据ID查找节点
    findNodeById(tree, id) {
      for (const node of tree) {
        if (node.id === id) return node;
        if (node.children) {
          const found = this.findNodeById(node.children, id);
          if (found) return found;
        }
      }
      return null;
    },

    // 点击树节点，与 Qt OnListWidgetTreeMenuSwitch 对应
    handleNodeClick(data) {
      this.isLatestContacts = false;
      this.currentStructureName = data.name;
      this.currentGroupId = data.id;
      this.currentUser = null;
      this.fetchMembers(data.id);
    },

    // 获取组成员，与 Qt GetAddrBookDetailInfo 对应，POST { group_id }
    async fetchMembers(groupId) {
      this.loading = true;
      try {
        const res = await listUsers({
          group_id: groupId,
        });
        const list = res.data?.list || [];
        // 与 Qt 代码一致：区分在线离线，但这里统一存入 memberList，由 computed 排序
        this.memberList = list.map((item) => ({
          id: item.id,
          name: item.name,
          role: item.role,
          phone: item.phone,
          status: item.status,
          email: item.email,
          group: item.group,
          full_group: item.full_group,
          avatar: item.avatar,
          online: item.online === 1 || item.online === true,
        }));
      } catch (e) {
        console.error("获取成员列表失败", e);
        this.memberList = [];
      } finally {
        this.loading = false;
      }
    },

    // 显示最近联系人，与 Qt SendLatestContactsSlot 对应
    showLatestContacts() {
      this.isLatestContacts = true;
      this.currentStructureName = "最近联系人";
      this.currentGroupId = null;
      this.currentUser = null;
      // 取消树节点选中
      this.$refs.orgTree.setCurrentKey(null);
      this.fetchLatestContacts();
    },

    // 获取最近联系人，与 Qt GetLatestContacts 对应，POST { scene: 1, page: 1, size: 65535 }
    async fetchLatestContacts() {
      this.loading = true;
      try {
        const res = await getLatestContacts({
          scene: 1,
          page: 1,
          // size: 65535,
        });
        const list = res.data?.list || [];
        this.memberList = list.map((item) => ({
          id: item.id,
          name: item.name,
          role: item.role,
          phone: item.phone,
          status: item.status,
          email: item.email,
          group: item.group,
          full_group: item.full_group,
          avatar: item.avatar,
          online: item.online === 1 || item.online === true,
        }));
      } catch (e) {
        console.error("获取最近联系人失败", e);
        this.memberList = [];
      } finally {
        this.loading = false;
      }
    },

    // 点击成员，与 Qt OnSecListMenuSwitch 对应
    handleMemberClick(member) {
      this.currentUser = { ...member };
    },

    // 搜索联系人，与 Qt searchContactsClicked 对应
    async handleSearch() {
      const text = this.searchText.trim();
      if (!text) {
        if (this.isLatestContacts) {
          this.fetchLatestContacts();
        } else if (this.currentGroupId) {
          this.fetchMembers(this.currentGroupId);
        }
        return;
      }
      this.loading = true;
      try {
        const res = await searchUsers({
          search_key: text,
          user_ids: [],
          page: 1,
          size: 10000,
        });
        const list = res.data?.list || [];
        this.isLatestContacts = true;
        this.currentStructureName = "搜索结果";
        this.currentGroupId = null;
        this.$refs.orgTree.setCurrentKey(null);
        this.memberList = list.map((item) => ({
          id: item.id,
          name: item.name,
          role: item.role,
          phone: item.phone,
          status: item.status,
          email: item.email,
          group: item.group,
          full_group: item.full_group,
          avatar: item.avatar,
          online: item.online === 1 || item.online === true,
        }));
      } catch (e) {
        console.error("搜索联系人失败", e);
      } finally {
        this.loading = false;
      }
    },

    // 清除搜索
    handleClearSearch() {
      this.searchText = "";
      if (this.isLatestContacts) {
        this.fetchLatestContacts();
      } else if (this.currentGroupId) {
        this.fetchMembers(this.currentGroupId);
      } else if (this.userGroupId) {
        this.fetchMembers(this.userGroupId);
      }
    },

    // 刷新
    handleRefresh() {
      if (this.isLatestContacts) {
        this.fetchLatestContacts();
      } else if (this.currentGroupId) {
        this.fetchMembers(this.currentGroupId);
      }
    },

    // 发消息，与 Qt SendMessag / SignalSendSelectedContactInfo 对应
    sendMessage() {
      if (!this.currentUser) return;
      // 跳转到消息页面并传递联系人信息
      this.$router.push({
        path: "/message",
        query: {
          contactId: this.currentUser.id,
          contactName: this.currentUser.name,
          scene: 1,
        },
      });
    },
  },
};
</script>

<style lang="scss" scoped>
.addrbook-page {
  display: flex;
  height: 100%;
}

.addrbook-left {
  width: 240px;
  border-right: 1px solid #ebeef5;
  overflow-y: auto;

  .latest-contacts {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 12px 16px;
    height: 61px;
    border-bottom: 1px solid #ebeef5;
    cursor: pointer;
    font-size: 14px;
    color: #606266;
    transition: all 0.2s;

    i {
      font-size: 16px;
    }

    &:hover {
      background: #e5f1fb;
      color: #409eff;
    }

    &.active {
      background: #e5f1fb;
      color: #409eff;
    }
  }

  ::v-deep .el-tree {
    background: transparent;

    .el-tree-node__content {
      height: 40px;
    }

    .el-tree-node:focus > .el-tree-node__content {
      background-color: #e5f1fb;
    }

    .el-tree-node__content:hover {
      background-color: #f0f7ff;
    }
  }
}

.addrbook-center {
  width: 280px;
  border-right: 1px solid #ebeef5;
  display: flex;
  flex-direction: column;

  .center-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 12px 16px;
    border-bottom: 1px solid #ebeef5;
    height: 61px;
    .structure-name {
      font-size: 14px;
      font-weight: 500;
      color: #303133;
    }

    .refresh-btn {
      font-size: 16px;
      color: #909399;
      cursor: pointer;

      &:hover {
        color: #409eff;
      }
    }
  }

  .search-box {
    padding: 12px 16px;
    border-bottom: 1px solid #ebeef5;
  }

  .member-list {
    flex: 1;
    overflow-y: auto;

    .member-item {
      display: flex;
      align-items: center;
      gap: 10px;
      padding: 8px 16px;
      cursor: pointer;
      transition: background 0.2s;
      position: relative;

      &:hover {
        background: #f5f7fa;
      }

      &.active {
        background: #e5f1fb;
      }

      &.offline {
        .member-name {
          color: #909399;
        }
      }

      .member-name {
        font-size: 14px;
        color: #303133;
        flex: 1;
        overflow: hidden;
        text-overflow: ellipsis;
        white-space: nowrap;
      }

      .online-dot {
        width: 8px;
        height: 8px;
        border-radius: 50%;
        background: #67c23a;
        flex-shrink: 0;
      }
    }
  }
}

.addrbook-right {
  flex: 1;
  background: #fff;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;

  .detail-panel {
    width: 100%;
    max-width: 400px;
    padding: 40px 24px;

    .avatar-section {
      display: flex;
      justify-content: center;
      margin-bottom: 32px;
    }

    .info-section {
      .info-row {
        display: flex;
        align-items: center;
        justify-content: space-between;
        gap: 8px;
        padding: 12px 0;
        border-bottom: 1px solid #f0f0f0;
        i {
          font-size: 16px;
          color: #009393;
          width: 20px;
          text-align: center;
        }

        .label {
          width: 70px;
          font-size: 14px;
          color: #909399;
          flex-shrink: 0;
        }

        .value {
          flex: 1;
          font-size: 14px;
          color: #303133;
          overflow: hidden;
          text-overflow: ellipsis;
          white-space: nowrap;
          text-align: right;

          &.online {
            color: #67c23a;
          }

          &.offline {
            color: #909399;
          }
        }
      }
    }

    .action-section {
      display: flex;
      gap: 16px;
      justify-content: center;
      margin-top: 32px;

      .el-button {
        min-width: 120px;
      }
    }
  }

  .empty-detail {
    width: 100%;
    height: 100%;
    display: flex;
    align-items: center;
    justify-content: center;
  }
}
</style>