import 'dart:async';
import 'dart:convert';
import 'dart:io';

import 'package:audioplayers/audioplayers.dart';
import 'package:dio/dio.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:get/get.dart' as my_get;
import 'package:image_picker/image_picker.dart';
import 'package:o2oa_all_platform/common/extension/index.dart';
// import 'package:open_file/open_file.dart';
import 'package:url_launcher/url_launcher.dart';
import 'package:uuid/uuid.dart';

import '../../../../common/api/index.dart';
import '../../../../common/models/index.dart';
import '../../../../common/utils/index.dart';
import '../../../../common/values/index.dart';
import '../../../../common/widgets/index.dart';
import '../../../common/preview_image/index.dart';
import '../../../common/process_webview/index.dart';
import '../../../common/video_player/index.dart';
import '../../contact/person/index.dart';
import '../group_members/index.dart';
import 'index.dart';

class ImChatController extends my_get.GetxController {
  ImChatController();

  final state = ImChatState();
  final channel = O2FlutterMethodChannelUtils();
  IMConversationInfo? conversationInfo;
  String? _conversationId;
  int page = 1; //当前页面
  int totalPage = 1; //总页数
  var _isLoading = false; //
  Map<String, String> headers = {};
  IMConfigData? _configData;

  // 聊天输入框的控制器
  final TextEditingController chatInputController = TextEditingController();
  final ScrollController chatInputScrollController = ScrollController();
  final FocusNode chatInputNode = FocusNode();
  // 修改群名输入框控制器
  final TextEditingController updateGroupTitleInputController =
      TextEditingController();
  // 聊天列表滚动控制器
  final ScrollController msgListScrollController = ScrollController();
  // 语音播放器
  // FlutterSoundPlayer? playerModule;
  AudioPlayer? _audioPlayer;
  PlayerState _playerState = PlayerState.stopped;
  StreamSubscription? _playerCompleteSubscription;
  // StreamSubscription? _playerStateChangeSubscription;

  final Uuid _uuid = const Uuid();
  // 拍照 图片选择
  final ImagePicker _imagePicker = ImagePicker();

  // 消息
  final eventBus = EventBus();
  final eventId = 'IMChat';

  /// 在 widget 内存中分配后立即调用。
  @override
  void onInit() {
    _initSoundPlayer();

    super.onInit();
  }

  ///
  /// 初始化播放器
  ///
  _initSoundPlayer() async {
    _audioPlayer = AudioPlayer();
    _playerCompleteSubscription =
        _audioPlayer?.onPlayerComplete.listen((event) {
      _audioPlayer?.stop();
      _playerState = PlayerState.completed;
      _stopPlayingUI();
    });
  }

  /// 在 onInit() 之后调用 1 帧。这是进入的理想场所
  @override
  void onReady() {
    // 各个监听
    _initListener();
    _loadEmojiTextList();
    // 初始化数据
    headers[O2ApiManager.instance.tokenName] =
        O2ApiManager.instance.o2User?.token ?? '';
    var map = my_get.Get.arguments;
    if (map != null) {
      state.title = map["title"] ?? "";
      OLogger.d("聊天标题 title: ${state.title} ");
      String id = map["conversationId"] ?? "";
      OLogger.d("会话id: $id ");
      if (id.isNotEmpty) {
        _conversationId = id;
        loadConversationInfo();
        loadChatMessageList();
        readConversation();
      } else {
        Loading.showError('args_error'.tr);
      }
    } else {
      Loading.showError('args_error'.tr);
    }
    super.onReady();
  }

  /// 在 [onDelete] 方法之前调用。
  @override
  void onClose() {
    eventBus.off(EventBus.websocketCreateImMsg, eventId);
    eventBus.off(EventBus.websocketRevokeImMsg, eventId);
    eventBus.off(EventBus.websocketImConversationUpdateMsg, eventId);
    eventBus.off(EventBus.websocketImConversationDeleteMsg, eventId);
    _disposeSoundPlayer();
    super.onClose();
  }

  _initListener() {
    //监听websocket聊天消息
    eventBus.on(EventBus.websocketCreateImMsg, eventId, (arg) {
      OLogger.d("收到websocket im 新消息！");
      if (arg is IMMessage) {
        IMMessage message = arg;
        if (message.conversationId != null &&
            message.conversationId == _conversationId) {
          OLogger.d("当前会话的消息，新增一条");
          _addMessageToUI(message);
          // 滚动底部
          _delayScorllToBottom();
        }
      }
    });
    // 监听撤回消息
    eventBus.on(EventBus.websocketRevokeImMsg, eventId, (arg) {
      OLogger.d("收到websocket im 撤回消息！");
      if (arg is IMMessage) {
        IMMessage message = arg;
        if (message.conversationId != null &&
            message.conversationId == _conversationId) {
          state.msgList.remove(message);
        }
      }
    });
    // 更新会话
    eventBus.on(EventBus.websocketImConversationUpdateMsg, eventId, (arg) {
      if (arg is IMConversationInfo && arg.id == _conversationId) {
        final personList = arg.personList ?? [];
        if (!personList
            .contains(O2ApiManager.instance.o2User?.distinguishedName)) {
          my_get.Get.back();
          Loading.showError('im_chat_error_conversation_delete'.tr);
        } else {
          loadConversationInfo();
        }
      }
    });
    // 删除会话
    eventBus.on(EventBus.websocketImConversationDeleteMsg, eventId, (arg) {
      if (arg is IMConversationInfo && arg.id == _conversationId) {
        my_get.Get.back();
        Loading.showError('im_chat_error_conversation_delete'.tr);
      }
    });
    msgListScrollController.addListener(scrollListener);
    // 监听输入法变化
    chatInputNode.addListener(() {
      if (chatInputNode.hasFocus) {
        state.toolBoxType = 0; // 关闭其他工具栏
        // 这里输入法出现的动画时间比较长，延迟滚动。。。。。
        Future.delayed(const Duration(milliseconds: 500), () {
          msgListScrollController.animateTo(0.0,
              duration: const Duration(milliseconds: 200),
              curve: Curves.easeInOut);
        });
      }
    });
  }

  ///
  /// 销毁播放器
  ///
  _disposeSoundPlayer() async {
    _audioPlayer?.stop();
    _audioPlayer = null;
    _playerCompleteSubscription?.cancel();
    _playerCompleteSubscription = null;
  }

  /// dispose 释放内存
  @override
  void dispose() {
    super.dispose();
  }

  void scrollListener() {
    if (msgListScrollController.position.pixels >=
        msgListScrollController.position.maxScrollExtent) {
      if (_isLoading) return;
      if (!state.hasMore) return;
      _isLoading = true;
      loadNextPageChatMessageList();
    }
  }

  /// 加载表情包
  Future<void> _loadEmojiTextList() async {
    state.emojiTextList.clear();
    EmojiJsonData? emojiJsonData = await O2Emoji.instance.getEmojiJsonData();
    if (emojiJsonData != null) {
      switch (state.emojiType.value) {
        case EmojiType.smileOrPerson:
          state.emojiTextList.addAll(emojiJsonData.smileOrPerson ?? []);
          break;
        case EmojiType.animals:
          state.emojiTextList.addAll(emojiJsonData.animals ?? []);
          break;
        case EmojiType.food:
          state.emojiTextList.addAll(emojiJsonData.food ?? []);
          break;
        case EmojiType.activities:
          state.emojiTextList.addAll(emojiJsonData.activities ?? []);
          break;
        case EmojiType.travel:
          state.emojiTextList.addAll(emojiJsonData.travel ?? []);
          break;
        case EmojiType.symbol:
          state.emojiTextList.addAll(emojiJsonData.symbol ?? []);
          break;
        case EmojiType.objects:
          state.emojiTextList.addAll(emojiJsonData.objects ?? []);
          break;
      }
    }
  }

  ///  消息列表 第一页 需要滚动到底部
  Future<void> loadChatMessageList() async {
    if (_conversationId == null) {
      OLogger.e('没有会话ID！！！！！！');
      _isLoading = false;
      return;
    }
    page = 1;
    var msgPage = await MessageCommunicationService.to
        .conversationMessageByPage(_conversationId!, page);
    if (msgPage != null) {
      totalPage = msgPage.totalPage;
      state.hasMore = totalPage > page;
      state.msgList.clear();
      state.msgList.addAll(msgPage.list);
      _delayScorllToBottom();
    }
    _isLoading = false;
    // 滚动到底部
  }

  /// 加载更多数据 给下拉刷新用
  /// 下拉不是刷新 是加载更多 这里跟普通的列表不一样
  /// 获取下一页历史消息 不滚动
  Future<void> loadNextPageChatMessageList() async {
    if (_conversationId == null) {
      OLogger.e('没有会话ID！！！！！！');
      _isLoading = false;
      return;
    }
    if (totalPage < page + 1) {
      OLogger.e('没有更多数据了， totalPage: $totalPage');
      _isLoading = false;
      return;
    }
    page = page + 1;
    OLogger.d("加载更多聊天消息！ page:$page");
    var msgPage = await MessageCommunicationService.to
        .conversationMessageByPage(_conversationId!, page);
    if (msgPage != null) {
      totalPage = msgPage.totalPage;
      state.hasMore = totalPage > page;
      state.msgList.addAll(msgPage.list);
    }
    _isLoading = false;
  }

  /// 获取配置文件
  Future<void> loadImConfig() async {
    _configData = await MessageCommunicationService.to.getImConfig();
    if (_configData?.enableClearMsg == true &&
        ((conversationInfo?.type == O2.imConversationTypeGroup &&
                conversationInfo?.adminPerson ==
                    O2ApiManager.instance.o2User?.distinguishedName) ||
            (conversationInfo?.type == O2.imConversationTypeSingle))) {
      if (!state.menuList
          .any((menu) => menu.type == IMChatMenuType.deleteConv)) {
        state.menuList.add(IMChatMenu(
            'im_chat_action_menu_delete_conversation'.tr,
            IMChatMenuType.deleteConv));
      }
    }
  }

  ///
  IMConfigData getImConfig() {
    return _configData == null
        ? IMConfigData(enableClearMsg: false, enableRevokeMsg: false)
        : _configData!;
  }

  ///
  /// 获取会话对象
  ///
  Future<void> loadConversationInfo() async {
    if (_conversationId == null) {
      OLogger.e('没有会话ID！！！！！！');
      return;
    }
    var conversation =
        await MessageCommunicationService.to.getConversation(_conversationId!);
    if (conversation != null) {
      conversationInfo = conversation;
      // 设置标题 工具栏等
      _updateTitle();
      // 顶部菜单
      if (conversationInfo?.type == O2.imConversationTypeGroup) {
        // 防止重复添加菜单按钮
        if (!state.menuList.any((menu) =>
            menu.type == IMChatMenuType.updateTitle ||
            menu.type == IMChatMenuType.updateMembers ||
            menu.type == IMChatMenuType.showGroupInfo)) {
          state.menuList.add(IMChatMenu(
              'im_chat_action_menu_show_group_info'.tr,
              IMChatMenuType.showGroupInfo));
          if (conversationInfo?.adminPerson ==
              O2ApiManager.instance.o2User?.distinguishedName) {
            state.menuList.add(IMChatMenu(
                'im_chat_action_menu_update_group_title'.tr,
                IMChatMenuType.updateTitle));
            state.menuList.add(IMChatMenu(
                'im_chat_action_menu_update_group_members'.tr,
                IMChatMenuType.updateMembers));
          }
        }
      }
      loadImConfig();
    }
  }

  ///
  /// 消息 已读
  ///
  Future<void> readConversation() async {
    if (_conversationId == null) {
      OLogger.e('没有会话ID！！！！！！');
      return;
    }
    final result =
        await MessageCommunicationService.to.readConversation(_conversationId!);
    OLogger.d("阅读会话： ${result?.toJson()}");
  }

  ///
  /// 更新群名称
  ///
  Future<void> updateGroupTitle(String title) async {
    if (_conversationId == null) {
      OLogger.e('没有会话ID！！！！！！');
      return;
    }
    if (conversationInfo != null &&
        conversationInfo?.type == O2.imConversationTypeGroup) {
      var form = IMConversationInfo();
      form.id = _conversationId;
      form.title = title;
      final result =
          await MessageCommunicationService.to.updateConversation(form);
      OLogger.d("更新会话title： $result");
      if (result != null) {
        conversationInfo?.title = title;
        _updateTitle();
        Loading.toast('im_chat_success_update_group_title'.tr);
      }
    }
  }

  ///
  /// 清除聊天记录
  ///
  Future<void> _clearAllMessage() async {
    if (_conversationId == null) {
      OLogger.e('没有会话ID！！！！！！');
      return;
    }
    var result =
        await MessageCommunicationService.to.deleteAllChatMsg(_conversationId!);
    if (result != null) {
      Loading.toast('im_chat_success_clear_all_messages'.tr);
      loadChatMessageList(); // 重新刷新数据
    }
  }

  void _updateTitle() {
    //标题处理
    var title = '';
    if (conversationInfo != null) {
      // 单聊
      if (conversationInfo?.type == O2.imConversationTypeSingle) {
        var otherParty = conversationInfo?.personList?.firstWhereOrNull(
            (element) =>
                element != O2ApiManager.instance.o2User?.distinguishedName);
        if (otherParty != null && otherParty.isNotEmpty) {
          if (otherParty.contains("@")) {
            title = otherParty.substring(0, otherParty.indexOf("@"));
          } else {
            title = otherParty;
          }
        }
      } else {
        title = conversationInfo?.title ?? '';
      }
    }
    state.title = title;
  }

  /// 针对UI动画
  void _delayScorllToBottom() {
    // 滚动底部 这里需要等待刷新页面后才能滚动
    Future.delayed(const Duration(milliseconds: 200), () {
      msgListScrollController.animateTo(0.0,
          duration: const Duration(milliseconds: 200), curve: Curves.easeInOut);
    });
  }

  ///
  /// 应用图标下载
  Future<void> getProcessAppIcon(String? appId) async {
    if (appId == null || appId.isEmpty) {
      return;
    }
    if (state.processAppIconMap[appId] == null) {
      var icon = await ProcessSurfaceService.to.applicationIcon(appId);
      if (icon != null) {
        state.processAppIconMap[appId] = icon;
      }
    }
  }

  /// 关闭输入法
  void closeSoftInputAndOtherTools() {
    chatInputNode.unfocus(); // 关闭输入法
    state.toolBoxType = 0;
  }

  void clickVoiceBtn() {
    chatInputNode.unfocus(); // 关闭输入法
    if (state.toolBoxType == 1) {
      state.toolBoxType = 0;
    } else {
      state.toolBoxType = 1;
      _delayScorllToBottom();
    }
  }

  void clickShowKeyboardBtn() {
    state.toolBoxType = 0;
    chatInputNode.requestFocus();
  }

  void clickEmojiBtn() {
    chatInputNode.unfocus(); // 关闭输入法
    if (state.toolBoxType == 2) {
      state.toolBoxType = 0;
    } else {
      state.toolBoxType = 2;
      _delayScorllToBottom();
    }
  }

  void clickEmojiTypeBtn(EmojiType type) {
    state.emojiType.value = type;
    _loadEmojiTextList();
  }

  void clickMoreBtn() {
    chatInputNode.unfocus(); // 关闭输入法
    if (state.toolBoxType == 3) {
      state.toolBoxType = 0;
    } else {
      state.toolBoxType = 3;
      _delayScorllToBottom();
    }
  }

  void clickChoosePhotosBtn() {
    _pickImageByType(0);
  }

  void clickTakePhotoBtn() {
    _pickImageByType(1);
  }

  void clickChooseFileBtn() {
    _chooseFile();
  }

  void clickChooseLocationBtn() async {
    OLogger.d("选择位置");
    // LocationData locationData =
    //     LocationData(LocationData.locationDataModePicker);
    // var location = await BaiduMapPage.open(locationData);
    // if (location != null && location is LocationData) {
    //   OLogger.d(
    //       '选择了。。。。${location.latitude} ${location.longitude} ${location.address} ');
    //   var msg = _createMsg(_locationMsgBody(location));
    //   if (msg != null) {
    //     _addMessageToUI(msg);
    //     _sendMessageToServer(msg);
    //   }
    // }
  }

  /// 点击头像
  void clickAvatarToPerson(String person) {
    PersonPage.open(person);
  }

  ///
  /// 点击右上角菜单
  ///
  void clickActionMenu(IMChatMenu menu) {
    OLogger.d('点击了菜单，${menu.name}');
    // 先关闭右上角菜单，再继续执行 防止pop冲突
    Future.delayed(const Duration(seconds: 0), () {
      switch (menu.type) {
        case IMChatMenuType.report:
          _openReportDialog();
          break;
        case IMChatMenuType.showGroupInfo:
          _showGroupInfo();
          break;
        case IMChatMenuType.updateTitle:
          _openUpdateTitleDialog();
          break;
        case IMChatMenuType.updateMembers:
          openGroupMembers();
          break;
        case IMChatMenuType.clearAllMessage:
          _confirmClearAllMessages();
          break;
        case IMChatMenuType.deleteConv:
          _deleteConversation();
          break;
      }
    });
  }

  /// 删除会话
  void _deleteConversation() {
    var context = my_get.Get.context;
    if (context == null) {
      return;
    }
    if (conversationInfo != null) {
      if (conversationInfo?.type == O2.imConversationTypeSingle) {
        // 单聊
        O2UI.showConfirm(
            context, 'im_chat_confirm_delete_single_conversation'.tr,
            okPressed: () => _deleteSingleConv());
      } else {
        // 群聊
        O2UI.showConfirm(
            context, 'im_chat_confirm_delete_group_conversation'.tr,
            okPressed: () => _deleteGroupConv());
      }
    }
  }

  void _deleteSingleConv() async {
    final result = await MessageCommunicationService.to
        .deleteSingleConversation(_conversationId!);
    if (result != null) {
      my_get.Get.back();
    }
  }

  void _deleteGroupConv() async {
    final result = await MessageCommunicationService.to
        .deleteGroupConversation(_conversationId!);
    if (result != null) {
      my_get.Get.back();
    }
  }

  /// 清除聊天记录
  void _confirmClearAllMessages() {
    O2UI.showConfirm(my_get.Get.context, 'im_chat_confirm_clear_all_message'.tr,
        okPressed: () => _clearAllMessage());
  }

  /// 显示群信息
  void _showGroupInfo() {
    if (conversationInfo != null) {
      GroupMembersPage.showGroupInfo(conversationInfo!);
    }
  }

  /// 更新群成员
  void openGroupMembers() async {
    if (conversationInfo != null) {
      await GroupMembersPage.updateMember(conversationInfo!);
      loadConversationInfo();
    }
  }

  /// 更新群名
  void _openUpdateTitleDialog() async {
    var context = my_get.Get.context;
    if (context == null) {
      return;
    }
    updateGroupTitleInputController.text = conversationInfo?.title ?? '';
    var result = await O2UI.showCustomDialog(
        my_get.Get.context,
        'im_chat_action_menu_update_group_title'.tr,
        TextField(
          controller: updateGroupTitleInputController,
          maxLines: 1,
          style: Theme.of(context).textTheme.bodyMedium,
          keyboardType: TextInputType.text,
          textInputAction: TextInputAction.next,
          decoration: InputDecoration(
            labelText: 'im_chat_action_menu_update_group_title_hint'.tr,
          ),
        ));
    OLogger.d('修改群名dialog，返回结果$result');
    if (result != null && result == O2DialogAction.positive) {
      var title = updateGroupTitleInputController.text;
      if (title.isEmpty) {
        Loading.toast('im_chat_error_update_group_title_not_empty'.tr);
      } else {
        updateGroupTitle(title);
      }
    }
  }

  /// 举报
  void _openReportDialog() async {
    var result = await O2UI.showCustomDialog(my_get.Get.context,
        'im_chat_action_menu_report'.tr, _reportFormWidget());
    OLogger.i('举报成功，返回结果$result');
  }

  Widget _reportFormWidget() {
    var context = my_get.Get.context;
    if (context == null) {
      return Container();
    }
    return Column(
      children: [
        TextField(
          maxLines: 1,
          style: Theme.of(context).textTheme.bodyMedium,
          keyboardType: TextInputType.text,
          textInputAction: TextInputAction.next,
          decoration: InputDecoration(
            labelText: 'im_chat_action_menu_report_form_reason'.tr,
          ),
        ),
        const SizedBox(
          height: 16,
        ),
        TextField(
          keyboardType: TextInputType.multiline,
          maxLines: 4,
          style: Theme.of(context).textTheme.bodyMedium,
          textInputAction: TextInputAction.done,
          decoration: InputDecoration(
            labelText: 'im_chat_action_menu_report_form_desc'.tr,
          ),
        ),
      ],
    );
  }

  ///
  /// 撤回消息
  ///
  void revokeMsg(IMMessage info) async {
    var back = await MessageCommunicationService.to.revokeMessage(info.id!);
    if (back != null) {
      state.msgList.remove(info);
      Loading.toast('im_chat_success_revoke'.tr);
    } else {
      Loading.showError('im_chat_error_revoke'.tr);
    }
  }

  ///
  /// 复制消息
  ///
  void copyTextMsg(IMMessage info) {
    if (info.toBody()?.type == IMMessageType.text.name) {
      Clipboard.setData(ClipboardData(text: info.toBody()?.body ?? ''));
      Loading.toast('im_chat_success_copy'.tr);
    }
  }

  ///
  /// 点击消息
  ///
  void clickMsgItem(IMMessage info) {
    var body = info.toBody();
    if (body != null) {
      if ((body.type == IMMessageType.audio.name ||
          body.type == IMMessageType.image.name ||
          body.type == IMMessageType.file.name)) {
        _openVoiceImageOrFileMsg(info);
      } else if (body.type == IMMessageType.process.name) {
        if (body.work != null && body.work?.isNotEmpty == true) {
          if (my_get.GetPlatform.isDesktop) {
            var url = O2ApiManager.instance.getWorkUrlInPC(body.work!);
            if (url == null) {
              return;
            }
            url +=
                '&${O2ApiManager.instance.tokenName}=${O2ApiManager.instance.o2User?.token ?? ''}';
            _launchInWebViewOrVC(url);
          } else {
            ProcessWebviewPage.open(body.work!,
                title: body.title ?? '${body.processName}-无标题');
          }
        }
      } else if (body.type == IMMessageType.location.name) {
        MapUtils.showMapListMenu('${body.longitude}', '${body.latitude}');
        // if (my_get.GetPlatform.isDesktop) {

        // } else {
        //   LocationData locationData = LocationData(
        //       LocationData.locationDataModeShow,
        //       latitude: body.latitude,
        //       longitude: body.longitude,
        //       address: body.address,
        //       addressDetail: body.addressDetail);
        //   // BaiduMapPage.open(locationData);
        // }
      }
    }
  }

  ///
  /// 播放语音消息 打开图片或文件消息
  Future<void> _openVoiceImageOrFileMsg(IMMessage info) async {
    var body = info.toBody();
    if (body != null) {
      var fileTempPath = body.fileTempPath;
      if (fileTempPath != null && fileTempPath.isNotEmpty) {
        if (body.type == IMMessageType.audio.name) {
          _playVoice(fileTempPath, info);
        } else if (body.type == IMMessageType.file.name ||
            body.type == IMMessageType.image.name) {
          _openFileOrgImage(fileTempPath, body.fileName ?? "Unknown");
        }
      } else if (body.fileId != null) {
        // 下载
        // 本地存储路径
        var filePath = await O2FilePathUtil.getImFileDownloadLocalPath(
            body.fileId!, body.fileName ?? "Unknown");
        OLogger.d("下载聊天文件： $filePath");
        if (filePath != null) {
          var file = File(filePath);
          if (!file.existsSync()) {
            Loading.show();
            var downloadUrl = MessageCommunicationService.to
                .getIMMsgDownloadFileUrl(body.fileId!);
            Response response =
                await O2HttpClient.instance.downloadFile(downloadUrl, filePath);
            if (response.statusCode != 200) {
              Loading.showError('im_chat_error_preview_file_fail'.tr);
              if (file.existsSync()) {
                // 下载失败 删除文件
                file.delete();
              }
              return;
            }
            Loading.dismiss();
          }
          if (body.type == IMMessageType.audio.name) {
            _playVoice(filePath, info);
          } else if (body.type == IMMessageType.file.name ||
              body.type == IMMessageType.image.name) {
            _openFileOrgImage(filePath, body.fileName ?? "Unknown");
          }
        } else {
          Loading.showError('im_chat_error_preview_file_fail'.tr);
        }
      }
    }
  }

  ///
  /// 播放音频
  ///
  void _playVoice(String filePath, IMMessage info) async {
    var exist = await File(filePath).exists();
    if (exist) {
      if (!(_playerState == PlayerState.stopped ||
          _playerState == PlayerState.completed)) {
        _audioPlayer?.stop();
      }
      _startPlayingUI(info);
      _audioPlayer?.play(DeviceFileSource(filePath));
      // if (playerModule?.isPlaying == true) {
      //   playerModule?.stopPlayer();
      // }
      // await playerModule?.startPlayer(
      //     fromURI: filePath,
      //     codec: Codec.aacADTS,
      //     whenFinished: () {
      //       _stopPlayingUI();
      //     });
    }
  }

  /// 开启播放动画
  void _startPlayingUI(IMMessage info) {
    state.playingVoiceId = info.id!;
  }

  /// 关闭播放动画
  void _stopPlayingUI() {
    state.playingVoiceId = "";
  }

  ///
  /// 打开图片或文件
  ///
  Future<void> _openFileOrgImage(String filePath, String fileName) async {
    OLogger.d('预览文件： $fileName $filePath');
    if (filePath.isImageFileName) {
      PreviewImagePage.open(filePath, fileName);
    } else if (filePath.isVideoFileName && !my_get.GetPlatform.isDesktop) {
      VideoPlayerPage.openLocalVideo(filePath, title: fileName);
    } else {
      if (my_get.GetPlatform.isDesktop) {
        // 使用本地软件打开文件
        final Uri uri = Uri.file(filePath);
        if (!await launchUrl(uri)) {
          // 无法打开？
          Loading.toast('im_msg_download_success'.tr);
        }
      } else {
        channel.openLocalFile(filePath);
      }
    }
  }

  /// 内部打开链接
  Future<void> _launchInWebViewOrVC(String url) async {
    Uri? uri = Uri.tryParse(url);
    if (uri == null) {
      OLogger.e(' 错误的 url $url ');
      return;
    }
    if (!await launchUrl(
      uri,
      webViewConfiguration: WebViewConfiguration(headers: <String, String>{
        O2ApiManager.instance.tokenName:
            O2ApiManager.instance.o2User?.token ?? ''
      }),
    )) {
      OLogger.e('Could not launch $url');
    }
  }

  /// 外部打开链接
  Future<void> _launchExternal(String url) async {
    Uri? uri = Uri.tryParse(url);
    if (uri != null && await canLaunchUrl(uri)) {
      final result = await launchUrl(
        uri,
        mode: LaunchMode.externalApplication,
        webViewConfiguration: WebViewConfiguration(headers: <String, String>{
          O2ApiManager.instance.tokenName:
              O2ApiManager.instance.o2User?.token ?? ''
        }),
      );
      if (!result) {
        OLogger.e('打开 url $url 失败！');
      }
    } else {
      OLogger.e(' 错误的 url $url ');
    }
  }

  /// 输入框输入发送消息
  void onSendText() {
    final text = chatInputController.text;
    OLogger.d("输入了 $text");
    if (text.isNotEmpty) {
      var msg = _createMsg(_textMsgBody(text));
      if (msg != null) {
        _addMessageToUI(msg);
        _sendMessageToServer(msg);
      }
    }
    // 清空输入框
    chatInputController.text = "";
  }

  /// 发送表情
  void onSendEmoji(String emojiKey) {
    OLogger.d("发送表情 $emojiKey");
    if (emojiKey.isNotEmpty) {
      var msg = _createMsg(_emojiMsgBody(emojiKey));
      if (msg != null) {
        _addMessageToUI(msg);
        _sendMessageToServer(msg);
      }
    }
  }

  void onSendEmojiText(String emoji) {
    OLogger.d("添加表情 $emoji");
    final text = chatInputController.text;
    chatInputController.text = text + emoji;
    chatInputController.selection = TextSelection.fromPosition(
        TextPosition(offset: chatInputController.text.length));
    if (chatInputScrollController.hasClients) {
      chatInputScrollController.animateTo(
          chatInputScrollController.position.maxScrollExtent,
          duration: const Duration(milliseconds: 50),
          curve: Curves.easeOut);
    }
  }

  /// 选择图片 或者 拍照
  Future<void> _pickImageByType(int type) async {
    XFile? file;
    if (type == 0) {
      // 相册
      file = await _imagePicker.pickImage(source: ImageSource.gallery);
    } else if (type == 1) {
      // 拍照
      if (!await O2Utils.cameraPermission()) {
        return;
      }
      file = await _imagePicker.pickImage(source: ImageSource.camera);
    }
    if (file != null) {
      _uploadFileAndSendMsg(file.path);
    }
  }

  ///
  /// 选择文件
  ///
  Future<void> _chooseFile() async {
    O2Utils.pickerFileOrImage((paths) {
      if (paths.isEmpty) {
        return;
      }
      String path = paths[0] ?? '';
      if (path.isEmpty) {
        return;
      }
      OLogger.d('选择了文件：$path');
      _uploadFileAndSendMsg(path);
    });
  }

  ///
  /// 声音文件上传 发送消息
  ///
  Future<void> uploadAndSendVoiceMsg(String voiceFilePath, int duration) async {
    IMMessageBody body = _voiceMsgBody(voiceFilePath, duration);
    var imMessage = _createMsg(body);
    if (imMessage != null) {
      OLogger.d("声音消息body1: ${imMessage.body}");
      _addMessageToUI(imMessage);
      File file = File(voiceFilePath);
      var fileRes = await MessageCommunicationService.to
          .uploadFileToIM(_conversationId!, body.type!, file);
      if (fileRes == null) {
        Loading.showError('im_chat_error_upload_fail'.tr);
        return;
      }
      body.fileId = fileRes.id;
      body.fileExtension = fileRes.fileExtension;
      body.fileName = fileRes.fileName;
      body.fileTempPath = null;
      imMessage.body = json.encode(body.toJson());
      OLogger.d("声音消息body2: ${imMessage.body}");
      _sendMessageToServer(imMessage);
    }
  }

  ///
  /// 上传文件 发送消息
  ///
  Future<void> _uploadFileAndSendMsg(String filePath) async {
    if (_conversationId == null) {
      OLogger.e("错误：没有会话ID 。。。。。。");
      return;
    }
    var fileExtension = filePath.fileNameExtension();
    if (fileExtension.isEmpty) {
      Loading.showError('im_chat_error_unknown_file'.tr);
      return;
    }
    OLogger.d("文件扩展名： $fileExtension");
    IMMessageBody body;
    switch (fileExtension) {
      case "jpg":
      case "jpeg":
      case "gif":
      case "png":
      case "bmp":
        body = _imageMsgBody(filePath);
        break;
      default:
        body = _fileMsgBody(filePath);
        break;
    }
    var imMessage = _createMsg(body);
    if (imMessage != null) {
      OLogger.d("消息body1: ${imMessage.body}");
      _addMessageToUI(imMessage);
      File file = File(filePath);
      var fileRes = await MessageCommunicationService.to
          .uploadFileToIM(_conversationId!, body.type!, file);
      if (fileRes == null) {
        Loading.showError('im_chat_error_upload_fail'.tr);
        return;
      }
      body.fileId = fileRes.id;
      body.fileExtension = fileRes.fileExtension;
      body.fileName = fileRes.fileName;
      body.fileTempPath = null;
      imMessage.body = json.encode(body.toJson());
      OLogger.d("消息body2: ${imMessage.body}");
      _sendMessageToServer(imMessage);
    }
  }

  void _addMessageToUI(IMMessage msg) {
    // 这里要加到最前面
    final oldList = state.msgList;
    var newList = <IMMessage>[msg];
    for (var i = 0; i < oldList.length; i++) {
      newList.add(oldList[i]);
    }
    state.msgList.clear();
    state.msgList.addAll(newList);
    // 滚动底部
    _delayScorllToBottom();
  }

  ///
  /// 发送消息到服务器
  ///
  Future<void> _sendMessageToServer(IMMessage msg) async {
    var id = await MessageCommunicationService.to.sendMessage(msg);
    if (id != null && id.id != null && id.id!.isNotEmpty) {
      _updateMsgData(id.id!, 0); // 发送正常
    } else {
      _updateMsgData(msg.id!, 2); // 发送失败
    }
  }

  ///
  /// 更新消息状态，把发送中改成
  ///
  void _updateMsgData(String msgId, int status) {
    int i = 0;
    IMMessage? msg;
    for (var element in state.msgList) {
      if (element.id == msgId) {
        msg = element;
        break;
      }
      i++;
    }
    if (msg != null) {
      msg.sendStatus = status;
      state.msgList[i] = msg;
    }
  }

  ///
  /// 文字消息
  ///
  IMMessageBody _textMsgBody(String text) {
    return IMMessageBody(type: IMMessageType.text.name, body: text);
  }

  ///
  /// 表情消息
  ///
  IMMessageBody _emojiMsgBody(String emoji) {
    return IMMessageBody(type: IMMessageType.emoji.name, body: emoji);
  }

  ///
  /// 表情消息
  ///
  IMMessageBody _locationMsgBody(LocationData locationData) {
    var body = IMMessageBody(
        type: IMMessageType.location.name,
        longitude: locationData.longitude,
        latitude: locationData.latitude,
        address: locationData.address,
        addressDetail: locationData.addressDetail);
    body.conversationBodyString();
    return body;
  }

  ///
  /// 文件消息
  ///
  IMMessageBody _voiceMsgBody(String fileTempPath, int duration) {
    var body = IMMessageBody(
        type: IMMessageType.audio.name,
        fileTempPath: fileTempPath,
        audioDuration: "$duration",
        fileExtension: fileTempPath.fileNameExtension(),
        fileName: fileTempPath.fileName());
    body.body = body.conversationBodyString();
    return body;
  }

  ///
  /// 文件消息
  ///
  IMMessageBody _fileMsgBody(String fileTempPath) {
    var body = IMMessageBody(
        type: IMMessageType.file.name,
        fileTempPath: fileTempPath,
        fileExtension: fileTempPath.fileNameExtension(),
        fileName: fileTempPath.fileName());
    body.body = body.conversationBodyString();
    return body;
  }

  ///
  /// 图片消息
  ///
  IMMessageBody _imageMsgBody(String fileTempPath) {
    var body = IMMessageBody(
        type: IMMessageType.image.name,
        fileTempPath: fileTempPath,
        fileExtension: fileTempPath.fileNameExtension(),
        fileName: fileTempPath.fileName());
    body.body = body.conversationBodyString();
    return body;
  }

  ///
  /// 创建一个新消息对象
  ///
  IMMessage? _createMsg(IMMessageBody body) {
    if (_conversationId != null) {
      var jsonBody = json.encode(body.toJson());
      var now = DateTime.now().ymdhms();
      return IMMessage(
          id: _uuid.v1(),
          body: jsonBody,
          conversationId: _conversationId,
          createPerson: O2ApiManager.instance.o2User?.distinguishedName,
          createTime: now,
          sendStatus: 1);
    }
    return null;
  }
}
