import 'dart:convert';

import 'package:chat/data/UserData.dart';
import 'package:chat/data/chat_data_mgr.dart';
import 'package:chat/models/group_info_model.dart';
import 'package:chat/proto/chat.pbserver.dart';
import 'package:chat/utils/MessageMgr.dart';
import 'package:chat/utils/group_member_model.dart';
import 'package:chat/utils/sql_util.dart';
import 'package:chat/utils/upload_util.dart';
import 'package:crclib/crclib.dart';

class GroupInfoMgr {
  static GroupInfoMgr _instance;
  factory GroupInfoMgr() => _getInstance();

  GroupInfoMgr._();
  static GroupInfoMgr _getInstance() {
    if (_instance == null) {
      _instance = GroupInfoMgr._();
    }
    return _instance;
  }

  List<GroupInfoModel> groupInfoList = [];

  bool isLoading = false;
  bool isInit = false;

  initLocalGroupList() async {
    if (isInit == true) {
      return;
    }
    isInit = true;
    var res = await SqlUtil.getAllGroupInfo();

    for (var i = 0; i < res.length; i++) {
      if (isGroupInList(res[i].sessionId)) {
        print('群已添加，勿重复添加');
      } else {
        groupInfoList.add(res[i]);
      }
    }
    sortGroupList();
  }

  int getGroupCheckStr(int groupId) {
    for (var group in groupInfoList) {
      if (group.sessionId == groupId) {
        group.members.sort((a, b) => a.memberId.compareTo(b.memberId));
        var checkStr = '';
        for (var member in group.members) {
          if (member.inGroup > 0) {
            checkStr =
                '$checkStr${member.memberId}${member.refName}${member.identity}';
          }
        }
        checkStr = '${group.sessionId}${group.name}${group.describe}$checkStr';

        return Crc32Zlib().convert(utf8.encode(checkStr));
      }
    }
    return -1;
  }

  checkGroupValid() async {
    if (groupInfoList.length > 0) {
      //获取群校验信息
      var groupCheckMap = await UploadUtil().getGroupCheckInfo();

      //获取无效群
      List<int> invalidGroupList = [];

      groupCheckMap.forEach((key, serverCode) {
        int groupId = int.parse(key);
        int checkStr = getGroupCheckStr(groupId);

        if (checkStr != serverCode) {
          print('群校验没有通过 $groupId :$checkStr : $serverCode');
          invalidGroupList.add(groupId);
          clearGroupCache(groupId);
        }
      });

      if (invalidGroupList.length > 0) {
        List<GroupInfoModel> res =
            await UploadUtil().getMoreGroupInfo(invalidGroupList);
        if (res == null || res.length == 0) {
          return;
        }
        for (var i = 0; i < res.length; i++) {
          GroupInfoMgr().addGroup(res[i]);
        }

        MessageMgr().emit('Update Group List');
      }
    } else {
      int localGroupCount = await SqlUtil.getGroupCount();
      if (localGroupCount == 0) {
        print('本地数据没有群数据,从服务器拉取群数据');
        var infoList = await UploadUtil().getGroupList();
        if (infoList == null || infoList.length == 0) {
          return;
        }

        for (var i = 0; i < infoList.length; i++) {
          GroupInfoMgr().addGroup(infoList[i]);
        }

        MessageMgr().emit('Update Group List');
      }
    }
  }

  clearGroupCache(int groupId) async {
    for (var i = 0; i < groupInfoList.length; i++) {
      if (groupInfoList[i].sessionId == groupId) {
        groupInfoList.removeAt(i);
      }
    }
    SqlUtil.groupInfoTableModel.deleteGroup(groupId);
    SqlUtil.groupMemberTableModel.deleteMembers(groupId);
  }

  sortGroupList() {
    print('排序开始');
    for (var item in groupInfoList) {
      print(item.name);
    }
    groupInfoList.sort((GroupInfoModel a, GroupInfoModel b) {
      if (a.topTag > b.topTag) {
        return -1;
      } else if (a.topTag < b.topTag) {
        return 1;
      } else {
        if (a.lastMsg != null && b.lastMsg != null) {
          if (a.lastMsg.updateAt > b.lastMsg.updateAt) {
            return -1;
          } else if (a.lastMsg.updateAt < b.lastMsg.updateAt) {
            return 1;
          } else {
            return 0;
          }
        } else if (a.lastMsg == null) {
          return 1;
        } else if (b.lastMsg == null) {
          return -1;
        } else {
          return 0;
        }
      }
    });
  }

  //获取群中的好友名称
  String getGroupFdName(int sessionId, int fdId) {
    GroupInfoModel group;
    for (var i = 0; i < groupInfoList.length; i++) {
      if (groupInfoList[i].sessionId == sessionId) {
        group = groupInfoList[i];
      }
    }

    if (group == null) {
      print('getGroupFdName 没有找到该群');
    } else {
      for (var member in group.members) {
        if (member.memberId == fdId) {
          return member.refName;
        }
      }
    }

    print('没有找到群好友的名字');

    return '';
  }

  //获取群信息
  Future<GroupInfoModel> getGroupInfo(int sessionId,
      {bool isSave = true}) async {
    if (groupInfoList.length == 0) {
      print('当前没有群');
    } else {
      for (var i = 0; i < groupInfoList.length; i++) {
        if (groupInfoList[i].sessionId == sessionId) {
          return groupInfoList[i];
        }
      }
    }

    var info = await UploadUtil().getGroupInfo(sessionId);
    if (info != null) {
      if (isSave) {
        addGroup(info);
      }

      return info;
    }

    print('群不存在 $sessionId');
    return null;
  }

  bool isGroupInList(int groupId) {
    for (var i = 0; i < groupInfoList.length; i++) {
      if (groupInfoList[i].sessionId == groupId) {
        return true;
      }
    }

    return false;
  }

  //保存群
  void addGroup(GroupInfoModel groupInfoModel) async {
    if (isGroupInList(groupInfoModel.sessionId)) {
      print('群已添加，勿重复添加');
    } else {
      bool isValid = false;
      for (GroupMemberModel member in groupInfoModel.members) {
        if (member.inGroup != 0) {
          isValid = true;
        }
      }

      if (isValid) {
        groupInfoList.add(groupInfoModel);

        var lastMsg = ChatDataMgr().getLastMsg(groupInfoModel.sessionId, true);
        groupInfoModel.updateLastMsg(lastMsg);

        bool isExist = await SqlUtil.groupInfoTableModel
            .isExistGroup(groupInfoModel.sessionId);
        if (!isExist) {
          SqlUtil.groupInfoTableModel.addGroup(groupInfoModel);
          SqlUtil.groupMemberTableModel.addMembers(groupInfoModel);

          print('创群成功!!! 成员数：${groupInfoModel.members.length}');
        }
      }
    }
  }

  //删除群
  void deleteGroup(int groupId) async {
    print('退出群聊 $groupId');

    var groupInfoModel = await getGroupInfo(groupId);

    //清空聊天数据
    ChatDataMgr().deleteMsg(groupId, true);

    if (groupInfoModel != null) {
      groupInfoList.remove(groupInfoModel);
      SqlUtil.groupInfoTableModel.deleteGroup(groupId);
      SqlUtil.groupMemberTableModel.deleteMembers(groupId);

      MessageMgr().emit('Update Group List');
    }
  }

  deleteAllGroup() async {
    print('清空所有群');

    SqlUtil.groupInfoTableModel.clearSelfData();
    SqlUtil.groupMemberTableModel.clearSelfData();
    SqlUtil.groupChatTableModel.clearSelfData();

    groupInfoList.clear();
  }

  //添加群成员
  void addMembers(int groupId, List<BaseUserInfo> members) async {
    print('添加群成员 ${members.length}个');
    var groupInfo = await getGroupInfo(groupId);
    if (groupInfo == null) {
      print('群不存在');
      return;
    }
    cleanAvatar(groupInfo);

    for (var i = 0; i < members.length; i++) {
      var member = GroupMemberModel.fromBaseInfo(members[i]);
      print('添加群成员 ${member.nickName}');
      groupInfo.addMember(member);
    }

    MessageMgr().emit('Update Group Info');
  }

  //自己被移出群
  void removeSelf(int groupId) async {
    var groupInfo = await getGroupInfo(groupId);
    if (groupInfo == null) {
      print('群不存在');
      return;
    }

    var myId = UserData().basicInfo.userId;
    groupInfo.removeMember(myId);
    groupInfo.isInGroup = false;

    MessageMgr().emit('Update Group Info');
  }

  //移出群成员
  void removeMembers(int groupId, List<BaseUserInfo> members) async {
    print('移出群成员 ${members.length}个');

    var groupInfo = await getGroupInfo(groupId);
    if (groupInfo == null) {
      print('群不存在');
      return;
    }
    cleanAvatar(groupInfo);
    for (var i = 0; i < members.length; i++) {
      groupInfo.removeMember(members[i].id);
      print('移出群成员 ${members[i].niceName}');
    }

    MessageMgr().emit('Update Group Info');
  }

  //修改群名称
  void updateGroupName(int groupId, name) async {
    print('修改群名称');

    var groupInfo = await getGroupInfo(groupId);
    if (groupInfo != null) {
      groupInfo.updateGroupName(name);
    }

    MessageMgr().emit('Update Group Info');
  }

  //修改群公告
  void updateGroupDescription(int groupId, String notice) async {
    var groupInfo = await getGroupInfo(groupId);
    if (groupInfo != null) {
      groupInfo.updateGroupNotice(notice);
    }

    MessageMgr().emit('Update Group Info');
  }

  //修改群成员别名
  void updateMemberRefName(int groupId, int uId, String refName) async {
    var groupInfo = await getGroupInfo(groupId);
    if (groupInfo != null) {
      groupInfo.updateMemberRefName(uId, refName);
    }

    MessageMgr().emit('Update Group Info');
  }

  //修改群校验开关
  void updateAskSwitch(int groupId, bool isOpen) async {
    var groupInfo = await getGroupInfo(groupId);
    if (groupInfo != null) {
      groupInfo.updateAskSwitch(isOpen);
    }
  }

  //修改成员免打扰设置
  void updateMemberMsgFree(int groupId, bool isOpen) async {
    var groupInfo = await getGroupInfo(groupId);
    if (groupInfo != null) {
      groupInfo.updateMemberMsgFree(isOpen ? 1 : 0);
    }
  }

  //修改群主
  void updateGroupMaster(int groupId, int oldId, int uId) async {
    var groupInfo = await getGroupInfo(groupId);
    if (groupInfo != null) {
      groupInfo.updateGroupHoster(oldId, uId);
    }
  }

  //更新头像
  void updateAvatar(int groupId, String path) async {
    var groupInfo = await getGroupInfo(groupId);
    if (groupInfo != null) {
      groupInfo.updateAvatar(path);
    }
  }

  void cleanAvatar(GroupInfoModel groupInfo) {
    if (groupInfo != null) {
      print('@@清除群头像');
      groupInfo.cleanAvatar();
    }
  }

  clear() {
    groupInfoList.clear();
    isInit = false;
  }
}
