import 'package:fis_common/index.dart';
import 'package:fis_common/logger/logger.dart';
import 'package:fis_i18n/i18n.dart';
import 'package:fis_jsonrpc/rpc.dart';
import 'package:fis_measure/utils/prompt_box.dart';
import 'package:fis_ui/index.dart';
import 'package:flutter/material.dart';
import 'package:flyinsono/architecture/define.dart';
import 'package:flyinsono/architecture/router/index.dart';
import 'package:flyinsono/architecture/services/modules/config_language.dart';
import 'package:flyinsono/architecture/services/modules/configurations_form.dart';
import 'package:flyinsono/architecture/states/states.dart';
import 'package:flyinsono/architecture/utils/keyboard.dart';
import 'package:flyinsono/common_business.dart';
import 'package:flyinsono/js_platform/listener.dart';
import 'package:flyinsono/managers/interfaces/appointment_consultation.dart';
import 'package:flyinsono/managers/interfaces/user_info.dart';
import 'package:flyinsono/rpc.dart';
import 'package:flyinsono/utils/export_status_type.dart';
import 'package:flyinsono/views/desktop/appointment_consultation/view.dart';
import 'package:flyinsono/views/desktop/index.dart';
import 'package:flyinsono/views/desktop/real_time_consultation/state.dart';
import 'package:flyinsono/views/desktop/real_time_consultation/widgets/application_info.dart';
import 'package:flyinsono/views/desktop/real_time_consultation/widgets/simple_Info.dart';
import 'package:get/get.dart';
import 'package:intl/intl.dart';
import 'consultation_evaluate_controller.dart';
import 'consultation_image_controller.dart';
import 'consultation_list_controller.dart';
import 'consultation_report_controller.dart';
import 'consultation_visit_controller.dart';
import 'listener_controller.dart';

class RealTimeConsultationController extends FControllerBase
    with EnterPressListenOnControllerMixin {
  late final RealTimeConsultationReportController reportController;
  late final RealTimeConsultationListController listController;
  late final RealTimeConsultationEvaluationController evaluationController;
  late final RealTimeConsultationVisitController visitController;
  late final RealTimeConsultationImageController imageController;
  late final ListenerController listenerController;
  final appointmentConsultationManager = Get.find<IAppointmentConsultation>();

  final searchController = TextEditingController();

  /// 需要初始化的预约单号
  String? initConsultationCode;

  final state = RealTimeConsultationState();

  /// 语言服务
  final languageService = Get.find<LanguageService>();

  /// 页面配置项
  final consultationService = Get.find<ConfigurationFormService>();

  /// 撤销按钮
  JsListener businessParent = JsListener();

  FocusNode keyWordSearchFocusNode = FocusNode();
  bool _isSearchHasFocus = false;
  @override
  void onEnterPressed() {
    if (_isSearchHasFocus) {
      state.pageIndex = 1;
      listController.findConsultationsByPageAsync();
    }
  }

  RealTimeConsultationController({this.initConsultationCode}) {
    reportController = RealTimeConsultationReportController(this);
    listController = RealTimeConsultationListController(this);
    evaluationController = RealTimeConsultationEvaluationController(this);
    visitController = RealTimeConsultationVisitController(this);
    imageController = RealTimeConsultationImageController(this);
    listenerController = ListenerController(this);
  }

  /// 同意预约会诊邀约
  Future<bool> agreeInvitation() async {
    var result = false;
    try {
      result = await rpc.liveConsultation.acceptInvitationAsync(
        AcceptInvitationRequest(
          token: Store.user.token,
          isAgree: true,
          consultationRecordCode: state.currentConsultationCode,
        ),
      );
      if (result) {
        await listController.findConsultationsByPageAsync();
        PromptBox.toast(
            i18nBook.realTimeConsultation.acceptedTheInvitation4Toast.t);
      }
    } catch (e) {
      print(e);
    }
    return result;
  }

  @override
  void dispose() {
    appointmentConsultationManager.onDataChange.removeListener(_onDataChange);
    listenerController.dispose();
    super.dispose();
  }

  ///批准预约会诊申请
  Future<bool> approveApplication(ApplicationInfo applicationInfo) async {
    var result = false;
    try {
      List<String> consultationMemberCodes = []; //参与人的编码
      for (int i = 0; i < applicationInfo.participantsTotal.length; i++) {
        consultationMemberCodes.add(applicationInfo.participantsTotal[i]);
      }
      result = await rpc.liveConsultation.approvalConsultationAsync(
        ApprovalConsultationRequest(
          token: Store.user.token,
          consultationCode: state.currentConsultationCode,
          expertUserCode: applicationInfo.competentExperts,
          consultationTime: applicationInfo.startTime!.toUtc(),
          consultationTimeEnd: applicationInfo.endTime!.toUtc(),
          consultationMemberCodes: consultationMemberCodes,
          description: applicationInfo.description,
          consultationReminders: applicationInfo.consultationReminders,
          location: "",
        ),
      );
      refreshRealTimeConsultation();
    } catch (e) {
      if (e.toString() ==
          "JSON-RPC Exception: 814 Consultation time greater than current time") {
        PromptBox.toast(i18nBook.realTimeConsultation.dateErrorNotice.t);
      } else {
        PromptBox.toast(
            i18nBook.realTimeConsultation.approveConsultationFaild.t);
      }
      logger.e("approvalConsultationAsync exception:", e);
      print(e);
    }
    return result;
  }

  /// 点击实时诊断的卡片
  void clickRealTimeConsultationCard(ConsultationsRecordCard info) {
    state.currentConsultationCode = info.consultationCode;
    findConsultationDetailAsync();
    print(state.currentConsultationCode);
  }

  /// 点击实时诊断的日程
  void clickRealTimeConsultationSchedule(String currentConsultationCode) {
    state.currentConsultationCode = currentConsultationCode;
    findConsultationDetailAsync();
  }

  /// 创建申请单
  void createAppointmentConsultation() async {
    await Get.dialog(
      FAppointmentConsultationPage(
        realTimeConsultationController: this,
      ),
    );
  }

  /// 查询会诊详情
  Future<void> findConsultationDetailAsync() async {
    try {
      final result = await rpc.liveConsultation.findConsultationDetailAsync(
        FindConsultationDetailRequest(
          token: Store.user.token,
          consultationCode: state.currentConsultationCode,
        ),
      );
      result.consultationTime =
          result.consultationTime?.toLocal() ?? DateTime.now();
      state.consultationsRecordInfos = result;
    } catch (e) {
      printError(info: "findConsultationDetailAsync exception:$e");
      logger.e("findConsultationDetailAsync exception:", e);
    }
  }

  String getAgeValue(
    String ageUnits,
    String ageYear,
    String ageMonth,
    String ageWeek,
    String ageDay,
  ) {
    switch (ageUnits) {
      case 'Year':
        return ageYear + i18nBook.remedical.years.t;
      case 'YearAndMonth':
        return ageYear +
            i18nBook.remedical.years.t +
            ageMonth +
            i18nBook.remedical.month.t;
      case 'MonthAndWeek':
        return ageMonth +
            i18nBook.remedical.month.t +
            ageWeek +
            i18nBook.remedical.week.t;
      case 'WeekAndDay':
        return ageWeek +
            i18nBook.remedical.week.t +
            ageDay +
            i18nBook.remedical.day.t;
      default:
        return i18nBook.remedical.notFill.t;
    }
  }

  ///获取所有可选择的参与人员
  Future<void> getAllSelectableParticipants() async {
    for (int i = 0; i < state.organizations.length; i++) {
      var result = getUserInfosByOrganizationCode(state.organizations[i].code);
      List<SimpleInfoItem> userInfos = await result;
      state.allSelectableParticipants.addAll(userInfos);
    }
  }

  ///获取助理医师
  Future<UserInfoByCodeDTO> getAssistantInfo(String expertCode) async {
    try {
      final result = await rpc.user.getUserByCodeAsync(
          GetUserByCodeRequest(token: Store.user.token, userCode: expertCode));
      state.assistantPhysicianName = result.bindAssistantDoctorUserName ??
          i18nBook.realTimeConsultation.noAssistant.t;
      state.assistantPhysicianCode = result.bindAssistantDoctorUserCode ?? '';
      return result;
    } catch (e) {
      logger.e(
          'RealTimeConsultationController getAssistantInfo ex:' + e.toString());
      return new UserInfoByCodeDTO();
    }
  }

  ///获取机构的会诊专家
  Future<List<FSelectModel>> getCompetentExperts() async {
    List<FSelectModel> expertList = [];
    try {
      var result = await rpc.liveConsultation
          .findOrganizationExpertsAsync(FindOrganizationExpertsRequest(
        token: Store.user.token,
        organizationCode: state.consultationsRecordInfos.expertOrganizationCode,
        pageIndex: 1,
        pageSize: 100,
      ));
      var pageData = result.pageData ?? [];
      for (int i = 0; i < pageData.length; i++) {
        final userName = pageData[i].displayName!;
        expertList.add(FSelectModel(
          code: pageData[i].userCode!,
          name: userName,
        ));
      }
    } catch (e) {
      print(e);
    }
    return expertList;
  }

  /// 翻译
  ///
  /// [moudle] 模块
  ///
  /// [code] 翻译key
  String getLanguageValues(
    String moudle,
    String code,
  ) {
    try {
      var value = languageService.findLanguageValueByCode(moudle, code);
      return value;
    } catch (e) {
      print(e);
    }
    return code;
  }

  ///获取已选择的可参与人员的详细信息
  void getParticipantsDetails() {
    state.choosedParticipantsDetails.clear();
    for (int j = 0; j < state.applicationInfo.participantsTotal.length; j++) {
      for (int i = 0; i < state.allSelectableParticipants.length; i++) {
        if (state.allSelectableParticipants[i].itemCode ==
            state.applicationInfo.participantsTotal[j]) {
          state.choosedParticipantsDetails
              .add(state.allSelectableParticipants[i]);
          break;
        }
      }
    }
  }

  /// 获取病人数据
  Map<String, String> getPatientValue(
    List<DataItemDTO> patientData,
  ) {
    return {
      'Name': handlePatientValue(patientData, 'Name'),
      'Age': handlePatientValue(patientData, 'Age'),
      'Sex': handlePatientValue(patientData, 'Sex'),
      'Phone': handlePatientValue(patientData, 'Phone'),
      'Birthday': handlePatientValue(patientData, 'Birthday'),
      'AgeYear': handlePatientValue(patientData, 'AgeYear'),
      'AgeMonth': handlePatientValue(patientData, 'AgeMonth'),
      'AgeWeek': handlePatientValue(patientData, 'AgeWeek'),
      'AgeDay': handlePatientValue(patientData, 'AgeDay'),
      'AgeUnits': handlePatientValue(patientData, 'AgeUnits'),
      'Anamnesis': handlePatientValue(patientData, 'Anamnesis'),
      'HeadImgUrl': handlePatientValue(patientData, 'HeadImgUrl'),
      'AnimalInfoName': handlePatientValue(patientData, 'AnimalInfoName'),
      'IdentityCard': handlePatientValue(patientData, 'IdentityCard'),
    };
  }

  ///获取角色类型
  ////普通用户 Role_GeneralUser
  ///实习医生 Role_InternshipDoctor
  ///专家助理 Role_ExpertAssistant
  ///认证医师 Role_CertifiedPhysician
  ///认证专家 Role_CertifiedExpert
  Future<String> getRoleType() async {
    try {
      UserDTO userInfo = await rpc.user.getUserInfoAsync(
        GetUserInfoRequest(
          token: Store.user.token,
        ),
      );
      return userInfo.roleCodes![0];
    } catch (e) {
      logger.e('RealTimeConsultationController GetRoleType ex:' + e.toString());
      return "";
    }
  }

  ///查询机构对应的用户信息  removeCodes表示需要去除的用户codes集合
  Future<List<SimpleInfoItem>> getUserInfosByOrganizationCode(
      String organizationCode,
      {String keyword = ''}) async {
    ///组织对应的用户信息
    List<SimpleInfoItem> organizationUserInfos = [];
    try {
      List<UserExtendDTO> result;
      if ([
        TransactionStatusEnum.ToStart,
        TransactionStatusEnum.InProgress,
        TransactionStatusEnum.PendingReport
      ].contains(state.consultationsRecordInfos.consultationStatus)) {
        //会诊中添加时排除已存在的用户
        result = await rpc.liveConsultation.getInviteableUserListAsync(
          GetInviteableUserListRequest(
            token: Store.user.token,
            language: i18nBook.locale.toCodeString('-'),
            consultationCode: state.currentConsultationCode,
            organizationCode: organizationCode,
          ),
        );
      } else {
        result = await rpc.user.getUserListAsync(
          GetUserListRequest(
              token: Store.user.token,
              organizationCode: organizationCode,
              organizationQueryType: OrganizationQueryTypeEnum.All,
              language: i18nBook.locale.toCodeString('-'),
              keyword: keyword,
              roleCodes: [
                RoleType.internshipDoctor,
                RoleType.certifiedPhysician,
                RoleType.certifiedExpert,
              ]),
        );
      }
      result.forEach(
        (element) async {
          final referUserName = element.displayName!;
          if (element.roleName == null) {
            element.roleName = i18nBook.user.notAuthenticated.t;
          }
          List<String> usersNeedToRemove = [
            state.expertCode ?? "",
            state.assistantPhysicianCode,
            state.consultationsRecordInfos.applyUserCode ?? ""
          ];
          if (usersNeedToRemove.contains(element.userCode) == false) {
            //去除确认申请界面已选择的专家账号和助理医师账号和申请人账号
            organizationUserInfos.add(
              SimpleInfoItem(
                itemCode: element.userCode!,
                name: referUserName,
                role: element.roleName,
                des: element.fieldList,
                image: element.headImageUrl,
              ),
            );
          }
        },
      );
    } catch (e) {
      print(e);
    }
    return organizationUserInfos;
  }

  /// 处理病人参数
  String handlePatientValue(List<DataItemDTO> patientData, String value) {
    return patientData
            .firstWhereOrNull(
              (element) => element.key == value,
            )
            ?.value ??
        '';
  }

  ///获取所有可转诊机构的信息和所有可选择的参与人的信息
  Future<void> initReferOrganization() async {
    try {
      if (Store.user.rootOrganizationCode.isNullOrEmpty) {
        var manager = Get.find<IUserInfoManager>();
        await manager.getUserInfoAsync();
      }
      var result = await rpc.liveConsultation.findParentOrganizationsAsync(
        FindHigherOrganizationsRequest(
          token: Store.user.token,
        ),
      );
      List<FSelectModel> selectReferOrgList = [];

      result.forEach((element) {
        selectReferOrgList.add(
          FSelectModel(
            name: element.organizationName ?? '',
            code: element.organizationCode ?? '',
          ),
        );
      });
      state.organizations = selectReferOrgList;

      FSelectModel currentOrganization = new FSelectModel(
          name: i18nBook.realTimeConsultation.thisInstitution.t,
          code: Store.user.rootOrganizationCode!); //本机构
      state.organizations.insert(0, currentOrganization);
      getAllSelectableParticipants();
    } catch (e) {
      print(e);
    }
  }

  /// 筛选
  void onFilter() async {
    await listController.findConsultationsByPageAsync();
    router.back();
  }

  /// 重置
  void onReset() {
    state.startDate = DateFormat('yyyy-MM-dd')
        .format(DateTime.now().toLocal().subtract(Duration(days: 30 * 3)));
    state.endDate = DateFormat('yyyy-MM-dd').format(DateTime.now().toLocal());
    state.consultationStatus = QueryConsultationStatusEnum.All;
    state.consultationEvaluationType = QueryEvaluateGradeEnum.All;
    state.consultationQueryType = ConsultationQueryTypeEnum.All;
    state.currentCompetentExpert = '';
    state.currentApplicantInstitution = '';
    state.currentConsultationInstitution = '';
    state.currentSex = '';
    state.currentMinAge = null;
    state.currentMaxAge = null;
    state.currentUnit = QueryAgeUnitsEnum.Year;
    state.currentPatientDiseases = '';
    state.currentPatientPrimaryDiagnosis = '';
  }

  @override
  void onInit() {
    super.onInit();
    appointmentConsultationManager.onDataChange.addListener(_onDataChange);
    listController.findConsultationsByPageAsync();

    /// 预约单配置初始化
    consultationService.init(true);

    /// 初始化当前机构名称
    _initRootOrganizationName();

    _listenSearchFocusNode();
    if (initConsultationCode != null) {
      state.currentConsultationCode = initConsultationCode ?? "";
      findConsultationDetailAsync();
    }
    Get.find<IUserInfoManager>().getUserInfoAsync().then((value) {
      if (value.rootOrganizationCode?.isEmpty ?? false) {
        PromptBox.toast(i18nBook.auth.pleaseSetHospital.t);
      }
    });
  }

  /// 刷新
  void refreshRealTimeConsultation() async {
    await listController.findConsultationsByPageAsync();
  }

  ///拒绝预约会诊申请
  Future<bool> refuseApplication() async {
    var result = false;
    try {
      result = await rpc.liveConsultation.rejectApplyConsultationAsync(
        RejectApplyConsultationRequest(
          token: Store.user.token,
          consultationCode: state.currentConsultationCode,
          reason: state.refuseReason,
        ),
      );
      if (result) {
        listController.findConsultationsByPageAsync();
      }
      appointmentConsultationManager.onDataChange.emit(this, true);
    } catch (e) {
      print(e);
    }
    return result;
  }

  /// 拒绝预约会诊邀约
  Future<bool> refuseInvitation(String rejectReason) async {
    var result = false;
    try {
      result = await rpc.liveConsultation.acceptInvitationAsync(
        AcceptInvitationRequest(
          token: Store.user.token,
          isAgree: false,
          refusalCause: rejectReason,
          consultationRecordCode: state.currentConsultationCode,
        ),
      );
      if (result) {
        await listController.findConsultationsByPageAsync();
        PromptBox.toast(
            i18nBook.realTimeConsultation.declinedTheInvitation4Toast.t);
      }
    } catch (e) {
      print(e);
    }
    return result;
  }

  /// 撤销二次提示框
  Future<void> revokeConsultation() async {
    await FConfirmAlert.showModalDialog(
      context: Get.context!,
      title: i18nBook.common.tip.t,
      subTitle: i18nBook.realTimeConsultation.sureCancelCurrentConsultation.t,
      businessParent: businessParent,
      confrimLabel: i18nBook.common.confirm.t,
      cancelLabel: i18nBook.common.cancel.t,
      onConfirm: () async {
        await _revokeConsultationAsync();
      },
      onCancel: () {},
    );
  }

  ///自动设置结束时间,结束时间在开始时间基础上加30分钟
  List<int> setEndTimeAuto(TimeOfDay startTime) {
    //增加的时间（分钟）
    int addMinute = 30;
    //时间间隔（分钟）
    int minuteInterval = 15;
    //分钟时间上限(分钟)
    int minuteTimeUpperBound = 45;
    //一天的总时间(小时)
    int oneDayHour = 24;
    //一小时有4个15分钟
    int count = 4;
    //如果minute大于45分钟，则hour加1；如果hour已满24小时，则hour从0开始
    int endHour = (startTime.hour +
                    ((startTime.minute + addMinute) > minuteTimeUpperBound
                        ? 1
                        : 0)) ~/
                oneDayHour ==
            1
        ? 0
        : startTime.hour +
            ((startTime.minute + addMinute) > minuteTimeUpperBound ? 1 : 0);
    //minute以15分钟为基数向上取整，如果minute超过60分钟，则minute从0开始循环
    int endMinute = (((startTime.minute + addMinute) ~/ minuteInterval +
                ((startTime.minute + addMinute) % minuteInterval == 0
                    ? 0
                    : 1)) %
            count) *
        minuteInterval;
    List<int> endTime = [endHour, endMinute];
    return endTime;
  }

  ///开启会诊
  void startConsultation({bool isJoin = false}) {
    var consultationCode = state.currentConsultationCode;
    appointmentConsultationManager.startConsultation(
      consultationCode,
      isJoin: isJoin,
      pageIndex: state.pageIndex,
    );
  }

  ///字符串转换为TimeOfDay
  TimeOfDay transformFromString(String str) {
    TimeOfDay timeOfDay = TimeOfDay(
        hour: int.parse(str.split(":")[0]),
        minute: int.parse(str.split(":")[1]));
    return timeOfDay;
  }

  ///TimeOfDay转换为字符串
  String transformFromTimeOfDay(TimeOfDay timeOfDay) {
    print('${timeOfDay.hour.toString()}:${timeOfDay.minute.toString()}');
    String time = timeOfDay.toString().split("(")[1].split(")")[0];
    return time;
  }

  void _listenSearchFocusNode() {
    keyWordSearchFocusNode.addListener(() {
      if (keyWordSearchFocusNode.hasFocus) {
        _isSearchHasFocus = true;
      } else {
        Future.delayed(
          const Duration(milliseconds: 10),
          () {
            _isSearchHasFocus = false;
          },
        );
      }
    });
  }

  Future<void> _initRootOrganizationName() async {
    final orgInfo = await rpc.organization
        .getOrganizationByCodeAsync(GetOrganizationByCodeRequest(
      token: Store.user.token,
      organizationCode: Store.user.rootOrganizationCode,
    ));
    Store.user.rootOrganizationName = orgInfo.organizationName ?? '';
  }

  /// 撤销
  Future<void> _revokeConsultationAsync() async {
    try {
      busy = true;
      final result = await rpc.liveConsultation.revokeConsultationAsync(
        RevokeConsultationRequest(
          token: Store.user.token,
          consultationCode: state.currentConsultationCode,
        ),
      );
      busy = false;
      if (result) {
        PromptBox.toast(i18nBook.common.revokeSuccess.t);
        await findConsultationDetailAsync();
      }
    } catch (e) {
      printError(info: "revokeConsultationAsync exception:$e");
      logger.e("revokeConsultationAsync exception:", e);
      busy = false;
    }
  }

  void _onDataChange(Object sender, bool e) {
    refreshRealTimeConsultation();
  }

  /// 打开会诊评价弹窗
  void openEvaluateDialog(String consultationCode) async {
    evaluationController.openEvaluateDialogByCode(consultationCode);
  }

  void abortExport() {
    state.isExporting = false;
    state.exportProgress = 0.0;
    state.exportState = ExportStatusType.Downloading;
    rpc.platform.abortExportOperation();
  }
}

class RealTimeConsultationDialogController
    extends RealTimeConsultationController {
  RealTimeConsultationDialogController({super.initConsultationCode});
}
