import 'dart:convert';
import 'dart:typed_data';

import 'package:autocomplete_textfield/autocomplete_textfield.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:get_it/get_it.dart';
import 'package:sprintf/sprintf.dart';
import 'package:ustest/ConsultationList.dart';
import 'package:ustest/Services/UserService.dart';
import 'package:ustest/meeting.dart';

import 'Services/ConsultationService.dart';

class UserView extends StatefulWidget {
  @override
  State<StatefulWidget> createState() {
    // TODO: implement createState
    return _UserView();
  }
}

class _UserView extends State<UserView> {
  String? selectedType = "我申请的";

  @override
  Widget build(BuildContext context) {
    print("build userView");
    var service = GetIt.instance.get<UserService>();
    var user = service.getCurrentUser();
    if (user == null) {
      print("user is null");
      _showSignInScreen(context);
    } else {
      service.UpdateCurrentUserDetail();
    }
    var userName = user == null ? "" : user.userName;
    var accessToken = user == null ? "" : user.accessToken;

    final items = <String>["我申请的", "我组织的", "我参与的"];
    int selectedState = 0;
    if (selectedType == "我申请的") {
      selectedState = 0;
    } else if (selectedType == "我组织的") {
      selectedState = 1;
    } else {
      selectedState = 2;
    }
    Future<List<Consultation>> future = fetchConsultations(selectedState);
    GlobalKey<AutoCompleteTextFieldState<String>> typeKey = GlobalKey();
    GlobalKey listKey = GlobalKey();
    return Scaffold(
      body: Center(
        child: Column(
          children: [
            Padding(
              padding: EdgeInsets.all(8.0),
              child: Row(
                children: [
                  user == null
                      ? TextButton(
                          child: const Text("Sign in"),
                          onPressed: () => _showSignInScreen(context))
                      : Text(sprintf(
                          'Name:%s, Token:%s', [userName, accessToken])),
                  TextButton.icon(
                      onPressed: () => onLogout(context),
                      icon: Icon(Icons.logout),
                      label: Text("注銷"))
                ],
              ),
            ),
            Row(
              children: [
                TextButton.icon(
                    onPressed: () => onApplyConsultation(context),
                    icon: Icon(Icons.add),
                    label: Text("Apply")),
              ],
            ),
            Padding(
                padding: const EdgeInsets.all(8.0),
                child: DropdownButtonFormField<String>(
                  key: typeKey,
                  value: selectedType,
                  decoration: InputDecoration(hintText: "Select one state"),
                  items: items
                      .map((e) => DropdownMenuItem<String>(
                            child: Text(e),
                            value: e,
                          ))
                      .toList(),
                  onChanged: (value) {
                    selectedType = value;
                  },
                )),
            Row(
              children: [
                TextButton.icon(
                    onPressed: () => setState(() {}),
                    icon: Icon(Icons.search),
                    label: Text("Search")),
              ],
            ),
            Expanded(
                child: Center(
              child: FutureBuilder<List<Consultation>>(
                key: listKey,
                future: future,
                builder: (context, snapshot) {
                  if (snapshot.hasError) {
                    return const Center(
                      child: Text('An error has occurred!'),
                    );
                  } else if (snapshot.hasData) {
                    return ConsultationList(
                        token: accessToken, consultations: snapshot.data!);
                  } else {
                    return const Center(
                      child: CircularProgressIndicator(),
                    );
                  }
                },
              ),
            )),
            service.Channel != null
                ? StreamBuilder(
                    stream: service.Channel!.stream,
                    builder: (context, snapshot) {
                      var message = "";
                      // var message =
                      //     snapshot.hasData ? '${snapshot.data}' : 'no message';
                      if (snapshot.hasData) {
                        var uint8Array =
                            Uint8List.fromList(snapshot.data as List<int>);
                        var byteData = uint8Array.buffer.asByteData();
                        var byteDataLength = byteData.lengthInBytes;
                        var messageConentList = Uint8List.view(
                            uint8Array.buffer, 0, byteDataLength);
                        var messageConentLength = messageConentList.length;
                        var messageConent =
                            Uint8List.fromList(messageConentList);
                        var messageText = Utf8Decoder().convert(messageConent);
                        //print("message text:" + messageText);
                        var messageObject = jsonDecode(messageText);
                        //通知类型区分
                        if (messageObject["NotificationType"] as int ==
                            NotificationTypeEnum.ConnectionNotification.index) {
                          var connectionNotification =
                              ConnectionNotification.fromJson(messageObject);
                          print(
                              "connectionNotification.NotificationType:${connectionNotification.notificationType}");
                        } else if (messageObject["NotificationType"] as int ==
                            NotificationTypeEnum.DisconnectNotification.index) {
                          var disconnectNotification =
                              DisconnectNotification.fromJson(messageObject);
                          print(
                              "disconnectNotification.NotificationType:${disconnectNotification.notificationType}");
                        } else if (messageObject["NotificationType"] as int ==
                            NotificationTypeEnum
                                .FinishNotifyRecordsMessage.index) {
                          var disconnectNotification =
                              FinishNotifyRecordsMessage.fromJson(
                                  messageObject);
                          var consultationService =
                              GetIt.instance.get<ConsultationService>();
                          consultationService
                              .RaiseConsultationNotificationReceived(
                                  messageObject);
                          print(
                              "FinishNotifyRecordsMessage.NotificationType:${disconnectNotification.notificationType},  ${disconnectNotification.codes}");
                        }

                        message = messageText;
                      }
                      return new Padding(
                        padding: const EdgeInsets.symmetric(vertical: 24.0),
                        child: new Text(message),
                      );
                    })
                : Text('no notification'),
            //MeetingPage()
          ],
        ),
      ),
    );
  }

  void _showSignInScreen(BuildContext context) {
    Future.delayed(Duration.zero, () {
      Navigator.of(context).pushNamed('/signin');
    });
  }

  Future<List<Consultation>> fetchConsultations(int? selectedType) async {
    try {
      var service = GetIt.instance.get<ConsultationService>();

      var list = await service.FindConsultationsByPageAsync('id', selectedType);
      return list;
    } catch (ex) {
      print('QueryExam.to ex' + ex.toString());
      return List.empty();
    }
  }

  void onLogout(context) {
    var service = GetIt.instance.get<UserService>();
    service.logout();
    Navigator.of(context).pushNamed('/signin');
  }

  void onApplyConsultation(context) {
    print("onApplyConsultation click");
    Navigator.of(context).pushNamed('/applyconsultation');
  }
}

enum NotificationTypeEnum {
  Daiding,

  /// <summary>
  /// ChatMsgNotification|1| 聊天通知
  /// </summary>
  ChatMsgNotification,

  /// <summary>
  /// UpgradeVersionNotification|2| 版本更新通知
  /// </summary>
  UpgradeVersionNotification,

  /// <summary>
  /// LogoffNotification|3| 登出通知
  /// </summary>
  LogoffNotification,

  /// <summary>
  /// DisconnectNotification| 4|与服务器断开连接通知
  /// </summary>
  DisconnectNotification,

  /// <summary>
  /// ConnectionNotification| 5|	与服务器已连接通知
  /// </summary>
  ConnectionNotification,

  /// <summary>
  ///FinishNotifyRecordsMessage| 6 | 检查记录完成消息类型
  /// </summary>
  FinishNotifyRecordsMessage,

  /// <summary>
  ///InvitedEnterRoomNotification| 7 | 邀请用户加入房间通知
  /// </summary>
  InvitedEnterRoomNotification,

  /// <summary>
  ///CancelInvitedEnterRoomNotification| 8 |取消邀请用户通知
  /// </summary>
  CancelInvitedEnterRoomNotification,

  placeholder9,
  placeholder10,
  placeholder11,
  placeholder12,
  placeholder13,
  placeholder14,
  placeholder15,
  placeholder16,
  placeholder17,
  placeholder18,
  placeholder19,
  placeholder20,
  placeholder21,
  placeholder22,
  placeholder23,
  placeholder24,

  /// <summary>
  /// InviteLiveConsultationNotification| 25 | 开始会诊的通知
  /// </summary>
  InviteLiveConsultationNotification,

  /// <summary>
  /// AcceptLiveConsultationNotification| 26 | 接受会诊的通知
  /// </summary>
  AcceptLiveConsultationNotification,

  /// <summary>
  /// RejectLiveConsultationNotification| 27 | 拒绝会诊的通知
  /// </summary>
  RejectLiveConsultationNotification,
}

class ConnectionNotification {
  NotificationTypeEnum notificationType;
  ConnectionNotification({
    this.notificationType = NotificationTypeEnum.Daiding,
  });
  factory ConnectionNotification.fromJson(Map<String, dynamic> map) {
    return ConnectionNotification(
      notificationType: NotificationTypeEnum.values
          .firstWhere((e) => e.index == map['NotificationType']),
    );
  }
}

class DisconnectNotification {
  NotificationTypeEnum notificationType;
  DisconnectNotification({
    this.notificationType = NotificationTypeEnum.Daiding,
  });
  factory DisconnectNotification.fromJson(Map<String, dynamic> map) {
    return DisconnectNotification(
      notificationType: NotificationTypeEnum.values
          .firstWhere((e) => e.index == map['NotificationType']),
    );
  }
}

class FinishNotifyRecordsMessage {
  NotificationTypeEnum notificationType;
  List<String>? codes;
  FinishNotifyRecordsMessage(
      {this.notificationType = NotificationTypeEnum.Daiding, this.codes});
  factory FinishNotifyRecordsMessage.fromJson(Map<String, dynamic> map) {
    return FinishNotifyRecordsMessage(
      notificationType: NotificationTypeEnum.values
          .firstWhere((e) => e.index == map['NotificationType']),
      codes: map['Codes'] != null ? map['Codes'].cast<String>().toList() : null,
    );
  }
}