import 'dart:async';
import 'package:chat/configs/app_colors.dart';
import 'package:chat/routes/contact_routes.dart';
import 'package:chat/services/tim/conversation_service.dart';
import 'package:chat/utils/sound_record.dart';
import 'package:chat/utils/ui_tools.dart';
import 'package:chat/views/conversation/widgets/tim_emoji_panel.dart';
import 'package:file_picker/file_picker.dart';
import 'package:flutter/material.dart';
// import 'package:flutter_baidu_mapapi_search/flutter_baidu_mapapi_search.dart';
import 'package:get/get.dart';
import 'package:permission_handler/permission_handler.dart';
import 'package:tencent_im_sdk_plugin/enum/conversation_type.dart';
import 'package:tencent_im_sdk_plugin/models/v2_tim_conversation.dart';
import 'package:wechat_assets_picker/wechat_assets_picker.dart';
import 'package:wechat_camera_picker/wechat_camera_picker.dart';

class MessageField extends StatefulWidget {
  final V2TimConversation conversation;

  const MessageField(this.conversation, {Key? key}) : super(key: key);

  @override
  State<MessageField> createState() => _MessageFieldState();
}

class _MessageFieldState extends State<MessageField> {
  final TextEditingController _controller = TextEditingController();

  bool isVoice = false;
  String _sendText = '';
  double paddingBottom = 0.0;
  String soundTipsText = "手指上滑，取消发送";
  bool isRecording = false;
  bool isInit = false;
  bool isCancelSend = false;
  DateTime startTime = DateTime.now();
  List<StreamSubscription<Object>> subscriptions = [];

  OverlayEntry? overlayEntry;
  String voiceIcon = "assets/chats/voice_volume_1.png";
  final FocusNode _focusNode = FocusNode();
  bool showMore = false;
  bool showEmojiPanel = false;
  bool showKeyboard = false;
  double lastkeyboardHeight = 0;

  @override
  void dispose() {
    _controller.dispose();
    for (var subscription in subscriptions) {
      subscription.cancel();
    }
    super.dispose();
  }

  Future<void> sendMessage() async {
    var text = _controller.text;

    if (text.isEmpty) {
      return;
    }

    TimConversationService.to.sendTextMessage(widget.conversation, text);
    _controller.text = '';
  }

  /// 发送媒体消息
  Future<void> sendMeidaMessage(AssetEntity asset) async {
    if (asset.type == AssetType.image) {
      TimConversationService.to.sendImageMessage(
        widget.conversation,
        asset,
      );
    } else if (asset.type == AssetType.video) {
      TimConversationService.to.sendVideoMessage(
        widget.conversation,
        asset,
      );
    } else {
      UiTools.toast('暂不支持的类型');
    }
  }

  hideAllPanel() {
    _focusNode.unfocus();
    setState(() {
      showKeyboard = false;
      showMore = false;
      showEmojiPanel = false;
    });
  }

  double _getBottomHeight() {
    listenKeyBoardStatus();
    if (showMore || showEmojiPanel) {
      return 248.0;
    }
    // 在文本框多行拓展时增加保护区高度
    else if (_controller.text.length >= 46 && showKeyboard == false) {
      return 25;
    } else {
      return 0;
    }
  }

  listenKeyBoardStatus() {
    final currentKeyboardHeight = MediaQuery.of(context).viewInsets.bottom;
    // 键盘弹出
    if (currentKeyboardHeight - lastkeyboardHeight > 0) {
      // 保证弹出时showKeyboard为true
      setState(() {
        showKeyboard = true;
      });

      /// 键盘收回
    } else if (currentKeyboardHeight - lastkeyboardHeight < 0) {}

    lastkeyboardHeight = MediaQuery.of(context).viewInsets.bottom;
  }

  _openMore() {
    if (showMore) {
      _focusNode.requestFocus();
    } else {
      _focusNode.unfocus();
    }
    setState(() {
      showKeyboard = showMore;
      showEmojiPanel = false;
      showMore = !showMore;
    });
  }

  @override
  Widget build(BuildContext context) {
    return SafeArea(
      child: Column(
        mainAxisSize: MainAxisSize.min,
        children: [
          const Divider(height: 0),
          Container(
            padding: EdgeInsets.only(
              left: 8,
              right: 8,
              top: 8,
              bottom: 8 + Get.mediaQuery.viewInsets.bottom,
            ),
            child: Row(
              children: [
                _voiceButton(),
                const SizedBox(width: 8),
                Expanded(child: _inputArea()),
                const SizedBox(width: 8),
                _emojiButton(),
                const SizedBox(width: 8),
                _sendButton()
              ],
            ),
          ),
          const Divider(height: 0),
          AnimatedContainer(
            height: _getBottomHeight(),
            duration: const Duration(milliseconds: 150),
            padding: showEmojiPanel
                ? const EdgeInsets.all(0)
                : const EdgeInsets.all(16),
            child: _getBottomContainer(),
          ),
        ],
      ),
    );
  }

  Widget _actionWidget(
    String text, {
    required IconData icon,
    VoidCallback? onTap,
  }) {
    return InkWell(
      onTap: () {
        onTap?.call();
      },
      child: Column(
        children: [
          Container(
            padding: const EdgeInsets.all(15),
            decoration: BoxDecoration(
              color: AppColors.white,
              borderRadius: BorderRadius.circular(5),
            ),
            child: Icon(
              icon,
              color: AppColors.unactive,
            ),
          ),
          const SizedBox(height: 3),
          Text(
            text,
            style: const TextStyle(
              color: AppColors.unactive,
              fontSize: 12,
            ),
          ),
        ],
      ),
    );
  }

  _openEmojiPanel() {
    if (showEmojiPanel) {
      _focusNode.requestFocus();
    } else {
      _focusNode.unfocus();
    }
    setState(() {
      showKeyboard = showEmojiPanel;
      showMore = false;
      showEmojiPanel = !showEmojiPanel;
    });
  }

  Widget _emojiButton() {
    return InkWell(
      onTap: () {
        _openEmojiPanel();
      },
      child: const Icon(
        Icons.emoji_emotions_outlined,
        size: 28,
      ),
    );
  }

  Widget _voiceButton() {
    if (!isVoice) {
      return InkWell(
        onTap: () {
          setState(() {
            isVoice = true;
          });
        },
        child: const Icon(
          Icons.mic_outlined,
          size: 28,
        ),
      );
    } else {
      return InkWell(
        onTap: () {
          setState(() {
            isVoice = false;
          });
        },
        child: const Icon(
          Icons.keyboard_outlined,
          size: 28,
        ),
      );
    }
  }

  Widget _inputArea() {
    if (isVoice) {
      return GestureDetector(
        onTapDown: (_) async {
          if (!isInit) {
            var result = await Permission.microphone.request().isGranted;
            if (result) initRecordSound();
          }
        },
        onLongPressStart: onLongPressStart,
        onLongPressMoveUpdate: onLongPressUpdate,
        onLongPressEnd: onLongPressEnd,
        onLongPressCancel: onLonePressCancel,
        child: Container(
          alignment: Alignment.center,
          padding: const EdgeInsets.only(
            left: 8.0,
            right: 8.0,
            top: 8.0,
            bottom: 8.0,
          ),
          decoration: const BoxDecoration(
            color: AppColors.white,
            borderRadius: BorderRadius.all(
              Radius.circular(
                4.0,
              ),
            ),
          ),
          child: const Text('按住说话'),
        ),
      );
    } else {
      return Container(
        padding: const EdgeInsets.only(
          left: 8.0,
          right: 8.0,
          top: 8.0,
          bottom: 8.0,
        ),
        decoration: const BoxDecoration(
          color: AppColors.white,
          borderRadius: BorderRadius.all(
            Radius.circular(
              4.0,
            ),
          ),
        ),
        child: TextField(
          controller: _controller,
          focusNode: _focusNode,
          decoration: null,
          onChanged: (e) {
            setState(() {
              _sendText = e;
            });
          },
          onTap: () {
            showKeyboard = true;
            showMore = false;
            showEmojiPanel = false;
          },
          onSubmitted: (value) {
            sendMessage();
          },
        ),
      );
    }
  }

  Widget _sendButton() {
    if (_sendText.isEmpty) {
      return InkWell(
        onTap: () {
          _openMore();
        },
        child: const Icon(
          Icons.add_circle_outline_outlined,
          size: 28,
          color: AppColors.active,
        ),
      );
    } else {
      return InkWell(
        onTap: () {
          sendMessage();
        },
        child: Container(
          height: 28.0,
          width: 54.0,
          alignment: Alignment.center,
          decoration: const BoxDecoration(
            color: AppColors.primary,
            borderRadius: BorderRadius.all(
              Radius.circular(
                8.0,
              ),
            ),
          ),
          child: const Text(
            '发送',
            style: TextStyle(
              letterSpacing: 2,
              color: AppColors.white,
              fontSize: 14.0,
            ),
          ),
        ),
      );
    }
  }

  initRecordSound() {
    final responseSubscription = SoundPlayer.responseListener((recordResponse) {
      final status = recordResponse.msg;
      if (status == "onStop") {
        if (!isCancelSend) {
          final soundPath = recordResponse.path;
          final recordDuration = recordResponse.audioTimeLength;
          TimConversationService.to.sendSoundMessage(
              widget.conversation, soundPath!, recordDuration!.toInt());
        }
      } else if (status == "onStart") {
        // print("start record");
        setState(() {
          isRecording = true;
        });
      } else {
        // print(status);
      }
    });
    final amplitutdeResponseSubscription =
        SoundPlayer.responseFromAmplitudeListener((recordResponse) {
      final voiceData = double.parse(recordResponse.msg!);
      setState(() {
        if (voiceData > 0 && voiceData < 0.1) {
          voiceIcon = "assets/chats/voice_volume_2.png";
        } else if (voiceData > 0.2 && voiceData < 0.3) {
          voiceIcon = "assets/chats/voice_volume_3.png";
        } else if (voiceData > 0.3 && voiceData < 0.4) {
          voiceIcon = "assets/chats/voice_volume_4.png";
        } else if (voiceData > 0.4 && voiceData < 0.5) {
          voiceIcon = "assets/chats/voice_volume_5.png";
        } else if (voiceData > 0.5 && voiceData < 0.6) {
          voiceIcon = "assets/chats/voice_volume_6.png";
        } else if (voiceData > 0.6 && voiceData < 0.7) {
          voiceIcon = "assets/chats/voice_volume_7.png";
        } else if (voiceData > 0.7 && voiceData < 1) {
          voiceIcon = "assets/chats/voice_volume_7.png";
        } else {
          voiceIcon = "assets/chats/voice_volume_1.png";
        }
        if (overlayEntry != null) {
          overlayEntry!.markNeedsBuild();
        }
      });
    });
    subscriptions = [responseSubscription, amplitutdeResponseSubscription];
    SoundPlayer.initSoundPlayer();
    isInit = true;
  }

  buildOverLayView(BuildContext context) {
    if (overlayEntry == null) {
      overlayEntry = OverlayEntry(builder: (content) {
        return Positioned(
          top: MediaQuery.of(context).size.height * 0.5 - 80,
          left: MediaQuery.of(context).size.width * 0.5 - 80,
          child: Material(
            type: MaterialType.transparency,
            child: Center(
              child: Opacity(
                opacity: 0.8,
                child: Container(
                  width: 160,
                  height: 160,
                  decoration: const BoxDecoration(
                    color: Color(0xff77797A),
                    borderRadius: BorderRadius.all(Radius.circular(20.0)),
                  ),
                  child: Column(
                    children: <Widget>[
                      Container(
                        margin: const EdgeInsets.only(top: 10),
                        child: Image.asset(
                          voiceIcon,
                          width: 100,
                          height: 100,
                          // package: 'flutter_plugin_record',
                        ),
                      ),
                      Text(
                        soundTipsText,
                        style: const TextStyle(
                          fontStyle: FontStyle.normal,
                          color: Colors.white,
                          fontSize: 14,
                        ),
                      )
                    ],
                  ),
                ),
              ),
            ),
          ),
        );
      });
      Overlay.of(context)!.insert(overlayEntry!);
    }
  }

  onLongPressStart(_) {
    if (isInit) {
      startTime = DateTime.now();
      SoundPlayer.startRecord();
      buildOverLayView(context);
    }
  }

  onLongPressUpdate(e) {
    double height = MediaQuery.of(context).size.height * 0.5 - 240;
    double dy = e.localPosition.dy;
    if (dy.abs() > height) {
      if (mounted && soundTipsText != '松开取消') {
        setState(() {
          soundTipsText = '松开取消';
        });
      }
    } else {
      if (mounted && soundTipsText == '松开取消') {
        setState(() {
          soundTipsText = '手指上滑，取消发送';
        });
      }
    }
  }

  onLongPressEnd(e) {
    double dy = e.localPosition.dy;
    // 此高度为 160为录音取消组件距离顶部的预留距离
    double height = MediaQuery.of(context).size.height * 0.5 - 240;
    if (dy.abs() > height) {
      isCancelSend = true;
    } else {
      isCancelSend = false;
    }
    if (overlayEntry != null) {
      overlayEntry!.remove();
      overlayEntry = null;
    }
    // Did not receive onStop from FlutterPluginRecord if the duration is too short.
    if (DateTime.now().difference(startTime).inSeconds < 1) {
      isCancelSend = true;
      UiTools.toast('说话时间太短!');
    }
    stop();
  }

  onLonePressCancel() {
    if (isRecording) {
      isCancelSend = true;
      if (overlayEntry != null) {
        overlayEntry!.remove();
        overlayEntry = null;
      }
      stop();
    }
  }

  void stop() {
    setState(() {
      isRecording = false;
    });
    SoundPlayer.stopRecord();
    setState(() {
      soundTipsText = '手指上滑，取消发送';
    });
  }

  _getMoreActions() {
    var list = List<Widget>.empty(growable: true);
    list.add(
      _actionWidget('相册', icon: Icons.photo, onTap: () async {
        var result = await AssetPicker.pickAssets(
          context,
          pickerConfig: const AssetPickerConfig(
            maxAssets: 9,
            requestType: RequestType.common,
          ),
        );
        if (result == null) {
          return;
        }
        for (var asset in result) {
          sendMeidaMessage(asset);
        }
      }),
    );
    list.add(
      _actionWidget('拍照', icon: Icons.photo_camera, onTap: () async {
        var asset = await CameraPicker.pickFromCamera(
          context,
          pickerConfig: const CameraPickerConfig(
            enableRecording: true,
          ),
        );
        if (asset == null) {
          return;
        }
        sendMeidaMessage(asset);
      }),
    );
    if (widget.conversation.type == ConversationType.V2TIM_C2C) {
      list.add(
        _actionWidget(
          '视频通话',
          icon: Icons.videocam,
          onTap: () {
            // ImTools.showTrtcMessage(widget.conversation.userID!);
          },
        ),
      );
    }
    list.add(
      _actionWidget(
        '位置',
        icon: Icons.pin_drop,
        onTap: () {
          // Get.toNamed(ImRoutes.conversationMap)?.then((value) {
          //   var _bmfPoiInfo = value['result'] as BMFPoiInfo;
          //   var snapshot = value['snapshot'] as Uint8List?;
          //   var model = LocationModel(
          //     name: _bmfPoiInfo.name!,
          //     address: _bmfPoiInfo.address!,
          //     list: snapshot!,
          //     latitude: _bmfPoiInfo.pt?.latitude ?? 0,
          //     longitude: _bmfPoiInfo.pt?.longitude ?? 0,
          //   );
          //   TimConversationService.to.sendLocationMessage(
          //     widget.conversation,
          //     model,
          //   );
          // });
        },
      ),
    );
    list.add(
      _actionWidget(
        '名片',
        icon: Icons.person,
        onTap: () {
          Get.toNamed(
            ContactRoutes.friend,
            arguments: {
              'name_card': true,
            },
          )?.then((value) {
            var model = value?['result'];
            if (model != null) {
              TimConversationService.to.sendCustomMessage(
                widget.conversation,
                model,
                'NAME_CARD',
              );
            }
          });
        },
      ),
    );
    list.add(
      _actionWidget(
        '文件',
        icon: Icons.folder,
        onTap: () async {
          FilePickerResult? result = await FilePicker.platform.pickFiles();
          if (result != null) {
            TimConversationService.to.sendFileMessage(
              widget.conversation,
              result.names.first!,
              result.paths.first!,
            );
          }
        },
      ),
    );
    return list;
  }

  Widget _getBottomContainer() {
    if (showEmojiPanel) {
      return EmojiPanel(
        onTapEmoji: (unicode) {
          final oldText = _controller.text;
          final newText = String.fromCharCode(unicode);
          _controller.text = "$oldText$newText";
          setState(() {
            _sendText = _controller.text;
          });
        },
      );
    }
    if (showMore) {
      return GridView.count(
        shrinkWrap: true,
        physics: const NeverScrollableScrollPhysics(),
        crossAxisCount: 4,
        children: _getMoreActions(),
      );
    }
    return Container();
  }
}
