import 'dart:async';

import 'package:get/get.dart';
import 'package:logger/logger.dart';
import 'package:loopin/IM/controller/chat_detail_controller.dart';
import 'package:loopin/IM/global_badge.dart';
import 'package:loopin/IM/im_message.dart';
import 'package:loopin/IM/im_service.dart';
import 'package:loopin/utils/index.dart';
import 'package:loopin/utils/lifecycle_handler.dart';
import 'package:loopin/utils/notification_banner.dart';
import 'package:shirne_dialog/shirne_dialog.dart';
import 'package:tencent_cloud_chat_sdk/enum/V2TimAdvancedMsgListener.dart';
import 'package:tencent_cloud_chat_sdk/enum/message_elem_type.dart';
import 'package:tencent_cloud_chat_sdk/enum/receive_message_opt.dart';
import 'package:tencent_cloud_chat_sdk/models/v2_tim_conversation.dart';
import 'package:tencent_cloud_chat_sdk/models/v2_tim_group_info.dart';
import 'package:tencent_cloud_chat_sdk/models/v2_tim_message.dart';
import 'package:tencent_cloud_chat_sdk/models/v2_tim_message_receipt.dart';
import 'package:tencent_cloud_chat_sdk/tencent_im_sdk_plugin.dart';

class ImMessageListenerService extends GetxService {
  ProgressController? _sendProgressController; // 消息发送提示

  final logger = Logger();
  V2TimAdvancedMsgListener? _listener;
  Timer? _debounceTimer;

  /// 插入标签时间间隔
  bool needInsertTimeLabel(int lastTimestamp, int newTimestamp, {int interval = 3 * 60}) {
    return (newTimestamp - lastTimestamp) > interval * 1000;
  }

  ///插入标签
  void insertTimeLabel(message) async {
    // 待插入的消息
    List<V2TimMessage> messagesToInsert = [];
    V2TimMessage? lastRealMsg;
    final chatDetailController = Get.find<ChatDetailController>();
    for (var msg in chatDetailController.chatList) {
      if (msg.localCustomData != 'time_label') {
        lastRealMsg = msg;
        break;
      }
    }

    final idRes = await ImService.instance.selfUserId();
    final selfUserId = idRes.data;
    // 如果有数据，检测时间，是否需要插入伪消息
    if (lastRealMsg != null &&
        needInsertTimeLabel(
          (lastRealMsg.timestamp ?? 0) * 1000, // 转为毫秒级
          DateTime.now().millisecondsSinceEpoch,
        )) {
      // 消息时间间隔超过3分钟插入伪消息
      final showLabel = Utils.formatChatTime(DateTime.now().millisecondsSinceEpoch ~/ 1000);
      final resMsg = await IMMessage().insertTimeLabel(showLabel, selfUserId);
      messagesToInsert.add(resMsg.data);
    } else {
      // 没数据的时候直接插入伪消息
      final showLabel = Utils.formatChatTime(DateTime.now().millisecondsSinceEpoch ~/ 1000);
      final resMsg = await IMMessage().insertTimeLabel(showLabel, selfUserId);
      messagesToInsert.add(resMsg.data);
    }
    messagesToInsert.insert(0, message);
    // messagesToInsert.add(message);

    // 新进入的消息插入列表
    chatDetailController.chatList.insertAll(0, messagesToInsert);
    // chatDetailController.chatList.addAll(messagesToInsert);
    // 滚动
    chatDetailController.scrollToBottom();
  }

  /// 处理消息
  void _handleNewMessage(V2TimMessage message) async {
    final id = Utils.handleText(message.groupID, message.sender, ''); // 优先取groupID,因为senderID是必然存在的;
    if (id.isEmpty) return;
    final isGroup = message.groupID != null && message.groupID!.isNotEmpty;
    final conversationID = isGroup ? 'group_${message.groupID}' : 'c2c_${message.userID}';
    if (id.isEmpty) return;

    /// 是否正在聊天 优先处理
    if (Get.isRegistered<ChatDetailController>()) {
      final chatDetailController = Get.find<ChatDetailController>();
      // 单聊和群聊的处理(chatDetailController.id是通过chat_binding传入的，按顺序取userID,没有则取groupID)
      if (chatDetailController.id == id) {
        // 确认正在聊天，插入消息前检测是否需要打时间标签
        insertTimeLabel(message);
        // 标注为已读
        await ImService.instance.clearConversationUnreadCount(conversationID: conversationID);
      }
      return;
    }
    //如果是tips类型的
    if (message.elemType == MessageElemType.V2TIM_ELEM_TYPE_GROUP_TIPS) {
      // 如果是群tips 不展示消息提示
      await ImService.instance.clearConversationUnreadCount(conversationID: conversationID);
      return;
    }

    // 未杀死状态，交给在线推送处理
    if (!LifecycleHandler.isInForeground) {
      logger.i("App 当前在后台，收到来自 $id 的消息 ${message.msgID}，暂不展示弹窗");
      // return;
    }
    //TODO 过滤有管理员标识的信息
    //TODO 等消息发送写完以后处理消息免打扰过滤，实现：发送消息时依赖cloudCustomData，根据conversation设置的opty属性是否开启了过滤，给customdata赋值
    //TODO 群消息

    ///--------免打扰相关
    // 单聊消息接收选项c2CReceiveMessageOpt，先不管单聊
    // 如果是群，先拿群的信息recvOpt
    if (isGroup) {
      //
      final res = await ImService.instance.getGroupsInfo(groupIDList: [message.groupID!]);
      if (res.success && res.data != null) {
        final V2TimGroupInfo groupData = res.data!.first.groupInfo!;
        if (groupData.recvOpt == ReceiveMsgOptType.kTIMRecvMsgOpt_Not_Notify_Except_At) {
          // 开启了免打扰模式， 现在只做了0=初始正常接受，3=在线接受，离线只接受@消息
          return;
        }
      } else {
        // 获取失败默认也不提示;
        return;
      }
    } else {
      // 单聊的
      final cRes = await ImService.instance.getConversation(conversationID: 'c2c_${message.userID}');
      final V2TimConversation c2cConv = cRes.data;
      if (c2cConv.recvOpt == ReceiveMsgOptType.kTIMRecvMsgOpt_Not_Notify) {
        // 开启了免打扰模式， 现在只做了0=初始正常接受，3=在线接受，离线只接受@消息
        return;
      }
    }

    _debounceTimer?.cancel(); // 每次都取消旧的
    _debounceTimer = Timer(Duration(milliseconds: 1000), () {
      NotificationBanner.show(message, isGroup);
    });
  }

  Future<ImMessageListenerService> init() async {
    _listener = V2TimAdvancedMsgListener(
      onRecvNewMessage: (V2TimMessage message) async {
        logger.i("收到新消息：${message.msgID}");
        _handleNewMessage(message);

        switch (message.elemType) {
          case MessageElemType.V2TIM_ELEM_TYPE_TEXT:
            logger.i("文本消息: ${message.textElem?.text}");
            break;
          case MessageElemType.V2TIM_ELEM_TYPE_CUSTOM:
            logger.i("自定义消息: ${message.customElem?.data}");
            break;
          case MessageElemType.V2TIM_ELEM_TYPE_IMAGE:
            logger.i("图片消息: ${message.imageElem?.imageList?.map((e) => e?.url).toList()}");
            break;
          case MessageElemType.V2TIM_ELEM_TYPE_VIDEO:
            logger.i("视频消息: ${message.videoElem?.snapshotPath}");
            break;
          case MessageElemType.V2TIM_ELEM_TYPE_SOUND:
            logger.i("语音消息: ${message.soundElem?.duration}s");
            break;
          case MessageElemType.V2TIM_ELEM_TYPE_FILE:
            logger.i("文件消息: ${message.fileElem?.fileName}");
            break;
          case MessageElemType.V2TIM_ELEM_TYPE_LOCATION:
            logger.i("位置消息: ${message.locationElem?.desc}");
            break;
          case MessageElemType.V2TIM_ELEM_TYPE_FACE:
            logger.i("表情消息: ${message.faceElem?.index}");
            break;
          case MessageElemType.V2TIM_ELEM_TYPE_GROUP_TIPS:
            logger.i("群提示消息: ${message.groupTipsElem?.groupID}");
            break;
          case MessageElemType.V2TIM_ELEM_TYPE_MERGER:
            logger.i("合并消息: ${message.mergerElem?.title}");
            final res = await TencentImSDKPlugin.v2TIMManager.getMessageManager().downloadMergerMessage(msgID: message.msgID!);
            if (res.code == 0) {
              logger.i("下载合并消息成功，包含 ${res.data?.length ?? 0} 条消息");
            } else {
              logger.w("合并消息下载失败: ${res.desc}");
            }
            break;
          default:
            logger.w("未识别消息类型: ${message.elemType}");
        }
      },
      onRecvMessageRevoked: (String msgID) {
        logger.i("消息被撤回: $msgID");
      },
      onRecvMessageModified: (V2TimMessage message) {
        logger.i("消息被修改: ${message.msgID}");
        // 目前就红包领取状态的变更
        if (Get.isRegistered<ChatDetailController>()) {
          final controller = Get.find<ChatDetailController>();
          final index = controller.chatList.indexWhere((m) => m.msgID == message.msgID);
          if (index != -1) {
            final newJson = message.customElem!.data!;
            controller.chatList[index].customElem!.data = newJson;
            controller.chatList.refresh();
          }
        }
      },
      onSendMessageProgress: (V2TimMessage message, int progress) {
        logger.i("发送中: ${message.msgID} -> $progress%");
        if (progress < 100) {
          _sendProgressController ??= MyDialog.loading(
            "发送中...",
            duration: null, // 不自动关闭
          );
        } else {
          _sendProgressController?.close();
          _sendProgressController = null;
        }
      },
      onRecvC2CReadReceipt: (List<V2TimMessageReceipt> receiptList) {
        final gtl = Get.find<GlobalBadge>();
        gtl.initUnreadCount();
        for (var receipt in receiptList) {
          logger.i("C2C已读: msgID=${receipt.msgID}, userID=${receipt.userID}");
        }
      },
      onRecvMessageReadReceipts: (List<V2TimMessageReceipt> receiptList) {
        final gtl = Get.find<GlobalBadge>();
        gtl.initUnreadCount();
        for (var receipt in receiptList) {
          logger.i("群已读: groupID=${receipt.groupID}, msgID=${receipt.msgID}, read=${receipt.readCount}, unread=${receipt.unreadCount}");
        }
      },
    );

    TencentImSDKPlugin.v2TIMManager.getMessageManager().addAdvancedMsgListener(listener: _listener!);

    logger.i("高级消息监听器已注册");
    return this;
  }

  @override
  void onClose() {
    logger.i("onClose 调用，_listener = $_listener");
    TencentImSDKPlugin.v2TIMManager.getMessageManager().removeAdvancedMsgListener(listener: _listener);
    logger.i("高级消息监听器已移除");
    super.onClose();
  }
}
