<template>
  <div class="app-container addrbook-page">
    <!-- 左侧树区域 -->
    <div class="addrbook-left">
      <div
        v-for="(item, idx) in leftTabList"
        :key="idx"
        class="latest-contacts"
        :class="{ active: item.flag && isLatestContacts }"
        @click="item.fn()"
      >
        <i :class="item.icon" />
        <span>{{ item.label }}</span>
      </div>
      <el-tree
        ref="orgTree"
        :data="treeData"
        :props="treeProps"
        :default-expanded-keys="defaultExpandedKeys"
        highlight-current
        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" @scroll="handleScroll">
        <div
          v-for="member in memberList"
          :key="member.id"
          class="member-item"
          :class="{
            active: currentUser.id === member.id,
            offline: !member.online,
          }"
          @click="setSelectUser(member)"
        >
          <el-avatar
            :size="32"
            :src="getAvatarUrl(member.avatar)"
            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 && !memberList.length"
          description="暂无成员"
        />
        <!-- 分页底部提示，仅常用联系人展示 -->
        <div
          v-if="isLatestContacts && memberList.length > 0"
          class="load-more-tip"
        >
          <span v-if="loadMoreLoading">加载更多...</span>
          <span v-if="noMore && !loadMoreLoading">没有更多数据了</span>
        </div>
      </div>
    </div>

    <!-- 右侧详情 -->
    <div class="addrbook-right">
      <div v-if="currentUser" class="detail-panel">
        <div class="avatar-section">
          <el-avatar
            :size="80"
            :src="getAvatarUrl(currentUser.avatar)"
            icon="el-icon-user-solid"
          />
        </div>
        <div class="info-section">
          <div v-for="info in userInfoList" :key="info.key" class="info-row">
            <i :class="info.icon" />
            <span class="label">{{ info.label }}</span>
            <el-tooltip
              :content="
                info.key === 'online'
                  ? currentUser.online
                    ? '正常'
                    : '离线'
                  : currentUser[info.key]
              "
              placement="top"
            >
              <span
                class="value"
                :class="
                  info.key === 'online'
                    ? currentUser.online
                      ? 'online'
                      : 'offline'
                    : ''
                "
              >
                {{
                  info.key === "online"
                    ? currentUser.online
                      ? "正常"
                      : "离线"
                    : currentUser[info.key]
                }}
              </span>
            </el-tooltip>
          </div>
        </div>
        <div class="action-section">
          <el-button
            type="primary"
            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 {
  getMessagesLatestContacts,
  getGroupsList,
  getGroupsListUser,
  searchUsers,
} from "@/api/contacts/index.js";
export default {
  name: "Contacts",
  data() {
    return {
      treeData: [],
      treeProps: { label: "name", children: "child" },
      defaultExpandedKeys: [],
      currentGroupId: null,
      currentStructureName: "",
      memberList: [],
      currentUser: null,
      searchText: "",
      loading: false,
      isLatestContacts: false,
      userGroupId: null,
      // 分页配置（仅常用联系人/搜索使用）
      pageNum: 1,
      pageSize: 15,
      noMore: false,
      loadMoreLoading: false,
      // 左侧顶部菜单配置
      leftTabList: [
        {
          label: "常用联系人",
          icon: "el-icon-time",
          flag: true,
          fn: () => this.showLatestContacts(),
        },
        {
          label: "组织架构",
          icon: "el-icon-office-building",
          flag: false,
          fn: () => this.fetchOrgTree(),
        },
      ],
      // 用户详情配置
      userInfoList: [
        { label: "姓名", icon: "el-icon-user", key: "name" },
        { label: "邮箱", icon: "el-icon-message", key: "email" },
        { label: "部门", icon: "el-icon-office-building", key: "full_group" },
        { label: "职位", icon: "el-icon-s-custom", key: "role" },
        { label: "手机", icon: "el-icon-phone", key: "phone" },
        { label: "状态", icon: "el-icon-info", key: "online" },
      ],
    };
  },
  computed: {
    MINIO_BASE() {
      return this.$store.state.user.netConfig.MINIO_ENDPOINT_HTTPS || "";
    },
  },
  mounted() {
    this.fetchOrgTree();
    this.showLatestContacts();
  },
  methods: {
    // 统一获取头像地址
    getAvatarUrl(avatar) {
      if (!avatar) return "";
      return avatar.startsWith("http") ? avatar : `${this.MINIO_BASE}${avatar}`;
    },
    // 选中联系人公共方法
    setSelectUser(user) {
      this.currentUser = { ...user };
    },
    // 重置分页参数
    resetPage() {
      this.pageNum = 1;
      this.noMore = false;
      this.memberList = [];
    },
    // 滚动触底
    handleScroll(e) {
      // 组织架构不触发分页加载，直接返回
      if (!this.isLatestContacts) return;
      const el = e.target;
      const scrollTop = el.scrollTop;
      const scrollHeight = el.scrollHeight;
      const clientHeight = el.clientHeight;
      // 距离底部50px触发加载
      if (scrollTop + clientHeight >= scrollHeight - 50) {
        this.loadNextPage();
      }
    },
    // 加载下一页
    loadNextPage() {
      // 多重拦截：加载中 / 无更多数据
      if (this.loadMoreLoading || this.noMore || this.loading) return;
      this.pageNum++;
      this.loadMemberList(false);
    },
    // 统一加载列表
    // isRefresh: true=第一页刷新 false=滚动追加
    async loadMemberList(isRefresh = true) {
      if (isRefresh) {
        this.loading = true;
        this.resetPage();
      } else {
        this.loadMoreLoading = true;
      }
      try {
        const keyword = this.searchText.trim();
        let resList = [];
        // 搜索场景（分页）
        if (keyword) {
          const { data } = await searchUsers({
            search_key: keyword,
            user_ids: [],
            page: this.pageNum,
            size: this.pageSize,
          });
          resList = data.list || [];
          this.isLatestContacts = true;
          this.currentStructureName = "搜索结果";
          this.currentGroupId = null;
          this.$refs.orgTree.setCurrentKey(null);
        } else if (this.isLatestContacts) {
          // 常用联系人（分页）
          const { data } = await getMessagesLatestContacts({
            scene: 1,
            page: this.pageNum,
            size: this.pageSize,
          });
          resList = data.list || [];
        } else {
          // 组织架构：不分页，一次性全量获取
          const { data } = await getGroupsListUser({
            group_id: this.currentGroupId,
          });
          resList = data.list || [];
        }

        const formatList = resList.map((item) => ({
          ...item,
          online: [1, true].includes(item.online),
        }));

        if (isRefresh) {
          this.memberList = formatList;
        } else {
          this.memberList.push(...formatList);
        }

        // 仅常用/搜索场景判断是否还有下一页
        if (this.isLatestContacts) {
          this.noMore = formatList.length < this.pageSize;
        } else {
          this.noMore = true; // 组织架构永远无更多
        }

        // 首次加载自动选中第一条
        if (isRefresh && this.memberList.length) {
          this.setSelectUser(this.memberList[0]);
        }
      } catch (err) {
        console.error("加载列表失败", err);
        if (isRefresh) this.memberList = [];
      } finally {
        this.loading = false;
        this.loadMoreLoading = false;
      }
    },
    // 树形结构相关
    async fetchOrgTree() {
      try {
        const { data } = await getGroupsList();
        this.treeData = data.list;
        this.defaultExpandedKeys = this.treeData.map((node) => node.id);
        if (!this.userGroupId) return;
        const parentKeys = this.findParentKeys(this.treeData, this.userGroupId);
        this.$nextTick(() => {
          this.$refs.orgTree.setCurrentKey(this.userGroupId);
          const node = this.findNodeById(this.treeData, this.userGroupId);
          if (node) {
            this.currentStructureName = node.name;
            this.currentGroupId = node.id;
            this.loadMemberList(true);
          }
        });
      } catch (err) {
        console.error("获取组织架构失败", err);
      }
    },
    findParentKeys(tree, targetId, parents = []) {
      for (const node of tree) {
        if (node.id === targetId) return [...parents, node.id];
        if (node.child && node.child.length) {
          const res = this.findParentKeys(node.child, targetId, [
            ...parents,
            node.id,
          ]);
          if (res.length) return res;
        }
      }
      return [];
    },
    findNodeById(tree, id) {
      for (const node of tree) {
        if (node.id === id) return node;
        if (node.child) {
          const res = this.findNodeById(node.child, id);
          if (res) return res;
        }
      }
      return null;
    },
    // 树点击（组织架构）
    handleNodeClick(data) {
      this.isLatestContacts = false;
      this.currentStructureName = data.name;
      this.currentGroupId = data.id;
      this.currentUser = null;
      this.loadMemberList(true);
    },
    // 兼容旧接口
    fetchMembers(groupId) {
      this.currentGroupId = groupId;
      this.loadMemberList(true);
    },
    // 常用联系人入口
    showLatestContacts() {
      this.isLatestContacts = true;
      this.currentStructureName = "最近联系人";
      this.currentGroupId = null;
      this.currentUser = null;
      this.$refs.orgTree.setCurrentKey(null);
      this.loadMemberList(true);
    },
    // 搜索
    handleSearch() {
      const keyword = this.searchText.trim();
      if (!keyword) return this.handleClearSearch();
      this.loadMemberList(true);
    },
    // 清空搜索
    handleClearSearch() {
      this.searchText = "";
      if (this.isLatestContacts) {
        this.showLatestContacts();
      } else if (this.currentGroupId) {
        this.loadMemberList(true);
      } else if (this.userGroupId) {
        this.currentGroupId = this.userGroupId;
        this.loadMemberList(true);
      }
    },
    // 刷新
    handleRefresh() {
      this.loadMemberList(true);
    },
    // 跳转发消息
    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,
    &.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;
  .search-box,
  .center-header {
    padding: 12px 16px;
    border-bottom: 1px solid #ebeef5;
    height: 61px;
  }
  .center-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    .structure-name {
      font-size: 14px;
      font-weight: 500;
      color: #303133;
    }
    .refresh-btn {
      font-size: 16px;
      color: #909399;
      cursor: pointer;
      &:hover {
        color: #409eff;
      }
    }
  }
  .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;
      &:hover {
        background: #f5f7fa;
      }
      &.active {
        background: #e5f1fb;
      }
      &.offline .member-name {
        color: #909399;
      }
      .member-name {
        flex: 1;
        overflow: hidden;
        text-overflow: ellipsis;
        white-space: nowrap;
        font-size: 14px;
        color: #303133;
      }
      .online-dot {
        width: 8px;
        height: 8px;
        border-radius: 50%;
        background: #67c23a;
        flex-shrink: 0;
      }
    }
    .load-more-tip {
      padding: 12px;
      text-align: center;
      font-size: 12px;
      color: #909399;
    }
  }
}
// 右侧详情
.addrbook-right {
  flex: 1;
  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>