import 'dart:convert';

import 'package:chat/controllers/group_controller.dart';
import 'package:chat/models/im/custom_message_model.dart';
import 'package:chat/services/auth_service.dart';
import 'package:chat/services/tim/apply_service.dart';
import 'package:chat/services/tim/block_service.dart';
import 'package:chat/services/tim/conversation_service.dart';
import 'package:chat/services/tim/friend_service.dart';
import 'package:chat/services/tim/group_service.dart';
import 'package:chat/services/tim/message_service.dart';
import 'package:chat/utils/ui_tools.dart';
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:tencent_im_sdk_plugin/enum/V2TimAdvancedMsgListener.dart';
import 'package:tencent_im_sdk_plugin/enum/V2TimFriendshipListener.dart';
import 'package:tencent_im_sdk_plugin/enum/V2TimGroupListener.dart';
import 'package:tencent_im_sdk_plugin/enum/V2TimSDKListener.dart';
import 'package:tencent_im_sdk_plugin/enum/log_level_enum.dart';
import 'package:tencent_im_sdk_plugin/enum/message_elem_type.dart';
import 'package:tencent_im_sdk_plugin/manager/v2_tim_manager.dart';
import 'package:tencent_im_sdk_plugin/models/v2_tim_friend_application.dart';
import 'package:tencent_im_sdk_plugin/models/v2_tim_friend_info.dart';
import 'package:tencent_im_sdk_plugin/models/v2_tim_group_change_info.dart';
import 'package:tencent_im_sdk_plugin/models/v2_tim_group_member_change_info.dart';
import 'package:tencent_im_sdk_plugin/models/v2_tim_group_member_info.dart';
import 'package:tencent_im_sdk_plugin/models/v2_tim_message.dart';
import 'package:tencent_im_sdk_plugin/models/v2_tim_message_receipt.dart';
import 'package:tencent_im_sdk_plugin/models/v2_tim_topic_info.dart';
import 'package:tencent_im_sdk_plugin/models/v2_tim_user_full_info.dart';
import 'package:tencent_im_sdk_plugin/models/v2_tim_user_status.dart';
import 'package:tencent_im_sdk_plugin/tencent_im_sdk_plugin.dart';
import 'package:vibration/vibration.dart';

class TimService extends GetxService {
  static TimService get to => Get.find<TimService>();

  /// 获取实例
  V2TIMManager get instance => _getInstance();

  /// 获取TIM实例
  V2TIMManager _getInstance() {
    return TencentImSDKPlugin.v2TIMManager;
  }

  int sdkAppID = 1400754674;

  String get _userSig => AuthService.to.userSig;

  String get _userId => AuthService.to.userId;

  RxString currentConversationId = ''.obs;

  @override
  void onInit() {
    super.onInit();

    if (AuthService.to.isLogin.value) {
      initSdk();
    }
  }

  Future initSdk() async {
    /// 初始化TIMSDK
    await instance.initSDK(
      sdkAppID: sdkAppID,
      loglevel: LogLevelEnum.V2TIM_LOG_INFO,
      listener: V2TimSDKListener(
        onConnectFailed: (
          int code,
          String error,
        ) {},
        onConnectSuccess: () async {},
        onConnecting: () {},
        onKickedOffline: () {
          UiTools.toast('该账号在其他设备登录被迫下线');
          AuthService.to.logout();
        },
        onSelfInfoUpdated: (
          V2TimUserFullInfo info,
        ) {},
        onUserSigExpired: () {},
        onUserStatusChanged: (List<V2TimUserStatus> userStatusList) {},
        onLog: (int logLevel, String logContent) {},
      ),
    );

    /// 登录
    var loginResult = await instance.login(
      userID: _userId,
      userSig: _userSig,
    );

    if (loginResult.code != 0) {
      UiTools.toast(loginResult.desc);
      await AuthService.to.logout();
    }

    Get.put(TimConversationService());
    Get.put(TimFriendService());
    Get.put(TimGroupService());
    Get.put(TimBlockService());
    Get.put(TimApplyService());
    Get.put(TimMessageService());

    /// 消息监听器
    await TimConversationService.to.messageManager.addAdvancedMsgListener(
      listener: V2TimAdvancedMsgListener(
        /// 收到新消息
        onRecvNewMessage: (
          V2TimMessage msg,
        ) {
          onRecvNewMessage(msg);
        },

        /// 收到C2C已读回执
        onRecvC2CReadReceipt: (
          List<V2TimMessageReceipt> receiptList,
        ) {},

        /// 消息撤回
        onRecvMessageRevoked: (
          String msgID,
        ) {},

        /// 发送消息进度
        onSendMessageProgress: (
          V2TimMessage message,
          int progress,
        ) {},

        /// 消息更改
        onRecvMessageModified: (
          V2TimMessage msg,
        ) {},

        /// 消息已读回执
        onRecvMessageReadReceipts: (
          List<V2TimMessageReceipt> receiptList,
        ) {},
      ),
    );

    await TimFriendService.to.friendshipManager.setFriendListener(
      listener: V2TimFriendshipListener(
        /// 有新的好友请求
        onFriendApplicationListAdded: (
          List<V2TimFriendApplication> applicationList,
        ) {
          TimApplyService.to.fetchList();
        },
        onFriendApplicationListDeleted: (
          List<String> userIDList,
        ) {
          TimApplyService.to.fetchList();
        },
        onFriendApplicationListRead: () {
          // UiTools.toast('onFriendApplicationListRead');
        },
        onFriendListAdded: (
          List<V2TimFriendInfo> users,
        ) {
          TimFriendService.to.fetchList();
        },
        onFriendListDeleted: (
          List<String> userList,
        ) {
          TimFriendService.to.fetchList();
        },

        /// 有黑名单
        onBlackListAdd: (
          List<V2TimFriendInfo> infoList,
        ) {
          TimFriendService.to.fetchList();
          TimBlockService.to.fetchList();
        },

        /// 移除黑名单
        onBlackListDeleted: (
          List<String> userList,
        ) {
          TimFriendService.to.fetchList();
          TimBlockService.to.fetchList();
        },

        /// 好友资料修改
        onFriendInfoChanged: (
          List<V2TimFriendInfo> infoList,
        ) {
          TimFriendService.to.fetchList();
        },
      ),
    );

    await instance.setGroupListener(
      listener: V2TimGroupListener(
        /// 群组解散
        onGroupDismissed: (
          String groupID,
          V2TimGroupMemberInfo opUser,
        ) async {
          await TimConversationService.to.deleteById(
            'group_$groupID',
          );
          await TimGroupService.to.fetchList();

          /// 如果是在当前的会话中，关闭会话内容，返回主页面
          if (currentConversationId.value == 'group_' + groupID) {
            UiTools.toast('群已解散');
            Navigator.popUntil(Get.context!, (route) => route.isFirst);
          }
        },

        /// 群资料修改
        onGroupInfoChanged: (
          String groupID,
          List<V2TimGroupChangeInfo?> changeInfos,
        ) {
          TimConversationService.to.fetchList();
          TimGroupService.to.fetchList();
        },
        onMemberEnter: (
          String groupID,
          List<V2TimGroupMemberInfo> memberList,
        ) {
          UiTools.toast('onMemberEnter');
        },
        onMemberLeave: (
          String groupID,
          V2TimGroupMemberInfo member,
        ) {
          UiTools.toast('onMemberLeave');
        },
        onMemberInvited: (
          String groupID,
          V2TimGroupMemberInfo opUser,
          List<V2TimGroupMemberInfo> memberList,
        ) {
          UiTools.toast('onMemberInvited');
        },

        /// 有用户被移出群聊，判断是否当前用户，当前会话，关闭会话
        onMemberKicked: (
          String groupID,
          V2TimGroupMemberInfo opUser,
          List<V2TimGroupMemberInfo> memberList,
        ) {
          bool isYou = memberList
              .where((e) => true
                  // e.userID ==
                  // UserController.to.userInfo.value!.userId.toString(),
                  )
              .isNotEmpty;
          if (isYou) {
            if (currentConversationId.value == 'group_' + groupID) {
              UiTools.toast('您已被${opUser.nickName}移出当前群聊');
              Navigator.popUntil(Get.context!, (route) => route.isFirst);
            }
            TimConversationService.to.deleteById(
              'group_' + groupID,
            );
            TimGroupService.to.fetchList();
          }
        },
        onMemberInfoChanged: (
          String groupID,
          List<V2TimGroupMemberChangeInfo> v2TIMGroupMemberChangeInfoList,
        ) {
          UiTools.toast('onMemberInfoChanged');
        },
        onGroupRecycled: (
          String groupID,
          V2TimGroupMemberInfo opUser,
        ) {
          UiTools.toast('onGroupRecycled');
        },
        onReceiveJoinApplication: (
          String groupID,
          V2TimGroupMemberInfo member,
          String opReason,
        ) {
          UiTools.toast('onReceiveJoinApplication');
        },
        onApplicationProcessed: (
          String groupID,
          V2TimGroupMemberInfo opUser,
          bool isAgreeJoin,
          String opReason,
        ) {
          UiTools.toast('onApplicationProcessed');
        },

        /// 有新的管理被授权
        onGrantAdministrator: (
          String groupID,
          V2TimGroupMemberInfo opUser,
          List<V2TimGroupMemberInfo> memberList,
        ) {
          if (currentConversationId.value == 'group_' + groupID) {
            GroupController.to.fetchGroupMemberList();
          }
        },

        /// 取消管理员
        onRevokeAdministrator: (
          String groupID,
          V2TimGroupMemberInfo opUser,
          List<V2TimGroupMemberInfo> memberList,
        ) {
          if (currentConversationId.value == 'group_' + groupID) {
            GroupController.to.fetchGroupMemberList();
          }
        },
        onQuitFromGroup: (
          String groupID,
        ) {
          UiTools.toast('onQuitFromGroup');
        },
        onReceiveRESTCustomData: (
          String groupID,
          String customData,
        ) {
          UiTools.toast('onReceiveRESTCustomData');
        },
        onGroupAttributeChanged: (
          String groupID,
          Map<String, String> groupAttributeMap,
        ) {
          UiTools.toast('onGroupAttributeChanged');
        },
        onTopicCreated: (
          String groupID,
          String topicID,
        ) {
          UiTools.toast('onTopicCreated');
        },
        onTopicDeleted: (
          String groupID,
          List<String> topicIDList,
        ) {
          UiTools.toast('onTopicDeleted');
        },
        onTopicInfoChanged: (
          String groupID,
          V2TimTopicInfo topicInfo,
        ) {
          UiTools.toast('onTopicInfoChanged');
        },
      ),
    );
  }

  /// 有新消息的事件处理
  Future<void> onRecvNewMessage(V2TimMessage message) async {
    /// 过滤自定义消息中，用户输入状态的消息
    if (message.elemType == MessageElemType.V2TIM_ELEM_TYPE_CUSTOM) {
      var msgData = json.decode(message.customElem!.data!);

      if (msgData['businessID'] == CustomMessageType.TYPING_STATUS) {
        return;
      }
    }

    var conversation = await TimConversationService.to.getById(
      getConversationIdByMessage(message),
    );
    if (conversation.recvOpt == 0) {
      /// 振动提醒
      Vibration.vibrate(duration: 100);
    }

    if (_isMessageInCurrentConversation(message)) {
      TimConversationService.to.markAsRead(conversation);
    } else {
      await TimConversationService.to.getUnreadCount();
    }

    /// 更新会话列表做了个延迟，要不然列表中的未读消息数量，不正确
    Future.delayed(const Duration(milliseconds: 500), () async {
      await TimConversationService.to.fetchList();
    });
  }

  /// 通过消息判断是否是当前会话
  bool _isMessageInCurrentConversation(V2TimMessage message) {
    return getConversationIdByMessage(message) == currentConversationId.value;
  }

  /// 通过消息获取会话ID
  String getConversationIdByMessage(V2TimMessage message) {
    String conId;
    if (message.groupID != null) {
      conId = 'group_' + message.groupID!;
    } else {
      conId = 'c2c_' + message.userID!;
    }

    return conId;
  }
}
