import 'package:fis_common/logger/logger.dart';
import 'package:fis_i18n/i18n.dart';
import 'package:fis_jsonrpc/rpc.dart';
import 'package:flutter/material.dart';
import 'package:flutter_cupertino_datetime_picker/flutter_cupertino_datetime_picker.dart';
import 'package:flyinsono/architecture/router/mobile/names.dart';
import 'package:flyinsono/architecture/router/router.dart';
import 'package:flyinsono/architecture/states/states.dart';
import 'package:flyinsono/architecture/utils/prompt_box.dart';
import 'package:flyinsono/common_business.dart';
import 'package:flyinsono/managers/interfaces/user_info.dart';
import 'package:flyinsono/managers/interfaces/live_consultation.dart';
import 'package:flyinsono/pages/schedule/calendar/utils/calendar_utils.dart';
import 'package:flyinsono/rpc.dart';
import 'package:flyinsono/views/desktop/real_time_consultation/widgets/simple_Info.dart';
import 'package:flyinsono/views/mobile/confirm_application_page/state.dart';
import 'package:flyinsono/views/mobile/confirm_application_page/widgets/select_sheet.dart';
import 'package:get/get.dart';

class ConfirmApplicationPageController extends GetxController {
  final state = ConfirmApplicationPageState();
  final descriptionController = TextEditingController();
  ConfirmApplicationPageController();

  ///批准预约会诊申请
  Future<void> approveApplication() async {
    try {
      List<ConsultationReminderDTO> consultationReminder = [];
      for (ConsultationReminderTimeEnum i
          in state.currectSelectedReminderTimeList) {
        for (ConsultationReminderMode j
            in state.currectSelectedReminderMethodList) {
          consultationReminder.add(ConsultationReminderDTO(
            consultationReminderTime: i,
            consultationReminderMode: j,
          ));
        }
      }
      if (state.startDateTime?.isBefore(DateTime.now()) ?? false) {
        PromptBox.toast(i18nBook.realTimeConsultation.dateErrorNotice.t);
        return;
      } else if (state.startDateTime?.isAfter(
            state.endDateTime ?? DateTime.now(),
          ) ??
          false) {
        PromptBox.toast(i18nBook.realTimeConsultation.timeErrorNotice.t);
        return;
      } else if (state.startDateTime == state.endDateTime) {
        PromptBox.toast(i18nBook.realTimeConsultation.timeErrorNoticeEqual.t);
        return;
      }

      var result = await rpc.liveConsultation.approvalConsultationAsync(
        ApprovalConsultationRequest(
          token: Store.user.token,
          consultationCode: state.consultationCode,
          expertUserCode: state.expertUserCode,
          consultationTime: state.startDateTime!.toLocal(),
          consultationTimeEnd: state.endDateTime!.toLocal(),
          consultationMemberCodes: state.selectParticipantsList,
          description: state.consultationDescription,
          consultationReminders: consultationReminder,
          location: "",
        ),
      );
      if (result) {
        router.replace(
          MobileRouteNames.RealTimeRemedical.ConsultationDetail,
          parameters: {
            'consultationCode': state.consultationCode,
          },
        );
      }
    } catch (e) {
      logger.e("approvalConsultationAsync exception:", e);
    }
  }

  /// 切换机构
  void changeOrgCode(String value) {
    state.currectOrganization = value;
    getAllSelectableParticipants();
  }

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

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

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

      /// 只有没有会诊专家的时候才走的逻辑
      if (state.expertList.length > 0 &&
          (state.consultationDetail.expertUserCode?.isEmpty ?? true)) {
        state.expertUserCode = state.expertList[0].value;
        getAssistantInfo();
      }
    } catch (e) {
      print(e);
    }
  }

  /// 选择的会诊时间
  dynamic getDateStringOrNull(DateTime? dateTime) {
    if (dateTime == null) {
      return null;
    } else
      return CalendarUtils.formatDateTime(
        dateTime.toLocal(),
      );
  }

  ///查询机构对应的用户信息  removeCodes表示需要去除的用户codes集合
  Future<List<FSelectSheetModel>> getUserInfosByOrganizationCode(
      String organizationCode,
      [String? currentConsultationCode]) async {
    ///组织对应的用户信息
    List<FSelectSheetModel> organizationUserInfos = [];
    try {
      List<UserExtendDTO> result;
      if ([
        TransactionStatusEnum.ToStart,
        TransactionStatusEnum.InProgress,
        TransactionStatusEnum.PendingReport
      ].contains(state.consultationDetail.consultationStatus)) {
        //会诊中添加时排除已存在的用户
        result = await rpc.liveConsultation.getInviteableUserListAsync(
          GetInviteableUserListRequest(
            token: Store.user.token,
            language: i18nBook.locale.toCodeString('-'),
            consultationCode: state.consultationCode,
            organizationCode: organizationCode,
          ),
        );
      } else {
        result = await rpc.user.getUserListAsync(
          GetUserListRequest(
              token: Store.user.token,
              organizationCode: organizationCode,
              organizationQueryType: OrganizationQueryTypeEnum.All,
              language: i18nBook.locale.toCodeString('-'),
              roleCodes: [
                RoleType.internshipDoctor,
                RoleType.certifiedPhysician,
                RoleType.certifiedExpert,
              ]),
        );
      }

      await rpc.user.getUserListAsync(
        GetUserListRequest(
          token: Store.user.token,
          organizationCode: organizationCode,
          organizationQueryType: OrganizationQueryTypeEnum.All,
          language: i18nBook.locale.toCodeString('-'),
          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.expertUserCode ?? "",
            state.assistantPhysicianCode,
            state.consultationDetail.applyUserCode ?? ""
          ];
          if (usersNeedToRemove.contains(element.userCode) == false) {
            //去除确认申请界面已选择的专家账号和助理医师账号和申请人账号
            organizationUserInfos.add(
              FSelectSheetModel(
                title: referUserName,
                value: SimpleInfoItem(
                  itemCode: element.userCode!,
                  name: referUserName,
                  role: element.roleName,
                  des: element.fieldList,
                  image: element.headImageUrl,
                ),
              ),
            );
          }
        },
      );
    } catch (e) {
      print(e);
    }
    return organizationUserInfos;
  }

  /// 获取所有可转诊机构的信息和所有可选择的参与人的信息
  Future<void> initReferOrganization() async {
    try {
      if (Store.user.rootOrganizationCode == null ||
          Store.user.rootOrganizationCode == '') {
        var manager = Get.find<IUserInfoManager>();
        await manager.getUserInfoAsync();
      }
      var result = await rpc.organization.getOrganizationByCodeAsync(
        GetOrganizationByCodeRequest(
          organizationCode: Store.user.rootOrganizationCode,
          token: Store.user.token,
        ),
      );
      List<FSelectSheetModel> selectReferOrgList = [
        FSelectSheetModel(
          title: i18nBook.realTimeConsultation.thisInstitution.t,
          value: Store.user.rootOrganizationCode!,
        ),
      ];

      result.referralOrganizations?.forEach((element) {
        selectReferOrgList.add(
          FSelectSheetModel(
            title: element.organizationName ?? '',
            value: element.organizationCode ?? '',
          ),
        );
      });
      state.organizationList = selectReferOrgList;

      getAllSelectableParticipants();
    } catch (e) {
      print(e);
    }
  }

  @override
  void onInit() {
    super.onInit();
    _initData();
  }

  @override
  void onReady() {
    super.onReady();
  }

  /// 选择结束时间
  void selectEndTime(DateTime selectTime) {
    state.endDateTime = selectTime;
  }

  /// 切换会诊专家
  void selectExpertUserCode(String value) {
    state.expertUserCode = value;
    getAssistantInfo();
  }

  /// 选择开始时间
  void selectStartTime(DateTime selectTime) {
    state.startDateTime = selectTime;
    state.endDateTime = selectTime.add(
      Duration(minutes: 30),
    );
  }

  /// 日期选择弹框
  void showDatePickerForDateTime(
    BuildContext context,
    Function(DateTime selectTime) onSelectTime,
    DateTime? currectTime,
  ) {
    DateTime today = new DateTime.now();
    DatePicker.showDatePicker(
      context,
      pickerMode: DateTimePickerMode.datetime,
      minDateTime: DateTime(2000, today.month, today.day, 0, 0),
      maxDateTime: DateTime(2122, 10, 10),
      dateFormat: "yyyy|MM|dd HH|mm",
      initialDateTime: currectTime ??
          state.consultationDetail.consultationTime?.toLocal() ??
          DateTime(today.year, today.month, today.day, 0, 0),
      minuteDivider: 15,
      onMonthChangeStartWithFirstDate: true,
      onConfirm: (DateTime dateTime, List<int> selectedIndex) {
        onSelectTime.call(dateTime);
      },
      locale: DateTimePickerLocale.zh_cn,
      onCancel: () {},
      onClose: () {},
      onChange: (datetime, selectedIndex) {
        print(datetime);
      },
    );
  }

  DateTime _compareDates(DateTime inputDate) {
    DateTime currentDate = DateTime.now();

    if (inputDate.isBefore(currentDate) ||
        inputDate.isAtSameMomentAs(currentDate)) {
      return currentDate;
    } else {
      return inputDate;
    }
  }

  DateTime _roundTime(DateTime? consultationTime) {
    if (consultationTime == null) {
      return _compareDates(DateTime.now().toLocal());
    }
    DateTime consultationDay = _compareDates(consultationTime);
    DateTime currentDay = DateTime.now();
    int minutes = currentDay.minute;
    int hours = currentDay.hour;

    if (minutes < 15) {
      minutes = 15;
    } else if (minutes < 30) {
      minutes = 30;
    } else if (minutes < 45) {
      minutes = 45;
    } else {
      minutes = 0;
      hours = (hours + 1) % 24;
    }

    return DateTime(
      consultationDay.year,
      consultationDay.month,
      consultationDay.day,
      hours,
      minutes,
    );
  }

  /// 初始化数据
  _initData() async {
    var parameters = router.getParams();
    if (parameters != null && parameters.isNotEmpty) {
      state.consultationCode = parameters["consultationCode"] ?? '';
      var consultationInfo = await Get.find<ILiveConsultationManager>()
          .findConsultationDetailAsync(state.consultationCode);
      if (consultationInfo == null) {
        return;
      }
      state.consultationDetail = consultationInfo;
      state.expertUserCode = consultationInfo.expertUserCode;
      state.startDateTime =
          _roundTime(consultationInfo.consultationTime?.toLocal());
      state.endDateTime = state.startDateTime?.add(Duration(minutes: 30));
      initReferOrganization();
      getCompetentExperts();
      getAssistantInfo();
    }
  }
}
