import 'dart:io';

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/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/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;
  ChatPage({Key key, this.friendId, this.enterType = 0, this.enterContent})
      : super(key: key);

  _ChatPageState createState() => _ChatPageState();
}

class _ChatPageState extends State<ChatPage> {
  ScrollController _scrollCtrl = ScrollController();

  MessageMgr msgMgr = MessageMgr();

  UserInfo friendInfo;

  List<MsgModel> msgList;

  KeyboardIndexProvider _keyboardIndexProvider = KeyboardIndexProvider();

  TextEditingController nickNameController = new TextEditingController();

  //统计聊天时长
  int startTime;

  @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);

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

    super.dispose();
  }

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

    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);
  }

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

    if (fileSize > 33 * 1024 * 1024) {
      showToast('文件大于33M');
      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;
        msg.extraFile = originMsg.extraFile;
        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) {
                nickNameController.text = Provider.of<RefNameProvider>(context)
                    .getRefName(friendInfo.userId, friendInfo.nickName);

                var confirm = CustomUI.buildConfirmBotton(
                    I18n.of(context).determine, () async {
                  nickNameController.text = nickNameController.text.trim();
                  if (nickNameController.text == null ||
                      nickNameController.text.length > 25) {
                    showToast(I18n.of(context).only1_8);
                    return;
                  }
                  Provider.of<RefNameProvider>(context).changeRefName(
                      friendInfo.userId, nickNameController.text, () {
                    Navigator.of(context).pop();
                  });
                });
                var tip = Column(
                  children: <Widget>[
                    Container(
                      margin: EdgeInsets.only(top: 20),
                      child: Text(
                        I18n.of(context).setRemark,
                        textScaleFactor: 1.0,
                        style: TextStyle(
                            color: Constants.BlackTextColor, fontSize: 16),
                      ),
                    ),
                    Container(
                      margin: EdgeInsets.only(top: 23, bottom: 25),
                      decoration: BoxDecoration(
                          color: Colors.grey[200],
                          borderRadius: BorderRadius.all(Radius.circular(8))),
                      child: TextField(
                        keyboardAppearance: Brightness.light,
                        controller: nickNameController,
                        textAlign: TextAlign.center,
                        textInputAction: TextInputAction.search,
                        style: TextStyle(
                            textBaseline: TextBaseline.alphabetic,
                            fontSize: 14),
                        decoration: InputDecoration(
                          hintText: friendInfo.nickName,
                          hintStyle: TextStyle(fontSize: 12),
                          filled: true,
                          contentPadding: EdgeInsets.only(top: 10, bottom: 10),
                          fillColor: Colors.transparent,
                          border: InputBorder.none,
                        ),
                        maxLines: 1,
                        inputFormatters: [LengthLimitingTextInputFormatter(15)],
                      ),
                    )
                  ],
                );
                var content = CustomUI.buildConfirmContent(tip, confirm);
                CustomUI.buildTip(context, '', content);
              }
            },
            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 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: PreferredSize(
                      //     preferredSize: Size.fromHeight(58),
                      //     child: Container(
                      //         color: AppBarTheme.of(context).color,
                      //         child: SafeArea(
                      //             child: Container(
                      //           height: 56,
                      //           child: Row(children: <Widget>[
                      //             SizedBox(width: 10),
                      //             CustomUI.buildCustomLeading(context),
                      //             Text(
                      //               Provider.of<RefNameProvider>(context)
                      //                   .getRefName(friendInfo.userId,
                      //                       friendInfo.nickName),
                      //               textScaleFactor: 1.0,
                      //               style: TextStyle(
                      //                 textBaseline: TextBaseline.ideographic,
                      //                   color: Constants.BlackTextColor,
                      //                   fontSize: 16.47),
                      //             ),
                      //             Expanded(
                      //                 child: Row(
                      //                     mainAxisAlignment:
                      //                         MainAxisAlignment.end,
                      //                     children: actions))
                      //           ]),
                      //         )))),
                      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),
                          titleSpacing: -10,
                          centerTitle: false,
                          elevation: 1,
                          actions: actions),
                      body: SafeArea(
                          child: Column(
                        children: <Widget>[
                          NetStateWidget(),
                          Expanded(child: _buildMessageList()),
                          InputBar(sendMsg: sendMsg),
                        ],
                      ))),
                  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();
                      }
                    }
                  },
                );
              },
            )));
  }

  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: ListView.builder(
                reverse: true,
                shrinkWrap: true,
                itemCount: msgList.length,
                controller: _scrollCtrl,
                padding: EdgeInsets.all(8.0),
                itemBuilder: _buildItem,
              )),
              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.isBlaklistMe(friendInfo.userId)) {
      showToast(I18n.of(context).you_are_blaklisted);
      return;
    }

    if (BlacklistMgr.isInMyblaklist(friendInfo.userId)) {
      showToast(I18n.of(context).reject_message);
      return;
    }

    if (!friendInfo.isCanStrangerNews &&
        !FriendListMgr().isMyFriend(friendInfo.userId)) {
      showToast(I18n.of(context).stranger_close_tips);
      return;
    }

    MsgHandler.insertMsgToDB(msg);
    MsgHandler.sendChatMsg(msg);
    if (mounted) {
      setState(() {});
      if (_scrollCtrl.hasClients) {
        _scrollCtrl.animateTo(0,
            duration: new Duration(milliseconds: 500), curve: Curves.ease);
      }
    }
  }

  void receiveMsg(args) {
    if (mounted) {
      setState(() {});
      if (_scrollCtrl.hasClients) {
        _scrollCtrl.animateTo(0,
            duration: new Duration(milliseconds: 500), curve: Curves.ease);
      }
    }
  }

  _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];
    return ChatPageItem(
        key: Key(msg.time.toString()),
        msg: msg,
        hideKeyboard: readOnly,
        friendInfo: friendInfo,
        lastMsgTime: lastMsgTime);
  }
}
