import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:logger/logger.dart';
import 'package:loopin/IM/controller/chat_controller.dart';
import 'package:loopin/IM/controller/im_user_info_controller.dart';
import 'package:loopin/IM/controller/tab_bar_controller.dart';
import 'package:loopin/IM/global_badge.dart';
import 'package:loopin/IM/im_core.dart';
import 'package:loopin/IM/im_friend_listeners.dart';
import 'package:loopin/IM/im_message_listeners.dart';
import 'package:loopin/IM/im_result.dart';
import 'package:loopin/IM/push_service.dart';
import 'package:loopin/models/conversation_view_model.dart';
import 'package:loopin/utils/wxsdk.dart';
import 'package:tencent_cloud_chat_sdk/enum/friend_application_type_enum.dart';
import 'package:tencent_cloud_chat_sdk/enum/friend_response_type_enum.dart';
import 'package:tencent_cloud_chat_sdk/enum/friend_type_enum.dart';
import 'package:tencent_cloud_chat_sdk/enum/history_msg_get_type_enum.dart';
import 'package:tencent_cloud_chat_sdk/models/v2_tim_callback.dart';
import 'package:tencent_cloud_chat_sdk/models/v2_tim_conversation.dart';
import 'package:tencent_cloud_chat_sdk/models/v2_tim_conversation_filter.dart';
import 'package:tencent_cloud_chat_sdk/models/v2_tim_conversation_operation_result.dart';
import 'package:tencent_cloud_chat_sdk/models/v2_tim_conversation_result.dart';
import 'package:tencent_cloud_chat_sdk/models/v2_tim_follow_info.dart';
import 'package:tencent_cloud_chat_sdk/models/v2_tim_follow_operation_result.dart';
import 'package:tencent_cloud_chat_sdk/models/v2_tim_follow_type_check_result.dart';
import 'package:tencent_cloud_chat_sdk/models/v2_tim_friend_info.dart';
import 'package:tencent_cloud_chat_sdk/models/v2_tim_friend_info_result.dart';
import 'package:tencent_cloud_chat_sdk/models/v2_tim_friend_operation_result.dart';
import 'package:tencent_cloud_chat_sdk/models/v2_tim_message.dart';
import 'package:tencent_cloud_chat_sdk/models/v2_tim_message_change_info.dart';
import 'package:tencent_cloud_chat_sdk/models/v2_tim_message_search_param.dart';
import 'package:tencent_cloud_chat_sdk/models/v2_tim_message_search_result.dart';
import 'package:tencent_cloud_chat_sdk/models/v2_tim_user_full_info.dart';
import 'package:tencent_cloud_chat_sdk/models/v2_tim_user_info_result.dart';
import 'package:tencent_cloud_chat_sdk/models/v2_tim_value_callback.dart';
import 'package:tencent_cloud_chat_sdk/native_im/adapter/tim_conversation_manager.dart';
import 'package:tencent_cloud_chat_sdk/native_im/adapter/tim_friendship_manager.dart';
import 'package:tencent_cloud_chat_sdk/native_im/adapter/tim_message_manager.dart';
import 'package:tencent_cloud_chat_sdk/tencent_im_sdk_plugin.dart';

final logger = Logger();

/// IM 服务封装类
class ImService {
  ImService._();
  static final instance = ImService._();

  /// 登录
  Future<ImResult> login({
    required String userID,
    required String userSig,
  }) async {
    final res = await TencentImSDKPlugin.v2TIMManager.login(
      userID: userID,
      userSig: userSig,
    );
    final result = ImResult(
      success: res.code == 0,
      code: res.code,
      desc: res.desc,
    );

    if (result.success) {
      logger.i("IM 登录成功：$userID");

      // 初始化会话数据
      final ctl = Get.find<ChatController>();
      await ctl.getConversationList();

      /// 初始化微信 SDK
      await Wxsdk.init();

      // 注册用户信息(基本信息+自定义信息)
      if (!Get.isRegistered<ImUserInfoController>()) {
        final imInfo = Get.put(ImUserInfoController(), permanent: true);
        await imInfo.refreshUserInfo();
      } else {
        await Get.find<ImUserInfoController>().refreshUserInfo();
      }

      // 登录成功后注册高级消息监听器
      final messageService = ImMessageListenerService();
      Get.put<ImMessageListenerService>(messageService, permanent: true);

      await messageService.init();

      // 注册关系链监听器
      final friendListener = ImFriendListeners();
      Get.put<ImFriendListeners>(friendListener, permanent: true);
      friendListener.register();

      /// 注册消息未读数监听器
      Get.put(GlobalBadge(), permanent: true);

      // 初始化push服务
      PushService().initPush(
        sdkAppId: 1600080789,
        appKey: 'vkFpe55aYqfV7Sk5uGaoxhEstJ3tcI9dquk7JwG1GloDSLD2HeMWeQweWWXgNlhC',
      );
    } else {
      logger.i("IM 登录失败：${result.code} - ${result.desc}");
      Get.snackbar(
        '登录失败',
        '${result.code} - ${result.desc}',
        backgroundColor: Colors.red.withAlpha(230),
        colorText: Colors.white,
        icon: const Icon(Icons.error_outline, color: Colors.white),
      );
    }
    return result;
  }

  /// 登出
  Future<ImResult> logout() async {
    final res = await TencentImSDKPlugin.v2TIMManager.logout();
    if (res.code == 0) {
      /// 移出消息监听器
      await Get.delete<ImMessageListenerService>(force: true);

      /// 移出关系链监听器
      Get.find<ImFriendListeners>().unregister();
      await Get.delete<ImFriendListeners>(force: true);

      /// 清理tabbar
      Get.find<TabBarController>().badgeMap.clear();

      /// 清理会话列表数据
      Get.find<ChatController>().initChatData();

      /// 移出未读消息监听器
      Get.find<GlobalBadge>().onClose();
      await Get.delete<GlobalBadge>(force: true);

      /// 移除推送服务
      await PushService.unInitPush();

      /// 反初始化
      await ImCore.unInit();
    }
    return ImResult.wrapNoData(res);
  }

  /// 设置会话自定义属性
  Future<ImResult<List<V2TimConversationOperationResult>>> setConversationCustomData({
    required String customData,
    required List<String> conversationIDList,
  }) async {
    final res = await TIMConversationManager.instance.setConversationCustomData(customData: customData, conversationIDList: conversationIDList);

    return ImResult.wrap(res);
  }

  /// 获取符合过滤条件的未读消息总数
  Future<ImResult<int>> getUnreadMessageCountByFilter({
    required V2TimConversationFilter filter,
  }) async {
    final res = await TIMConversationManager.instance.getUnreadMessageCountByFilter(
      filter: filter,
    );
    return ImResult.wrap(res);
  }

  /// 删除会话
  Future<ImResult<void>> deleteConversation({
    required String conversationID,
  }) async {
    final res = await TIMConversationManager.instance.deleteConversation(conversationID: conversationID);

    return ImResult.wrapNoData(res);
  }

  /// 创建会话分组
  Future<ImResult<List<V2TimConversationOperationResult>>> createConversationGroup({
    required String groupName,
    required List<String> conversationIDList,
  }) async {
    final res = await TIMConversationManager.instance.createConversationGroup(
      groupName: groupName,
      conversationIDList: conversationIDList,
    );

    return ImResult.wrap(res);
  }

  /// 获取会话分组列表
  Future<ImResult<List<String>>> getConversationGroupList() async {
    final res = await TIMConversationManager.instance.getConversationGroupList();
    return ImResult.wrap(res);
  }

  /// 将会话添加到分组
  Future<ImResult<List<V2TimConversationOperationResult>>> addConversationsToGroup({
    required String groupName,
    required List<String> conversationIDList,
  }) async {
    final res = await TIMConversationManager.instance.addConversationsToGroup(
      groupName: groupName,
      conversationIDList: conversationIDList,
    );
    return ImResult.wrap(res);
  }

  ///将会话移除分组
  Future<ImResult<List<V2TimConversationOperationResult>>> deleteConversationsFromGroup({
    required String groupName,
    required List<String> conversationIDList,
  }) async {
    final res = await TIMConversationManager.instance.deleteConversationsFromGroup(
      groupName: groupName,
      conversationIDList: conversationIDList,
    );
    return ImResult.wrap(res);
  }

  /// 高级查询会话列表
  Future<ImResult<V2TimConversationResult>> getConversationListByFilter({
    required V2TimConversationFilter filter,
    required int nextSeq,
    int count = 20,
  }) async {
    final res = await TIMConversationManager.instance.getConversationListByFilter(
      filter: filter,
      nextSeq: nextSeq,
      count: count,
    );

    return ImResult.wrap(res);
  }

  /// 查询会话记录
  Future<ImResult> getConversationList(String nextSeq, int count) async {
    // final res = await TencentImSDKPlugin.v2TIMManager.getConversationManager().getConversationList(nextSeq: nextSeq, count: count);
    final res = await getConvData(nextSeq, count);
    if (res.success == false) {
      return ImResult(
        success: false,
        code: res.code,
        desc: res.desc,
      );
    }

    final convList = res.data?.conversationList ?? [];

    final userIDList = <String>[];
    final groupIDList = <String>[];

    // 提前收集所有需要批量查询的 userID 和 groupID
    for (var conv in convList) {
      logger.e('未过滤前到会话数据：${conv.toLogString()}');
      if (conv.userID != null) {
        userIDList.add(conv.userID!);
      } else if (conv.groupID != null) {
        groupIDList.add(conv.groupID!);
      }
    }
    logger.e('用户ID：$userIDList');

    Map<String, String?> userFaceUrlMap = {};
    Map<String, String?> groupFaceUrlMap = {};
    Map<String, String> isCustomAdmin = {};
    if (userIDList.isNotEmpty) {
      final userRes = await TencentImSDKPlugin.v2TIMManager.getUsersInfo(userIDList: userIDList);

      if (userRes.code == 0) {
        for (var user in userRes.data!) {
          final userId = user.userID ?? '';
          userFaceUrlMap[userId] = user.faceUrl;

          // 读取管理员标识
          final customInfo = user.customInfo;
          logger.w('自定义信息：${user.toJson()}');
          if (customInfo != null) {
            isCustomAdmin[userId] = customInfo['admin'] ?? '0';
          }
        }
      }
    }

    if (groupIDList.isNotEmpty) {
      final groupRes = await TencentImSDKPlugin.v2TIMManager.getGroupManager().getGroupsInfo(groupIDList: groupIDList);
      if (groupRes.code == 0) {
        for (var groupResult in groupRes.data!) {
          final info = groupResult.groupInfo;
          if (info != null) {
            groupFaceUrlMap[info.groupID] = info.faceUrl;
          }
        }
      }
    }

    final viewList = convList.map((conv) {
      String? faceUrl = conv.faceUrl;

      if (faceUrl == null || faceUrl.isEmpty) {
        if (conv.userID != null) {
          faceUrl = userFaceUrlMap[conv.userID!];
        } else if (conv.groupID != null) {
          faceUrl = groupFaceUrlMap[conv.groupID!];
        }
      }

      return ConversationViewModel(
        conversation: conv,
        faceUrl: faceUrl,
        isCustomAdmin: isCustomAdmin[conv.userID],
      );
    }).toList();

    // 筛选数据,过滤掉陌生人消息
    viewList.removeWhere((conv) {
      final special = conv.conversation.conversationGroupList ?? [];
      return special.contains('noFriend');
    });

    ChatController chatcontroller = Get.find<ChatController>();
    logger.e('新的分页内容：${res.data!.toLogString()}，控制器中的：${chatcontroller.nextSeq.value}');
    String newNextSeq = res.data?.nextSeq ?? '0';
    bool isEnd = res.data?.isFinished ?? true;

    if (isEnd) {
      //没数据了，关闭拉取;
      chatcontroller.isFinished.value = isEnd;
    } else {
      // 没拉完，记录游标
      chatcontroller.nextSeq.value = newNextSeq;
    }

    // 更新分页
    chatcontroller.nextSeq.value = res.data!.nextSeq!;
    if (res.data!.isFinished == false) {
      if (viewList.length < 20) {
        // 递归补偿拉取
        final nextRes = await getConversationList(
          res.data!.nextSeq!,
          count,
        );
        if (nextRes.success && nextRes.data != null) {
          viewList.addAll(nextRes.data as List<ConversationViewModel>);
        }
      }
    }

    return ImResult(
      success: res.code == 0,
      code: res.code,
      desc: res.desc,
      data: viewList,
    );
  }

  ///获取所有会话数据
  Future<ImResult<V2TimConversationResult>> getConvData(String nextSeq, int count) async {
    final res = await TencentImSDKPlugin.v2TIMManager.getConversationManager().getConversationList(nextSeq: nextSeq, count: count);
    return ImResult.wrap(res);
  }

  ///获取指定会话
  Future<ImResult> getConversation({
    required String conversationID,
  }) async {
    final res = await TIMConversationManager.instance.getConversation(conversationID: conversationID); //c2c_conversationID,group_conversationID

    return ImResult<V2TimConversation?>(
      success: res.code == 0 && res.data != null,
      code: res.code,
      desc: res.desc,
      data: res.data,
    );
  }

  /// 搜索本地消息
  Future<ImResult<V2TimMessageSearchResult>> searchLocalMessages({
    required String page,
    required String conversationID,

    /// 关键词匹配机制or=0，and=1，
    int type = 1,

    /// ['你好','周末']
    required List<String> keywordList,

    /// 默认自定义消息
    List<int> messageTypeList = const [1, 2],
  }) async {
    final searchParam = V2TimMessageSearchParam(
      type: type,
      conversationID: conversationID,
      keywordList: keywordList,
      messageTypeList: messageTypeList,
      pageSize: 100,
      // pageIndex: page,
      searchCursor: page,
    );
    final V2TimValueCallback<V2TimMessageSearchResult> res = await TIMMessageManager.instance.searchLocalMessages(searchParam: searchParam);
    return ImResult.wrap(res);
  }

  /// 获取消息
  Future<ImResult<List<V2TimMessage>>> findMessages({
    required List<String> messageIDList,
  }) async {
    final res = await TIMMessageManager.instance.findMessages(messageIDList: messageIDList);
    return ImResult.wrap(res);
  }

  /// 修改消息
  Future<ImResult<V2TimMessageChangeInfo>> modifyMessage({
    required V2TimMessage message,
  }) async {
    final res = await TIMMessageManager.instance.modifyMessage(message: message);
    return ImResult.wrap(res);
  }

  /// 获取聊天记录 如果是群聊传 groupID，单聊传 userID，二选一
  Future<ImResult<List<V2TimMessage>>> getHistoryMessageList({
    HistoryMsgGetTypeEnum getType = HistoryMsgGetTypeEnum.V2TIM_GET_LOCAL_OLDER_MSG,
    String? userID,
    String? groupID,
    int? lastMsgSeq,
    int count = 10,
    V2TimMessage? lastMsg,
    List<int>? messageTypeList,
    List<int>? messageSeqList,
    int? timeBegin,
    int? timePeriod,
  }) async {
    if ((userID == null || userID.isEmpty) && (groupID == null || groupID.isEmpty)) {
      return ImResult(
        success: false,
        code: -1,
        desc: 'userID 或 groupID 必须至少传入一个',
        data: [],
      );
    }

    final isC2C = userID != null && groupID == null;

    final manager = TencentImSDKPlugin.v2TIMManager.getMessageManager();

    V2TimValueCallback<List<V2TimMessage>> res;

    if (!isC2C && lastMsg == null && lastMsgSeq != null) {
      // 群聊
      res = await manager.getHistoryMessageList(
        getType: getType,
        userID: userID,
        groupID: groupID,
        count: count,
        lastMsgSeq: lastMsgSeq, //群聊用,包含最后一条msg
        messageTypeList: messageTypeList,
        messageSeqList: messageSeqList,
        timeBegin: timeBegin,
        timePeriod: timePeriod,
      );
    } else {
      // 单聊
      res = await manager.getHistoryMessageList(
        getType: getType,
        userID: userID,
        groupID: groupID,
        count: count,
        lastMsg: lastMsg, // 单聊用，不包含最后一条msg
        messageTypeList: messageTypeList,
        messageSeqList: messageSeqList,
        timeBegin: timeBegin,
        timePeriod: timePeriod,
      );
    }

    return ImResult<List<V2TimMessage>>(
      success: res.code == 0,
      code: res.code,
      desc: res.desc,
      data: res.data ?? [],
    );
  }

  ///
  /// 清理指定单聊会话的未读数
  ///
  Future<ImResult> clearConversationUnreadCount({
    required String conversationID,
    // 0表示全部清除
    int cleanTimestamp = 0,
    int cleanSequence = 0,
  }) async {
    final res = await TIMConversationManager.instance.cleanConversationUnreadMessageCount(
      conversationID: conversationID,
      cleanTimestamp: cleanTimestamp, // 单聊生效
      cleanSequence: cleanSequence, // 群聊生效
    );

    return ImResult.wrapNoData(res);
  }

  /// 获取自己的userId
  Future<ImResult> selfUserId() async {
    V2TimValueCallback<String> self = await TencentImSDKPlugin.v2TIMManager.getLoginUser();
    String? userId = self.data;
    return ImResult(
      success: self.code == 0,
      code: self.code,
      desc: self.desc,
      data: userId,
    );
  }

  /// 查询当前登录用户的个人信息
  Future<ImResult> selfInfo() async {
    // 获取当前登录的用户 ID
    final idRes = await selfUserId();
    // 获取用户信息
    V2TimValueCallback<List<V2TimUserFullInfo>> res = await TencentImSDKPlugin.v2TIMManager.getUsersInfo(userIDList: [idRes.data]);
    return ImResult(
      success: res.code == 0,
      code: res.code,
      desc: res.desc,
      data: res.data?.isNotEmpty == true ? res.data!.first : null,
    );
  }

  /// 查询其他人的信息
  Future<ImResult> otherInfo(id) async {
    // 获取用户信息
    V2TimValueCallback<List<V2TimUserFullInfo>> res = await TencentImSDKPlugin.v2TIMManager.getUsersInfo(userIDList: [id]);
    return ImResult(
      success: res.code == 0,
      code: res.code,
      desc: res.desc,
      data: res.data?.isNotEmpty == true ? res.data!.first : null,
    );
  }

  /// 设置个人资料
  Future<ImResult> setSelfInfo({
    required V2TimUserFullInfo userFullInfo,
  }) async {
    final res = await TencentImSDKPlugin.v2TIMManager.setSelfInfo(
      userFullInfo: userFullInfo,
    );
    return ImResult.wrapNoData(res);
  }

  /// 检查是否是好友（双向或单向）
  Future<ImResult> isMyFriend(String userID, FriendTypeEnum checkType) async {
    final res = await TIMFriendshipManager.instance.checkFriend(
      userIDList: [userID],
      checkType: checkType, //V2TIM_FRIEND_TYPE_BOTH V2TIM_FRIEND_TYPE_SINGLE
    );

    if (res.code == 0 && res.data != null && res.data!.isNotEmpty) {
      final resultType = res.data!.first.resultType;
      final isFriend = resultType == 3; //0=无， 1=单向， 2=我在对方列表，3=双向
      return ImResult(
        success: true,
        desc: res.desc,
        code: res.code,
        data: isFriend,
      );
    } else {
      return ImResult(
        success: false,
        code: res.code,
        desc: res.desc,
        data: false,
      );
    }
  }

  /// 添加好友
  Future<ImResult<V2TimFriendOperationResult>> addFriend({
    required String userID,
    String? remark,
    String? friendGroup,
    String? addWording,
    String? addSource,
    required FriendTypeEnum addType,
  }) async {
    final res = await TIMFriendshipManager.instance.addFriend(
      userID: userID,
      remark: remark,
      friendGroup: friendGroup,
      addWording: addWording,
      addSource: addSource,
      addType: addType,
    );
    return ImResult.wrap(res);
  }

  ///接受好友申请
  Future<ImResult<V2TimFriendOperationResult>> acceptFriendApplication({
    required FriendResponseTypeEnum responseType,
    required FriendApplicationTypeEnum type, // V2TIM_FRIEND_ACCEPT_AGREE，同意添加单向好友；V2TIM_FRIEND_ACCEPT_AGREE_AND_ADD，同意并添加为双向好友
    required String userID,
  }) async {
    final res = await TIMFriendshipManager.instance.acceptFriendApplication(
      responseType: responseType,
      type: type,
      userID: userID,
    );
    return ImResult.wrap(res);
  }

  /// 拉黑
  Future<ImResult<List<V2TimFriendOperationResult>>> addToBlackList({
    required List<String> userIDList,
  }) async {
    final res = await TIMFriendshipManager.instance.addToBlackList(userIDList: userIDList);
    return ImResult.wrap(res);
  }

  /// 取消拉黑
  Future<ImResult<List<V2TimFriendOperationResult>>> deleteFromBlackList({
    required List<String> userIDList,
  }) async {
    final res = await TIMFriendshipManager.instance.deleteFromBlackList(userIDList: userIDList);
    return ImResult.wrap(res);
  }

  ///获取好友列表
  Future<ImResult<List<V2TimFriendInfo>>> getFriendList() async {
    final res = await TIMFriendshipManager.instance.getFriendList();
    return ImResult.wrap(res);
  }

  /// set好友备注
  Future<ImResult> setFriendInfo({
    required String userID,
    String? friendRemark,
    Map<String, String>? friendCustomInfo,
  }) async {
    late V2TimCallback res;
    res = await TIMFriendshipManager.instance.setFriendInfo(
      userID: userID,
      friendRemark: friendRemark,
      friendCustomInfo: friendCustomInfo,
    );
    return ImResult.wrapNoData(res);
  }

  /// 获取好友信息
  Future<ImResult<List<V2TimFriendInfoResult>>> getFriendInfo({
    required List<String> userIDList,
  }) async {
    final res = await TIMFriendshipManager.instance.getFriendsInfo(userIDList: userIDList);
    return ImResult.wrap(res);
  }

  ///关注
  Future<ImResult<List<V2TimFollowOperationResult>>> followUser({
    required List<String> userIDList,
  }) async {
    final res = await TIMFriendshipManager.instance.followUser(
      userIDList: userIDList,
    );
    return ImResult.wrap(res);
  }

  ///取关
  Future<ImResult<List<V2TimFollowOperationResult>>> unfollowUser({
    required List<String> userIDList,
  }) async {
    final res = await TIMFriendshipManager.instance.unfollowUser(
      userIDList: userIDList,
    );
    return ImResult.wrap(res);
  }

  /// check关注的类型
  /// 0：不是好友也没有关注
  /// 1：你关注了对方（单向）
  /// 2：对方关注了你（单向）
  /// 3：互相关注（双向好友）
  Future<ImResult<List<V2TimFollowTypeCheckResult>>> checkFollowType({
    required List<String> userIDList,
  }) async {
    final res = await TIMFriendshipManager.instance.checkFollowType(
      userIDList: userIDList,
    );
    return ImResult.wrap(res);
  }

  ///获取指定用户的 关注/粉丝/互关 数量信息
  Future<ImResult<List<V2TimFollowInfo>>> getUserFollowInfo({
    required List<String> userIDList,
  }) async {
    final res = await TIMFriendshipManager.instance.getUserFollowInfo(userIDList: userIDList);
    return ImResult.wrap(res);
  }

  /// 获取双向关注列表（互关好友）
  /// [nextCursor] 分页游标，首次传空字符串
  Future<ImResult<V2TimUserInfoResult>> getMutualFollowersList({
    required String nextCursor,
  }) async {
    final res = await TIMFriendshipManager.instance.getMutualFollowersList(
      nextCursor: nextCursor,
    );
    return ImResult.wrap(res);
  }

  /// 获取我的粉丝列表
  /// [nextCursor] 分页游标，首次传空字符串
  Future<ImResult<V2TimUserInfoResult>> getMyFollowersList({
    required String nextCursor,
  }) async {
    final res = await TIMFriendshipManager.instance.getMyFollowersList(
      nextCursor: nextCursor,
    );
    return ImResult.wrap(res);
  }
}
