import 'dart:convert';
import 'dart:io';
import 'package:chat/data/translate_hk_data_mgr.dart';
import 'package:chat/home/audio_chat_view.dart';
import 'package:chat/utils/screen.dart';
import 'package:chat/utils/upload_util.dart';
import 'package:chat/utils/white_opacity_anim.dart';
import 'package:fixnum/fixnum.dart';
import 'package:cached_network_image/cached_network_image.dart';
import 'package:chat/chat/translate_state.dart';
import 'package:chat/data/UserData.dart';
import 'package:chat/data/chat_data_mgr.dart';
import 'package:chat/data/constants.dart';
import 'package:chat/generated/i18n.dart';
import 'package:chat/home/add_friend.dart';
import 'package:chat/models/ChatMsg.dart';
import 'package:chat/models/UserInfo.dart';
import 'package:chat/models/keyboard_provider.dart';
import 'package:chat/models/ref_name_provider.dart';
import 'package:chat/models/voucher_change.dart';
import 'package:chat/proto/all.pbserver.dart';
import 'package:chat/utils/CustomUI.dart';
import 'package:chat/utils/HttpUtil.dart';
import 'package:chat/utils/MessageMgr.dart';
import 'package:chat/utils/TokenMgr.dart';
import 'package:chat/utils/analyze_utils.dart';
import 'package:chat/utils/app_navigator.dart';
import 'package:chat/utils/blacklist_mgr.dart';
import 'package:chat/utils/count_down_button.dart';
import 'package:chat/utils/friend_list_mgr.dart';
import 'package:chat/utils/msgHandler.dart';
import 'package:chat/utils/net_state_widget.dart';
import 'package:chat/utils/sound_util.dart';
import 'package:chat/utils/sp_utils.dart';
import 'package:chat/utils/sql_util.dart';
import 'package:dio/dio.dart';
import 'package:extended_text/extended_text.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:oktoast/oktoast.dart';
import 'package:provider/provider.dart';
import '../r.dart';
import 'ChatPageItem.dart';
import 'input_bar.dart';
import 'package:chat/utils/PopUpMenu.dart' as myPop;
import 'package:chat/models/money_change.dart';

class ChatPage extends StatefulWidget {
  final int friendId;
  final int enterType; // 0默认  1图片
  final dynamic enterContent;
  final bool isTranslateButler;

  ChatPage(
      {Key key,
      this.friendId,
      this.enterType = 0,
      this.enterContent,
      this.isTranslateButler = false})
      : super(key: key);

  _ChatPageState createState() => _ChatPageState();
}

class _ChatPageState extends State<ChatPage> {
  final ItemScrollController itemScrollController = ItemScrollController();
  final ItemPositionsListener itemPositionListener =
      ItemPositionsListener.create();
  //ScrollController _scrollCtrl = ScrollController();

  MessageMgr msgMgr = MessageMgr();

  UserInfo friendInfo;

  List<MsgModel> msgList;

  KeyboardIndexProvider _keyboardIndexProvider = KeyboardIndexProvider();

  TextEditingController nickNameController = new TextEditingController();

  //统计聊天时长
  int startTime;

  bool isTranslateButler;

  bool isTranslateButlerFinish=false;///翻译管家是否已经结束

  int jumpTime;

  @override
  void dispose() {
    var endTime = DateTime.now().millisecondsSinceEpoch ~/ 1000;
    AnalyzeUtils.commitChatDuration(startTime, endTime);

    MessageMgr().off('Send CoinBag', _sendCoin);
    msgMgr.off('New Chat Message', receiveMsg);
    msgMgr.off('Keyboard Hide', dealWithKeyboardHide);
    msgMgr.off('Delete Select Message', _deleteItem);
    msgMgr.off(MessageMgr.TRANSLATE_HK_END_CHAT, translateHKChatEnd);
    msgMgr.off('Jump to Msg', jumpToMsg);

    MsgHandler.curActiveSession = 0;
    SoundUtils().stop();
    nickNameController.dispose();
    super.dispose();
  }

  jumpToMsg(time) {
    //var screenItemNums = itemPositionListener.itemPositions.value.length;
    int jumIndex = 0;
    jumpTime = time;
    for (int i = 0; i < msgList.length; i++) {
      if (time == msgList[i].time) {
        jumIndex = i - 1; // - screenItemNums + 2;
        break;
      }
    }
    if (jumIndex < 0) {
      jumIndex = 0;
    }
    if (jumIndex > msgList.length - 1) {
      jumIndex = msgList.length - 1;
    }
    setState(() {
      itemScrollController.scrollTo(
          index: jumIndex, duration: new Duration(microseconds: 1));
    });
  }

  @override
  void initState() {
    super.initState();
    print('init chatpage');
    getDefaultSetting();
    getUserInfo();

    isTranslateButler = widget.isTranslateButler;
    ///todo 这里再判断是否还在服务时间

    startTime = DateTime.now().millisecondsSinceEpoch ~/ 1000;

    msgList = ChatDataMgr().getRecord();

    msgMgr.on('New Chat Message', receiveMsg);
    msgMgr.on('Keyboard Hide', dealWithKeyboardHide);
    msgMgr.on('Send CoinBag', _sendCoin);
    msgMgr.on('Delete Select Message', _deleteItem);
    msgMgr.on(MessageMgr.TRANSLATE_HK_END_CHAT, translateHKChatEnd);
    msgMgr.on('Jump to Msg', jumpToMsg);
  }

  translateHKChatEnd(args){
    setState(() {
      isTranslateButlerFinish=true;
    });

  }

  void _sendFile(File file) async {
//    File file = await FilePicker.getFile();
    int fileSize = file.lengthSync();
    print('选择的文件 ${file.path} 大小 $fileSize');

    if (fileSize > 33 * 1024 * 1024) {
      showToast(I18n.of(context).max_file.replaceFirst('/s1', 33.toString()));
      return;
    }

    var fileName = file.path.split('/').last;
    print('fileName  $fileName');

    var ext = '';
    var extList = fileName.split('.');
    if (extList.length > 1) {
      ext = extList.last;
    }
    print('ext  $ext');

    var fileMsg = FileChat.create();
    fileMsg.type = ext;
    fileMsg.size = fileSize;
    fileMsg.name = fileName;

    var msg = MsgHandler.createSendMsg(
        ChatType.FileChatType, fileMsg.writeToBuffer(),
        friendId: widget.friendId,
        localFile: file.path,
        channelType: ChatChannelType.Session);

    sendMsg(msg);
  }

  _sendCoin(args) async {
    var res = await _checkCoinBeforeSend(args['amount']);
    if (res != null) {
      args['redNo'] = res['redNo'];
      args['friendId'] = widget.friendId;
      var msg = MsgHandler.createCoinBagMsg(args);

      sendMsg(msg);
    }
  }

//校验
  _checkCoinBeforeSend(int amount) async {
    Map data = {
      "userId": UserData().basicInfo.userId,
      "rUserId": friendInfo.userId,
      "price": amount,
    };
    data['sign'] = TokenMgr().getSign(data);

    Response res = await HttpUtil().post('red/packet/send', data: data);
    if (res == null) {
      return null;
    }
    Map resData = res.data;
    if (resData['code'] == 0) {
      print(resData['data']);
      return resData['data'];
    }

    return null;
  }

  void getDefaultSetting() async {
    bool soundPlayMode =
        (await SPUtils.getBool(Constants.SOUND_PLAY_MODE)) ?? false;

    _keyboardIndexProvider.init(soundPlayMode);
  }

  dealWithKeyboardHide(args) {
    if (_keyboardIndexProvider.curKeyboardIndex == 0) {
      hideKeyBoard();
    }
  }

  getUserInfo() async {
    //先从本地获取用户信息
    friendInfo = await HttpUtil().getFriendInfo(widget.friendId, true);

    //如果是新的聊天，向服务器发送创建会话消息
    if (msgList.length == 0) {
      MsgHandler.getActiveSesstion(
          [friendInfo.userId, UserData().basicInfo.userId]);
    }

    if (mounted) {
      setState(() {});
    }

    WidgetsBinding.instance.addPostFrameCallback((_) {
      if (widget.enterType == 1) {
        print('接收到的:${widget.enterContent}');

        _sendFile(File(widget.enterContent));
      } else if (widget.enterType == 2) {
        //转发消息

        MsgModel originMsg = widget.enterContent;
        MsgModel msg = MsgHandler.createSendMsg(
            ChatType.valueOf(originMsg.msgType), originMsg.msgContent);
        msg.extraInfo = originMsg.extraInfo;
        if (originMsg.extraFile == null ||
            originMsg.extraFile.contains('http')) {
          msg.extraFile = originMsg.extraFile;
        } else {
          msg.extraFile = UploadUtil().getFullUrl(
              originMsg.extraFile, originMsg.sessionId, originMsg.channelType);
        }

        msg.localFile = originMsg.localFile;
        msg.friendId = widget.friendId;
        if (msg.localFile != null) {
          msg.state = MsgState.Uploaded;
        }

        sendMsg(msg);
      }
    });
  }

  @override
  Widget build(BuildContext context) {
    print('build chatpage');

    if (friendInfo == null) {
      return Scaffold(
        backgroundColor: const Color(0xFFE2E9F1),
        body: SafeArea(
          child: Center(
            child: CircularProgressIndicator(),
          ),
        ),
      );
    }

    List<Widget> actions = [];

    int voucher = Provider.of<VoucherChangeProvider>(context).voucher;
    actions.add(Row(
      children: <Widget>[
        CustomUI.buildImageLabel("assets/images/voucher.png", voucher,
            imgOpc: 0.5, imgHeight: 13),
        CustomUI.buildImageLabel(
            R.assetsImagesCoin, Provider.of<MoneyChangeProvider>(context).money,
            isLeft: false)
      ],
    ));
    actions.add(TranslateSateWidget(friendId: friendInfo.userId));
    actions.add(Container(
        margin: EdgeInsets.only(top: 1),
        child: myPop.PopupMenuButton(
            icon: Icon(
              Icons.more_horiz,
              size: 24,
            ),
            offset: Offset(0, 100),
            onSelected: (int index) {
              if (index == 2) {
                AppNavigator.pushInformUserPage(
                    context, friendInfo.sex == 1, friendInfo.userId);
              } else if (index == 1) {
                Navigator.of(context).push(
                  new MaterialPageRoute(
                    builder: (context) {
                      return AddFriendPage(
                          userId: friendInfo.userId,
                          pageType: SendMessagePageType.Remark,
                          originalName: Provider.of<RefNameProvider>(context)
                              .getRefName(
                                  friendInfo.userId, friendInfo.nickName));
                    },
                  ),
                );
              }
            },
            itemBuilder: (BuildContext context) {
              return <myPop.PopupMenuItem<int>>[
                myPop.PopupMenuItem(
                  child: Container(
                    alignment: Alignment.center,
                    color: Colors.white,
                    padding: EdgeInsets.symmetric(vertical: 10, horizontal: 10),
                    child: Text(I18n.of(context).anonymous_report,
                        textScaleFactor: 1.0,
                        maxLines: 1,
                        style: TextStyle(
                            color: Color(AppColors.AppBarColor), fontSize: 12)),
                  ),
                  value: 2,
                ),
                myPop.PopupMenuItem(
                  child: Container(
                    decoration: BoxDecoration(
                      border: Border(
                          top: BorderSide(width: 1, color: Colors.grey[300])),
                      color: Colors.white,
                    ),
                    alignment: Alignment.center,
                    padding: EdgeInsets.symmetric(vertical: 10, horizontal: 10),
                    child: Text(I18n.of(context).Remark,
                        textScaleFactor: 1.0,
                        maxLines: 1,
                        style: TextStyle(
                            color: Color(AppColors.AppBarColor), fontSize: 12)),
                  ),
                  value: 1,
                ),
              ];
            })));

    return Stack(
      children: <Widget>[
        MultiProvider(
            providers: [
              ChangeNotifierProvider(create: (_) => _keyboardIndexProvider),
              Provider<bool>.value(value: false),
              Provider<int>.value(value: widget.friendId),
            ],
            child: GestureDetector(
                onTap: hideKeyBoard,
                child: ExtendedTextSelectionPointerHandler(
                  ///选择文字，消除弹窗

                  builder: (states) {
                    return Listener(
                      child: Scaffold(
                          resizeToAvoidBottomInset: false,
                          backgroundColor: const Color(0xFFE2E9F1),
                          appBar: AppBar(
                              title: Text(
                                '${Provider.of<RefNameProvider>(context).getRefName(friendInfo.userId, friendInfo.nickName)}',
                                textScaleFactor: 1.0,
                                style: TextStyle(
                                    color: Constants.BlackTextColor,
                                    fontSize: 16.47),
                              ),
                              leading: CustomUI.buildCustomLeading(context,onTap:(){
                                if(isTranslateButler && !isTranslateButlerFinish){
                                  if(UserData().isTranslateUser){
                                    showToast('翻译服务未结束不能主动结束');
                                  }else{
                                    CustomUI.buildTowConfirm(
                                        context,
                                        '是否提前结束翻译管家服务？',
                                        I18n.of(context).confirm,
                                            (){
                                          setState(() {
                                            isTranslateButlerFinish=true;

                                          });

                                          MsgHandler.sendEndTransHKOrderReq();
                                          Navigator.of(context).pop();
                                        },
                                        '取消',
                                            (){ Navigator.of(context).pop();});
                                  }
                                }else{
                                  Navigator.of(context).pop();
                                }

                              }), //todo
                              titleSpacing: -10,
                              centerTitle: false,
                              elevation: 1,
                              actions: actions),
                          body: SafeArea(
                              child: Column(
                            children: <Widget>[
                              NetStateWidget(),
                              (isTranslateButler&!isTranslateButlerFinish)
                                  ? _buildTranslationButler()
                                  : Container(),
                              Expanded(child: _buildMessageList()),
                              InputBar(sendMsg: sendMsg,isTranslateHK: isTranslateButler,),
                            ],
                          ))),
                      behavior: HitTestBehavior.translucent,
                      onPointerDown: (value) {
                        for (var state in states) {
                          if (!state.containsPosition(value.position)) {
                            //clear other selection
                            state.clearSelection();
                          }
                        }
                      },
                      onPointerMove: (value) {
                        //clear other selection
                        for (var state in states) {
                          if (!state.containsPosition(value.position)) {
                            //clear other selection
                            state.clearSelection();
                          }
                        }
                      },
                    );
                  },
                ))),
         isTranslateButler ? getAudioChatView() : Container(),
         isTranslateButler ? zoomAudioButton() : Container()
      ],
    );
  }

  Widget getAudioChatView() {
    if (friendInfo == null || isTranslateButlerFinish) {
      return Container();
    }

    return isActive == null
        ? Container()
        : Offstage(
            offstage: !isShowAudio,
            child: AudioChatPage(
              userInfo: friendInfo,
              isTranslateButler: true,
              isReplay: !TranslateHKMgr().isUser,
              translateButlerCloseCallBack: audioChatPageCallBack,
            ),
          );
  }

  audioChatPageCallBack(int args) {
    switch (args) {
      case 1:
        setState(() {
          isShowAudio = !isShowAudio;
          isShowZoomButton = true;
        });
        break;
      case 2:
        setState(() {
          isActive = false;
        });
        break;
    }
  }

  bool isShowAudio = false;

  ///控住连麦窗口是否显示
  bool isActive = true;

  ///控制连麦是否关闭
  bool isShowZoomButton = true;
  GlobalKey mykey = GlobalKey();

  double dx = Screen.width , dy = Screen.height/2;
  double zoomButtonSize = 60;

  void dragEvent(DragUpdateDetails details) {
    final RenderObject box = context.findRenderObject();
    //  获得自定义Widget的大小，用来计算Widget的中心锚点
    dx = details.globalPosition.dx - mykey.currentContext.size.width / 2;
    dy = details.globalPosition.dy - mykey.currentContext.size.height / 2;

//    print('dx $dx  dy $dy  screen width:${Screen.width}');

    if (dx > Screen.width - zoomButtonSize) {
      dx = Screen.width - zoomButtonSize;
    } else if (dx < 0) {
      dx = 0;
    }

    if (dy > Screen.height - zoomButtonSize) {
      dy = Screen.height - zoomButtonSize;
    } else if (dy < 0) {
      dy = 0;
    }

    setState(() {});
  }

  Widget zoomAudioButton() {

    if (friendInfo == null || !isShowZoomButton) {
      return Container();
    }

    Widget button =  Container(
      key: mykey,
      width: 57,
      height: 74,
      child: Card(child: Align(child: Icon(
        IconData(0xe67d, fontFamily: Constants.IconFontFamily),
        color: Color(0xFF008AFF),
        size: 35.0,
      ),alignment: Alignment.center,),),
    );

    return GestureDetector(
      onHorizontalDragUpdate: dragEvent,
      onVerticalDragUpdate: dragEvent,
      onTap: (){
        setState(() {
          isShowAudio = !isShowAudio;
          isShowZoomButton = !isShowZoomButton;
        });
      },
      child: Container(

        child: Transform.translate(
          offset: Offset(dx, dy),
          child: Align(
            alignment: Alignment.topLeft,
            child: button,
          ),
        ),
      ),
    );
  }

  Widget _buildTranslationButler() {
    bool hasHeadImg = true;
    if (friendInfo.headimgurl == null || friendInfo.headimgurl.length == 0) {
      hasHeadImg = false;
    }

    /// 5H币/1分钟
    String coinTIme = I18n.of(context).translation_butler_coin_time;
    coinTIme = coinTIme.replaceAll('/s1', '5');
    coinTIme = coinTIme.replaceAll('/s2', '1');

    return Container(
      padding: EdgeInsets.fromLTRB(10, 10, 10, 10),
      color: Colors.white,
      child: Row(
        children: <Widget>[
          ClipRRect(
              borderRadius: BorderRadius.circular(8),
              child: hasHeadImg
                  ? CachedNetworkImage(
                      imageUrl: friendInfo.headimgurl,
                      placeholder: (context, url) => Image.asset(
                        Constants.DefaultHeadImgUrl,
                        width: 54,
                        height: 54,
                      ),
                      width: 54,
                      height: 54,
                    )
                  : SizedBox(
                      width: 54,
                      height: 54,
                      child: Image.asset(R.assetsImagesDefaultNorAvatar))),
          Padding(
            padding: EdgeInsets.only(left: 10),
            child: Container(
              child: Column(
                crossAxisAlignment: CrossAxisAlignment.start,
                children: <Widget>[
                  Text(
                    I18n.of(context).translation_butler,
                    textScaleFactor: 1.0,
                    overflow: TextOverflow.ellipsis,
                    maxLines: 1,
                    style: TextStyle(
                        color: AppColors.NewAppbarTextColor, fontSize: 15),
                  ),
                  SizedBox(
                    height: 5,
                  ),
                  Text(
                    coinTIme,
                    textScaleFactor: 1.0,
                    maxLines: 1,
                    style: TextStyle(color: Color(0xFF797979), fontSize: 13),
                  )
                ],
              ),
              constraints: BoxConstraints(maxWidth: 135),
            ),
          ),
          TranslateHKMgr().isUser?Expanded(
              child: Container(
            constraints: BoxConstraints(maxWidth: 130),
            width: double.maxFinite,
            child: CountDownButton(
              I18n.of(context).translation_butler_end_service,
              () {

//                Navigator.of(context).pop();
              },
              countDownTime: 60*5,
              align: Alignment.centerRight,
              onPress: () {
                MsgHandler.sendEndTransHKOrderReq();
//                Navigator.of(context).pop();
              },
            ),
//            alignment: Alignment(1,0),
          )):Container(),
        ],
      ),
    );
  }


  Widget _buildMessageList() {
    return Container(
      alignment: Alignment.topCenter,
      child: msgList.length == 0
          ? Padding(
              padding: EdgeInsets.all(8),
              child: Text(
                I18n.of(context).chat_tips,
                textAlign: TextAlign.center,
                textScaleFactor: 1.0,
                style: TextStyle(color: Colors.grey, fontSize: 12),
              ))
          : NotificationListener(
              child: Scrollbar(
                  child: ScrollablePositionedList.builder(
                physics: new ClampingScrollPhysics(),
                itemCount: msgList.length,
                itemBuilder: _buildItem,
                itemScrollController: itemScrollController,
                itemPositionsListener: itemPositionListener,
                //padding: EdgeInsets.all(8.0),
                reverse: true,
                hitCallback: hideKeyBoard,
              )),
              onNotification: (notification) {
                if (notification is ScrollNotification) {
                  //   var offset = notification.metrics.pixels;
                  //   print('滚动事件 offset $offset');
                }
                return true;
              },
            ),
    );
  }

  hideKeyBoard() {
    _keyboardIndexProvider.changeSelectIndex(-1);
  }

  readOnly() {
    _keyboardIndexProvider.changeReadOnlyKey(true);
  }

  sendMsg(MsgModel msg) {


    print('对方是否拉黑你 ${friendInfo.isBlackened}');
    if (BlacklistMgr.isBlack(friendInfo.userId)) {
      return;
    }
    print('chat page session id:${msg.sessionId}');
    if (!friendInfo.isCanStrangerNews &&
        !FriendListMgr().isMyFriend(friendInfo.userId)) {
      showToast(I18n.of(context).stranger_close_tips);
      return;
    }

    MsgHandler.insertMsgToDB(msg);
    MsgHandler.sendChatMsg(msg);
    if (mounted) {
      setState(() {});
      itemScrollController.jumpTo(index: 0);
    }
  }

  MsgModel msg;
  int count = 0;

  testBig(MsgModel msg) async {
    for (int k = 0; k < 100; k++) {
      msg.msgContent = utf8.encode('测试$count');
      Int64 time = Int64((DateTime.now()).millisecondsSinceEpoch);
      msg.time = time.toInt();
      MsgHandler.insertMsgToDB(msg);
      MsgHandler.sendChatMsg(msg);
      await Future.delayed(Duration(milliseconds: 500), () {});
      count++;
    }
    count = 0;
    print('发送完毕');
    showToast('发送完毕');
  }

  void receiveMsg(args) {
    if (mounted) {
      setState(() {});
    }
  }

  _deleteItem(msg) {
    MessageMgr().emit('Cancel Request', msg);
    print('#### 开始删除--');
    msgList.remove(msg);
    setState(() {});
    SqlUtil().deleteSigleRecordWith(msg.sessionId, msg.time);
  }

  Widget _buildItem(BuildContext context, int index) {
    var lastMsgTime;
    if (index < msgList.length - 1) {
      lastMsgTime = msgList[index + 1].time;
    }

    MsgModel msg = msgList[index];
    if (msg.time == jumpTime) {
      return WhiteOpacityAnim(
        key: Key(msg.time.toString()),
        child: ChatPageItem(
            key: Key(msg.time.toString()),
            msg: msg,
            hideKeyboard: readOnly,
            friendInfo: friendInfo,
            lastMsgTime: lastMsgTime),
        animFinishCallback: () {
          jumpTime = null;
        },
      );
    } else {
      return ChatPageItem(
          key: Key(msg.time.toString()),
          msg: msg,
          hideKeyboard: readOnly,
          friendInfo: friendInfo,
          lastMsgTime: lastMsgTime);
    }
  }
}
