<template>
  <view class="tab-page">
    <view v-if="loading" class="chat-loading">
      <loading :size="50" :mask="false">
        <view>消息接收中...</view>
      </loading>
    </view>
    <view class="header">
			<uni-icons class="btn-side left" type="back" size="20" @click="onNavBack"></uni-icons>
			<text class="title">消息 {{ unreadCount>0?`(${unreadCount})`:'' }} </text>
			<uni-icons class="btn-side right" type="plus" size="20" @click="toFriendList"></uni-icons>
		</view>
    <view class="chat-tip" v-if="!loading && chatStore.chats.length == 0">
      温馨提示：您现在还没有任何聊天消息，快跟您的好友发起聊天吧~
    </view>
    <scroll-view
      class="scroll-bar"
      v-else
      scroll-with-animation="true"
      scroll-y="true"
    >
      <view v-for="(chat, index) in chatStore.chats" :key="index">
        <chat-item
          :chat="chat"
          :index="index"
          @longpress.native="onShowMenu($event, index)"
        ></chat-item>
      </view>
    </scroll-view>

    <pop-menu
      v-show="menu.show"
      :menu-style="menu.style"
      :items="menu.items"
      @close="menu.show = false"
      @select="onSelectMenu"
    ></pop-menu>
  </view>
</template>

<script setup>
    import { reactive, nextTick, computed } from "vue";
    import chatItem from "./components/chat-item.vue";
    import popMenu from "../components/pop-menu.vue";
    import { useChatStore } from "@/common/store/im/chatStore.js";
    import { useFriendStore } from '@/common/store/im/friendStore.js';
    import { useGroupStore } from '@/common/store/im/groupStore.js';
    import { useIMUserStore } from '@/common/store/im/imUserStore.js';
    import * as wsApi from '@/common/config/wssocket';
    import http from '@/common/request/im.js';
    import config from "@/common/config/index.js";
    import { MESSAGE_TYPE } from '@/common/enums/im.ts';
    import { onLoad } from '@dcloudio/uni-app';

    const friendStore = useFriendStore();
    const groupStore = useGroupStore();
    const chatStore = useChatStore();
    const imUserStore = useIMUserStore();

    const menu = reactive({
      show: false,
      style: "",
      chatIdx: -1,
      items: [
        {
          key: "DELETE",
          name: "删除",
          icon: "trash",
        },
        {
          key: "TOP",
          name: "置顶",
          icon: "arrow-up",
        },
      ],
    });

    const unreadCount = computed(() => {
      let count = 0;
      chatStore.chats.forEach((chat) => {
        count += chat.unreadCount;
      });
      return count;
    });

    const loading = computed(() => {
      return chatStore.loadingGroupMsg || chatStore.loadingPrivateMsg;
    });

    onLoad(() => {
      // init();
    });

    const onSelectMenu = (item) => {
      switch (item.key) {
        case "DELETE":
          removeChat(menu.chatIdx);
          break;
        case "TOP":
          moveToTop(menu.chatIdx);
          break;
        default:
          break;
      }
      menu.show = false;
    };

    const onShowMenu = (e, chatIdx) => {
      uni.getSystemInfo({
        success: (res) => {
          let touches = e.touches[0];
          let style = "";
          /* 因 非H5端不兼容 style 属性绑定 Object ，所以拼接字符 */
          if (touches.clientY > res.windowHeight / 2) {
            style = `bottom:${res.windowHeight - touches.clientY}px;`;
          } else {
            style = `top:${touches.clientY}px;`;
          }
          if (touches.clientX > res.windowWidth / 2) {
            style += `right:${res.windowWidth - touches.clientX}px;`;
          } else {
            style += `left:${touches.clientX}px;`;
          }
          menu.style = style;
          menu.chatIdx = chatIdx;
          nextTick(() => {
            menu.show = true;
          });
        },
      });
    };

    const onNavBack = () => {
      uni.reLaunch({
        url: "/pages/msg/msg"
      })
    }

    const toFriendList = () => {
      uni.navigateTo({
        url:'/pages/msg/im/friend/friend'
      })
    }

    const removeChat = (chatIdx) => {
      chatStore.removeChat(chatIdx);
    };

    const moveToTop = (chatIdx) => {
      chatStore.moveTop(chatIdx);
    };

    const init = () => {
      // // 审核
      // initAudit();
      // // 初始化websocket
      // initWebSocket();
      // // 加载离线消息
      loadPrivateMessage(chatStore.privateMsgMaxId);
      loadGroupMessage(chatStore.groupMsgMaxId);
      // 加载数据
      imUserStore.loadUser()
        .then(() => {
          friendStore.loadFriend();
          groupStore.loadGroup();
          chatStore.loadChat();

          // 审核
          // initAudit();
          // 初始化websocket
          initWebSocket();
          // 加载离线消息
          loadPrivateMessage(chatStore.privateMsgMaxId);
          loadGroupMessage(chatStore.groupMsgMaxId);
        })
        .catch((e) => {
          console.log(e);
          exit();
        });
    };
    const initWebSocket = () => {
      let loginInfo = uni.getStorageSync("loginInfo");
      wsApi.init();
      wsApi.connect(config.IM_WS_URL, loginInfo.accessToken);
      wsApi.onMessage((cmd, msgInfo) => {
        if (cmd == 2) {
          // 异地登录，强制下线
          uni.showModal({
            content: "您已在其他地方登陆，将被强制下线",
            showCancel: false,
          });
          exit();
        } else if (cmd == 3) {
          // 私聊消息
          handlePrivateMessage(msgInfo);
        } else if (cmd == 4) {
          // 群聊消息
          handleGroupMessage(msgInfo);
        }
      });
      wsApi.onClose((res) => {
        // 3000是客户端主动关闭
        if (res.code != 3000) {
          // 重新连接
          uni.showToast({
            title: "连接已断开，尝试重新连接...",
            icon: "none",
          });
          let loginInfo = uni.getStorageSync("loginInfo");
          wsApi.reconnect(process.env.WS_URL, loginInfo.accessToken);
        }
      });
    };
    const loadPrivateMessage = (minId) => {
      chatStore.updateLoadingPrivateMsg(true);
      http({
        url: "/message/private/loadMessage?minId=" + minId,
        method: "GET",
      }).then((msgInfos) => {
        msgInfos.forEach((msgInfo) => {
          msgInfo.selfSend = msgInfo.sendId == imUserStore.userInfo.id;
          let friendId = msgInfo.selfSend ? msgInfo.recvId : msgInfo.sendId;
          let friend = friendStore.friends.find(
            (f) => f.id == friendId
          );
          if (friend) {
            insertPrivateMessage(friend, msgInfo);
          }
        });
        if (msgInfos.length == 100) {
          // 继续拉取
          loadPrivateMessage(msgInfos[99].id);
        } else {
          chatStore.updateLoadingPrivateMsg(false);
        }
      });
    };
    const loadGroupMessage = (minId) => {
      chatStore.updateLoadingGroupMsg(true);
      http({
        url: "/message/group/loadMessage?minId=" + minId,
        method: "GET",
      }).then((msgInfos) => {
        msgInfos.forEach((msgInfo) => {
          msgInfo.selfSend = msgInfo.sendId == imUserStore.userInfo.id;
          let groupId = msgInfo.groupId;
          let group = groupStore.groups.find((g) => g.id == groupId);
          if (group) {
            insertGroupMessage(group, msgInfo);
          }
        });
        if (msgInfos.length == 100) {
          // 继续拉取
          loadGroupMessage(msgInfos[99].id);
        } else {
          chatStore.updateLoadingGroupMsg(false);
        }
      });
    };
    const handlePrivateMessage = (msg) => {
      // 标记这条消息是不是自己发的
      msg.selfSend = msg.sendId == imUserStore.userInfo.id;
      // 好友id
      let friendId = msg.selfSend ? msg.recvId : msg.sendId;
      // 消息已读处理
      if (msg.type == MESSAGE_TYPE.READED) {
        if (msg.selfSend) {
          // 我已读对方的消息，清空已读数量
          let chatInfo = {
            type: "PRIVATE",
            targetId: friendId,
          };
          chatStore.resetUnreadCount(chatInfo);
        } else {
          // 对方已读我的消息，修改消息状态为已读
          chatStore.readedMessage({ friendId: friendId });
        }
        return;
      }
      loadFriendInfo(friendId).then((friend) => {
        insertPrivateMessage(friend, msg);
      });
    };
    const insertPrivateMessage = (friend, msg) => {
      let chatInfo = {
        type: "PRIVATE",
        targetId: friend.id,
        showName: friend.nickName,
        headImage: friend.headImage,
      };
      // 打开会话
      chatStore.openChat(chatInfo);
      // 插入消息
      chatStore.insertMessage(msg);
      // 播放提示音
      // !msg.selfSend && playAudioTip();
    };
    const handleGroupMessage = (msg) => {
      // 标记这条消息是不是自己发的
      msg.selfSend = msg.sendId == imUserStore.userInfo.id;
      let groupId = msg.groupId;
      // 消息已读处理
      if (msg.type == MESSAGE_TYPE.READED) {
        // 我已读对方的消息，清空已读数量
        let chatInfo = {
          type: "GROUP",
          targetId: groupId,
        };
        chatStore.resetUnreadCount(chatInfo);
        return;
      }
      loadGroupInfo(groupId).then((group) => {
        // 插入群聊消息
        insertGroupMessage(group, msg);
      });
    };
    const insertGroupMessage = (group, msg) => {
      let chatInfo = {
        type: "GROUP",
        targetId: group.id,
        showName: group.remark,
        headImage: group.headImageThumb,
      };
      // 打开会话
      chatStore.openChat(chatInfo);
      // 插入消息
      chatStore.insertMessage(msg);
      // 播放提示音
      // !msg.selfSend && playAudioTip();
    };
    const loadFriendInfo = (id) => {
      return new Promise((resolve, reject) => {
        let friend = friendStore.friends.find((f) => f.id == id);
        if (friend) {
          resolve(friend);
        } else {
          http({
            url: `/friend/find/${id}`,
            method: "get",
          }).then((friend) => {
            friendStore.addFriend(friend);
            resolve(friend);
          });
        }
      });
    };
    const loadGroupInfo = (id) => {
      return new Promise((resolve, reject) => {
        let group = groupStore.groups.find((g) => g.id == id);
        if (group) {
          resolve(group);
        } else {
          http({
            url: `/group/find/${id}`,
            method: "get",
          }).then((group) => {
            resolve(group);
            groupStore.addGroup(group);
          });
        }
      });
    };
    const initAudit = () => {
      if (imUserStore.userInfo.type == 1) {
        // 显示群组功能
        uni.setTabBarItem({
          index: 2,
          text: "群聊",
        });
      } else {
        // 隐藏群组功能
        uni.setTabBarItem({
          index: 2,
          text: "搜索",
        });
      }
    };
</script>

<style scoped lang="scss">
.chat-tip {
  position: absolute;
  top: 400rpx;
  padding: 50rpx;
  line-height: 50rpx;
  text-align: left;
  color: darkblue;
  font-size: 30rpx;
}

.chat-loading {
  display: block;
  height: 100rpx;
  background: white;
  position: relative;
  color: blue;
}

.header {
     display: flex;
			justify-content: center;
			align-items: center;
			height: 60rpx;
			padding: 10px;
			background: linear-gradient(180deg, #d8e2fb 0%, #f1f5fe 100%);
			line-height: 50px;
			font-size: 35rpx;
			font-weight: 600;
			color:#203350;
			border-bottom: 1px solid #eee;


			.btn-side {
				position: absolute;
				line-height: 60rpx;
				font-size: 28rpx;
				cursor: pointer;

				&.left {
					left: 30rpx;
				}

				&.right {
					right: 30rpx;
				}
			}
		}
</style>
