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

import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:image_picker/image_picker.dart';
import 'package:multi_image_picker/multi_image_picker.dart';
import 'package:sport/bean/message.dart';
import 'package:sport/db/message_db.dart';
import 'package:sport/pages/social/chat_page.dart';
import 'package:sport/services/api/inject_api.dart';
import 'package:sport/widgets/button_primary.dart';
import 'package:sport/widgets/decoration.dart';

class MenuBar extends StatefulWidget {
  final String inputField;
  final Function closeMenuCallBack;
  final Widget messageList;
  final Function scrollToBottom;
  final MenuIdentity menuIdentity;
  final Function sendCallBack;
  final GlobalKey globalkey;

  MenuBar(
    this.messageList, {
    @required this.menuIdentity,
    this.inputField,
    this.closeMenuCallBack,
    this.scrollToBottom,
    this.sendCallBack,
    this.globalkey,
  });

  @override
  State<StatefulWidget> createState() {
    // TODO: implement createState
    return _MenuBarState();
  }
}

class _MenuBarState extends State<MenuBar>
    with WidgetsBindingObserver, InjectApi {
  GlobalKey _myKey = new GlobalKey(); // 用来定位Message位置

  List<Asset> imageList = []; // 选图片的列表
  File _image; // 拍照后的图片路径

  String _textFieldValue = ""; // TextField的文本

  // TextField的 controller
  TextEditingController _controller;

  FocusNode _focusNode = new FocusNode(); // TextField 的 focus

  double keyBoardHeight = 270.0; // 初始化下面menu的高度 后续会动态调整后 优化

  bool isFirst = true; // flag 优化menu高度的操作

  String emojiJson; // 读取的JSON

  int isShowMenuBottomIndex = 0; // 用数字去优化if else 的判断

  double height;

  Timer _timer;

  void initState() {
    super.initState();

    initEmoji();

    _controller = TextEditingController();

//    _focusNode.addListener(() {
//      if (_focusNode.hasFocus) {
//        widget.scrollToBottom(keyBoardHeight: keyBoardHeight);
//        setState(() {
//          isShowMenuBottomIndex = 1;
//        });
//      }
//    });
//    WidgetsBinding.instance.addObserver(this);
  }

  // 直接进来就请求了 不要 搞这些骚的....
  void initEmoji() async {
    String json = await DefaultAssetBundle.of(context)
        .loadString("lib/assets/json/emoji_list.json");
    setState(() {
      emojiJson = json;
    });
  }

  //页面销毁
  @override
  void dispose() {
    super.dispose();
    //释放
    _focusNode.dispose();
    _timer?.cancel();
  }

  @override
//  void didChangeMetrics() {
//    super.didChangeMetrics();
//    WidgetsBinding.instance.addPostFrameCallback((_) {
//      // 当前是安卓系统并且在焦点聚焦的情况下
////      if (Platform.isAndroid && _focusNode.hasFocus) {
////        widget.scrollToBottom(context, widget.globalkey, false);
////      }
//    });
//  }

  Future add(MessageInstance message) async {
    // 聊天的时候 是没有返回 curId的 本地存储的时候 就得自己构造一个? 或者是不存?
    await MessageDB().insert(new MessageItem(
        message: message, status: 0, userId: message.toUser.id, curId: 0));
  }

  Widget extMenuItem(
    String text,
    String url,
    int index,
  ) {
    String error;
    void getPicture() async {
      try {
        // 这里是拿到想要发的图片
        List<Asset> resultList = await MultiImagePicker.pickImages(
            maxImages: 9,
            selectedAssets: imageList,
            materialOptions: MaterialOptions(
              actionBarTitle: "选择图片",
              allViewTitle: "选择图片",
              useDetailsView: true,
              startInAllView: true,
              selectionLimitReachedText: "不能选择更多了~",
            ),
            cupertinoOptions: CupertinoOptions(
              selectionFillColor: "#ff11ab",
              selectionTextColor: "#ffffff",
              selectionCharacter: "✓",
            ));
      } on Exception catch (e) {
        error = e.toString();
      }
    }

    void getPhoto() async {
      try {
        // 拍完直接发...
        final pickedFile =
            await new ImagePicker().getImage(source: ImageSource.camera);
        // 如果是聊天 直接发 ...
        if (widget.menuIdentity.menuScene == "chat") {
          // 先上传
          String url = (await api.postChatUpload(File(pickedFile.path))).data;
          MessageInstance message = (await api.postChatSend(
                  widget.menuIdentity.userId,
                  "image",
                  '{ "data":{ "url":"$url" }}'))
              .data;
//          print("$message -------------------------------");
          add(message);
        }
      } on Exception catch (e) {
        error = e.toString();
      }
    }

    List<Function> menuOperation = [getPicture, getPhoto];

    return InkWell(
      child: Column(
        crossAxisAlignment: CrossAxisAlignment.center,
        children: <Widget>[
          Container(
            padding: EdgeInsets.fromLTRB(14.0, 16.0, 14.0, 14.0),
            child: Image.asset("lib/assets/img/$url.png"),
            decoration: BoxDecoration(
              borderRadius: BorderRadius.circular(10.0),
              color: Color(0xfff1f1f1),
            ),
          ),
          SizedBox(
            height: 5.0,
          ),
          Text("$text")
        ],
      ),
      onTap: () {
        menuOperation[index]();
      },
    );
  }

  Widget _emoJiList() {
    if (emojiJson != null && emojiJson.length != 0) {
      List<dynamic> data = json.decode(emojiJson);
      return Container(
        height: keyBoardHeight,
        padding: EdgeInsets.only(left: 5, top: 5, right: 5, bottom: 5),
        decoration: BoxDecoration(
            color: Colors.white,
            border:
                Border(top: BorderSide(width: 1.0, color: Color(0xFFDCDCDC)))),
        child: GridView.custom(
          padding: EdgeInsets.all(3),
          shrinkWrap: true,
          gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
            crossAxisCount: 6,
            mainAxisSpacing: 0.5,
            crossAxisSpacing: 6.0,
          ),
          childrenDelegate: SliverChildBuilderDelegate(
            (context, index) {
              return GestureDetector(
                onTap: () {
                  String intPutString = _controller.text +
                      String.fromCharCode(data[index]["unicode"]);

                  var content = intPutString;
                  _controller.value = TextEditingValue(
                      // 设置内容
                      text: content,
                      // 保持光标在最后
                      selection: TextSelection.fromPosition(TextPosition(
                          affinity: TextAffinity.downstream,
                          offset: content.length)));
                },
                child: Center(
                  child: Text(
                    String.fromCharCode(data[index]["unicode"]),
                    style: TextStyle(fontSize: 33),
                  ),
                ),
              );
            },
            childCount: data.length,
          ),
        ),
      );
    }
    return Container();
  }

  Widget menuBottom() {
    // 这里的软键盘动画还是有点问题....
    List<Widget> list = [
      Container(),
      SizedBox(
        height: MediaQuery.of(context).viewInsets.bottom,
      ),
      Container(
          height: keyBoardHeight,
          padding: EdgeInsets.only(left: 24.0, right: 24.0),
          decoration: BoxDecoration(
              color: Colors.white,
              border: Border(
                  top: BorderSide(width: 1.0, color: Color(0xFFDCDCDC)))),
          child: GridView(
              shrinkWrap: true,
              padding: EdgeInsets.only(top: 24.0),
              physics: NeverScrollableScrollPhysics(),
              gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
                crossAxisCount: 4, //横轴三个子widget
              ),
              children: <Widget>[
                extMenuItem("图片", "bbs_icon_picture", 0),
                extMenuItem("拍照", "bbs_icon_photo", 1),
              ])),
      _emoJiList(),
    ];
    return list[isShowMenuBottomIndex];
  }

  Widget build(BuildContext context) {
    // 优化 输入键盘高度 跟 菜单栏高度的操作
    if (isFirst && MediaQuery.of(context).viewInsets.bottom != 0.0) {
      setState(() {
        keyBoardHeight = MediaQuery.of(context).viewInsets.bottom;
        isFirst = false;
      });
    }

    return Column(
      children: <Widget>[
//        GestureDetector(
//          onTap: () {
//            setState(() {
//              isShowMenuBottomIndex = 0;
//            });
//            _focusNode.unfocus();
//          },
//          // 列表在这里...
//          child: ,
//        ),
        Expanded(
          child: widget.messageList,
        ),
        ConstrainedBox(
            key: _myKey,
            constraints: BoxConstraints(maxHeight: 150, minHeight: 50),
            child: Container(
                padding:
                    const EdgeInsets.symmetric(vertical: 8.0, horizontal: 12.0),
                decoration: shadowTop(),
                child: Column(
                  mainAxisSize: MainAxisSize.min,
                  children: <Widget>[
                    Row(
                      children: <Widget>[
                        GestureDetector(
                          onTap: () {
                            if (_focusNode.hasFocus) {
                              SystemChannels.textInput
                                  .invokeMethod('TextInput.hide');
                            }
                            setState(() {
                              isShowMenuBottomIndex = 2;
                            });
                          },
                          child: Padding(
//                padding: const EdgeInsets.symmetric(vertical: 8.0, horizontal: 12.0),
                            child: Image.asset(
                                "lib/assets/img/bbs_icon_addmore.png"),
                            padding: EdgeInsets.only(right: 12.0),
                          ),
                        ),
                        GestureDetector(
                          onTap: () {
                            setState(() {
                              FocusScope.of(context).requestFocus(_focusNode);
                              if (_focusNode.hasFocus) {
                                SystemChannels.textInput
                                    .invokeMethod('TextInput.hide');
                              }
                              isShowMenuBottomIndex = 3;
                            });
                          },
                          child: Padding(
//                padding: const EdgeInsets.symmetric(vertical: 8.0, horizontal: 12.0),
                            child: Image.asset(
                                "lib/assets/img/bbs_icon_expression.png"),
                            padding: EdgeInsets.only(right: 12.0),
                          ),
                        ),
                        Expanded(
                          flex: 7,
                          child: Container(
                            child: TextField(
                              controller: _controller,
                              focusNode: _focusNode,
                              keyboardType: TextInputType.multiline,
                              minLines: 1,
                              maxLines: 3,
//                              maxLength: 200,
//                              onChanged: (value) {
//                                setState(() {
//                                  _textFieldValue = value;
//                                });
//                              },
                              onTap: () {
                                setState(() {
                                  isShowMenuBottomIndex = 1;
                                });
                              },
                              decoration: InputDecoration(
                                  counterText: "",
                                  hintText: "${widget.inputField}",
                                  contentPadding:
                                      EdgeInsets.symmetric(vertical: 16.0),
                                  border: InputBorder.none),
                            ),
                          ),
                        ),
                        Expanded(
                          flex: 3,
                          child: PrimaryButton(
                              content: "发送",
                              callback: () async {
                                if (widget.menuIdentity.menuScene == "chat") {
//                                  MessageInstance message =
//                                      (await api.postChatSend(
//                                              widget.menuIdentity.userId,
//                                              "text",
//                                              '{"text":"${_controller.text}"}'))
//                                          .data;

                                  MessageInstance message = new MessageInstance(
                                    type: "link",
                                    data: new MessageData(
                                        logo: avatarList[
                                            Random().nextInt(10) % 13],
                                        url: "www.baidu.com",
                                        text: "饭粒猫与包子鸭呀...",
                                        user: new MessagePostUser(
                                            name: "饭粒猫...")),
                                    toUser: new MessageUser(
                                        id: 10,
                                        avatar:
                                            "https://wxt.sinaimg.cn/thumb300/a6bdcd78gy1gfna8wnwquj20lr0lradp.jpg?tags=%5B%5D"),
                                    fromUser: new MessageUser(
                                        id: 10,
                                        avatar:
                                            "https://wxt.sinaimg.cn/thumb300/a6bdcd78gy1gfna8wnwquj20lr0lradp.jpg?tags=%5B%5D"),
                                  );

//                                  await add(
//                                      message); // await 是等待的标志 我等待完 在做后面的init 的事?
//                                  _controller.text = "";

                                  // view 上setstate 渲染的...
                                  widget.sendCallBack(
                                      message); // 添加完 在 callBack...

                                  // 调整高度...
//                                  widget.scrollToBottom(context,
//                                      widget.globalkey, false); //发完还得 调整一手 ...
                                }
                                // 这里可能传不了 callback 所有需要的值都在menu bar里面 只能通过传 不同的 场景 进行 不同的操作
                              }),
                        ),
                      ],
                    ),
                  ],
                ))),
        // 底部的骚操作
        menuBottom(),
      ],
    );
  }
}

// 只是用来封装 scrollToBottom
class GetMenuController {
  ScrollController scrollMenuController = new ScrollController();

  // 暂时不用 这个 scrollToBottom ...
  void scrollToBottom(BuildContext context, GlobalKey key, bool first) {
    scrollMenuController.addListener(() {
      print("[offSet:]${scrollMenuController.offset}----------------------");
    });

    // 页面一屏的高度
    double pageHeight = MediaQuery.of(context).size.height;

    // 头部的高度...
    double appBarAndHeight = MediaQuery.of(context).padding.top + 56;

    // 尾部的高度...
    double bottomHeight = 160;

    // scrollView 的 高度 ...
    double scrollHeight = key.currentContext.size.height;

    print("[scrollHeight]:$scrollHeight----------------------------");

    double position = scrollMenuController?.position?.maxScrollExtent;

    double currentOffset = scrollMenuController.offset;

    double getScrollTop(bool first) {
      if (first) {
        return scrollHeight;
      } else {
        // 不需要滚动的状态... 当前 所处的位置 需不需要 加上 bottomHeight...
        if (currentOffset < bottomHeight) {
          return position + appBarAndHeight + bottomHeight;
        } else {
          return position + appBarAndHeight;
        }
      }
    }

    if (scrollMenuController.hasClients) {
      Future.delayed(Duration(milliseconds: 30), () {
        scrollMenuController?.jumpTo(getScrollTop(first));
      });
    }
  }
}

// 自己内部传的 bean 用来鉴别 是什么 场景使用的 menuBar
class MenuIdentity {
  String menuScene; // 当前的MenuBar 所属的场景在哪 比如 聊天 chat / 社区 social / 反馈 feedBack 等
  int userId; // Chat的时候需要的userId

  MenuIdentity({this.menuScene, this.userId});

  MenuIdentity.fromJson(Map<String, dynamic> json) {
    menuScene = json['menuScene'];
    userId = json['userId'];
  }

  Map<String, dynamic> toJson() {
    final Map<String, dynamic> data = new Map<String, dynamic>();
    data['menuScene'] = this.menuScene;
    data['userId'] = this.userId;
    return data;
  }
}
