/*
 * @Descripttion: 
 * @version: 
 * @Author: guanxiaoxin
 * @Date: 2023-07-27 09:14:15
 * @LastEditors: guanxiaoxin
 * @LastEditTime: 2023-08-04 10:22:46
 * @FilePath: \work\lib\views\desktop\appointment_consultation\controller.dart
 */
import 'package:fis_common/helpers/encrypt.dart';
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_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/states/states.dart';
import 'package:flyinsono/architecture/utils/keyboard.dart';
import 'package:flyinsono/architecture/utils/prompt_box.dart';
import 'package:flyinsono/common_business.dart';
import 'package:flyinsono/js_platform/listener.dart';
import 'package:flyinsono/managers/interfaces/entities/patient_Info.dart';
import 'package:flyinsono/managers/interfaces/user_info.dart';
import 'package:flyinsono/rpc.dart';
import 'package:flyinsono/views/desktop/appointment_consultation/controller/check_required_item_controller.dart';
import 'package:flyinsono/views/desktop/appointment_consultation/state.dart';
import 'package:flyinsono/views/desktop/real_time_consultation/controller/real_time_consultation_controller.dart';
import 'package:get/get.dart';
import 'entitys/appointment_model.dart';
import 'entitys/patient_model.dart';

class AppointmentConsultationController extends FControllerBase
    with EnterPressListenOnControllerMixin {
  final state = AppotintmentConsultationState();
  final deviceInputController = TextEditingController();
  final expertInputController = TextEditingController();
  final deviceFocusNode = FocusNode();
  final expertFocusNode = FocusNode();
  late final CheckRequiredItemController checkRequiredItemController;

  /// 实时会诊控制器
  final RealTimeConsultationController realTimeConsultationController;

  final bool isEmergency;

  Map<String, String> patient = {};

  // final checkRequiredItemController = CheckRequiredItemController();
  AppointmentConsultationController({
    required this.realTimeConsultationController,
    this.isEmergency = false,
  }) {
    checkRequiredItemController = CheckRequiredItemController(this);
  }
  OrganizationDTO? orgInfo;
  FocusNode keyWordSearchFocusNode = FocusNode();
  bool _isSearchHasFocus = false;

  // 俩个逻辑1、创建；2、修改
  List<DataItemDTO> applyConsultationPatientInfo() {
    return [
      if (state.currentPatient.phone!.isPhoneNumber ||
          patient['Phone']!.isPhoneNumber)
        DataItemDTO(
          key: 'Phone',
          value: FEncryptHelper.encodeBase64(
            state.currentPatient.phone.isNullOrEmpty
                ? patient['Phone'] ?? ''
                : state.currentPatient.phone ?? '',
          ),
        ),
      DataItemDTO(
        key: 'AgeUnits',
        value: state.currentPatient.ageUnits ?? patient['AgeUnits'],
      ),
      DataItemDTO(
        key: 'AgeYear',
        value: state.currentPatient.ageYear,
      ),
      DataItemDTO(
        key: 'AgeMonth',
        value: state.currentPatient.ageMonth,
      ),
      DataItemDTO(
        key: 'AgeWeek',
        value: state.currentPatient.ageWeek,
      ),
      DataItemDTO(
        key: 'AgeDay',
        value: state.currentPatient.ageDay,
      ),
      DataItemDTO(
        key: 'Sex',
        value: patient['Sex'] ?? state.currentPatient.sex,
      ),
      DataItemDTO(
        key: 'Anamnesis',
        value: state.currentPatient.anamnesis ?? patient['Anamnesis'],
      ),
    ];
  }

  /// 选择病人
  void clickSelectPatient() async {
    await findConsultationPatientAsync();
    if (state.patientList.isEmpty) {
      confirmAlertAddNewPatient();
    }
  }

  /// 二次弹框 是否是新创建病人
  void confirmAlertAddNewPatient() {
    var container = JsListener();
    FConfirmAlert.show(
      context: Get.context!,
      title: i18nBook.common.tip.t,
      subTitle: i18nBook.remedical.hint4patientNotFound.translate(
        [state.patientName],
      ),
      confrimLabel: i18nBook.common.confirm.t,
      cancelLabel: i18nBook.common.cancel.t,
      onConfirm: () async {
        await busyHandle(
          () async {
            await createPatient();
          },
          text: i18nBook.remedical.creating.t,
        );
      },
      businessParent: container,
    );
  }

  /// 创建申请
  Future<void> createNewConsultationAsync() async {
    final appointmentInformation = state.appointmentInformation;

    /// 如果不是专家助理，而是专家或者医生，那申请人是自己
    if (!state.isApplyUserField) {
      appointmentInformation.appointmentApplicant = Store.user.code;
    }
    if (!checkRequiredItemController.isCanApplyConsultation()) {
      PromptBox.toast(
          i18nBook.realTimeConsultation.requiredItemsNotCompleted.t);
      return;
    }

    if (_determineFormatOfPhoneNum(state.currentPatient.phone!) == false) {
      PromptBox.toast(i18nBook.errorCodes.errorCode6000.t);
      return;
    }
    busy = true;
    final result = await rpc.liveConsultation.applyConsultationAsync(
      ApplyConsultationRequest(
        token: Store.user.token,
        expertUserCode: appointmentInformation.appointmentCompetentExpert,
        deviceCode: appointmentInformation.appointmentDevice,
        scanPositions: appointmentInformation.appointmentScanningPosition,
        consultationTime: appointmentInformation.appointmentTime!.toUtc(),
        patientCode: state.currentPatient.patientCode,
        diseases: appointmentInformation.appointmentDiseaseName,
        scanUserCode: appointmentInformation.appointmentDocter,
        expertOrganizationCode:
            appointmentInformation.appointmentConsultationInstitution,
        applyUserCode: appointmentInformation.appointmentApplicant,
        primaryDiagnosis: appointmentInformation.preliminaryDiagnosis,
        patientDatas: applyConsultationPatientInfo(), // 申请预约单的病人数据
      ),
    );
    if (result.isNotEmpty) {
      realTimeConsultationController.listController
          .findConsultationsByPageAsync();
      router.back();
      PromptBox.toast(i18nBook.remedical.createSuccess.t);
    }
    busy = false;
  }

  /// 根据名字快捷创建病人
  Future<void> createPatient() async {
    if (state.patientName.isEmpty) {
      PromptBox.toast(
          i18nBook.realTimeConsultation.pleaseEnterCreatedPatientName.t);
      return;
    }
    final name = FEncryptHelper.encodeBase64(state.patientName);
    await createPatientByUnregisteredAsync(
      name,
    );
  }

  /// 创建病人
  Future<void> createPatientByUnregisteredAsync(
    String patientName,
  ) async {
    try {
      busy = true;
      final result = await rpc.patient.createPatientByUnregisteredAsync(
        CreatePatientByUnregisteredRequest(
          token: Store.user.token,
          patientName: patientName,
        ),
      );
      findConsultationPatientAsync();
      if (!result) {
        PromptBox.toast(i18nBook.remedical.creatFailed.t);
      }
      busy = false;
    } catch (e) {
      printError(info: "createPatientByUnregisteredAsync exception:$e");
      logger.e("createPatientByUnregisteredAsync exception:", e);
      busy = false;
    }
  }

  /// dispose 释放内存
  @override
  void dispose() {
    super.dispose();
  }

  /// 获取病人列表数据
  Future<void> findConsultationPatientAsync() async {
    try {
      final result = await rpc.liveConsultation.findConsultationPatientAsync(
        FindConsultationPatientPageRequest(
          token: Store.user.token,
          keyword: state.patientName,
          pageIndex: 1,
          pageSize: 100,
        ),
      );
      handleConsultationPatient(result.pageData ?? []);
    } catch (e) {
      logger.e('msg', e);
    }
  }

  /// 申请人
  Future<void> findOrganizationAssistantsAsync() async {
    try {
      final result = await rpc.liveConsultation.findAssistantExpertsAsync(
        FindAssistantExpertsRequest(
          token: Store.user.token,
        ),
      );
      List<FSelectModel> organizationAssistants = [];
      for (int i = 0; i < result.length; i++) {
        organizationAssistants.add(
          FSelectModel(
            name: result[i].displayName!,
            code: result[i].userCode ?? '',
          ),
        );
      }
      state.organizationAssistants = organizationAssistants;
    } catch (e) {
      printError(info: "findOrganizationAssistantsAsync exception:$e");
      logger.e("findOrganizationAssistantsAsync exception:", e);
      busy = false;
    }
  }

  /// 获取会诊专家
  Future<List<FSelectModel>> findOrganizationExpertsAsync(
      {int pageIndex = 1,
      int pageSize = 100,
      String? keyword,
      bool isloadMore = false}) async {
    try {
      final result = await rpc.liveConsultation.findOrganizationExpertsAsync(
        FindOrganizationExpertsRequest(
          token: Store.user.token,
          pageIndex: pageIndex,
          keyword: keyword,
          pageSize: pageSize,
          organizationCode:
              state.appointmentInformation.appointmentConsultationInstitution,
        ),
      );
      var pageData = result.pageData ?? [];
      List<FSelectModel> competentExperts = [];
      for (int i = 0; i < pageData.length; i++) {
        competentExperts.add(
          FSelectModel(
            name: pageData[i].displayName!,
            code: pageData[i].userCode ?? '',
          ),
        );
      }
      if (isloadMore) {
        state.competentExperts.addAll(competentExperts);
        return competentExperts;
      } else if (pageIndex == 1) {
        state.competentExperts = competentExperts;
      }
    } catch (e) {
      printError(info: "findOrganizationExpertsAsync exception:$e");
      logger.e("findOrganizationExpertsAsync exception:", e);
      busy = false;
    }
    return state.competentExperts;
  }

  /// 获取会诊机构
  Future<void> findParentOrganizationsAsync() async {
    try {
      final result = await rpc.liveConsultation.findParentOrganizationsAsync(
        FindHigherOrganizationsRequest(
          token: Store.user.token,
        ),
      );
      List<FSelectModel> consultationInstitution = [];
      for (int i = 0; i < result.length; i++) {
        consultationInstitution.add(
          FSelectModel(
            name: result[i].organizationName ?? '',
            code: result[i].organizationCode ?? '',
          ),
        );
      }
      final consultationsRecordInfos =
          realTimeConsultationController.state.consultationsRecordInfos;
      if (consultationsRecordInfos.isEmergency) {
        var orgCode =
            state.appointmentInformation.appointmentConsultationInstitution ??
                '';
        if (orgCode.isNotEmpty) {
          final orginfos = await Get.find<IUserInfoManager>()
              .getOrganizationByCode(state.appointmentInformation
                      .appointmentConsultationInstitution ??
                  '');
          consultationInstitution.add(
            FSelectModel(
              name: orginfos.organizationName ?? '',
              code: orginfos.organizationCode ?? '',
            ),
          );
        }
      }
      state.consultationInstitution = consultationInstitution;
      //如果之前选择的会诊机构已解绑,则默认不选择任何会诊机构
      state.selectedconsultationInstitution = setSelectValue(
          state.consultationInstitution,
          state.appointmentInformation.appointmentConsultationInstitution);
    } catch (e) {
      printError(info: "getUserListAsync exception:$e");
      logger.e("getUserListAsync exception:", e);
      busy = false;
    }
  }

  ///获取病人信息
  Future<ClientPatientInfoDTO> findPatientByCodeAsync(
      String patientCode) async {
    try {
      if (patientCode.isNullOrEmpty) {
        return ClientPatientInfoDTO();
      }
      final patients = await rpc.patient.findPatientByCodeAsync(
        FindPatientByCodeRequest(
          code: patientCode,
          token: Store.user.token,
        ),
      );
      return patients;
    } catch (e) {
      return ClientPatientInfoDTO();
    }
  }

  /// 获取检查部位
  Future<void> findScanPositionsAsync() async {
    try {
      busy = true;
      final result = await rpc.liveConsultation.findScanPositionsAsync(
        TokenRequest(
          token: Store.user.token,
        ),
      );
      List<FSelectModel> scanPositionsList = [];
      for (int i = 0; i < result.length; i++) {
        scanPositionsList.add(
          FSelectModel(
            name: realTimeConsultationController.getLanguageValues(
              'consultation',
              result[i],
            ),
            code: result[i],
          ),
        );
      }
      state.scanPositionsList = scanPositionsList;
      busy = false;
    } catch (e) {
      printError(info: "getPersonDeviceDropdownListAsync exception:$e");
      logger.e("getPersonDeviceDropdownListAsync exception:", e);
      busy = false;
    }
  }

  String getLanguageValues(String? code) {
    return realTimeConsultationController.getLanguageValues(
      'consultation',
      code ?? '',
    );
  }

  /// 获取个人设备
  Future<List<FSelectModel>> getPersonDeviceDropdownListAsync({
    int pageIndex = 1,
    int pageSize = 100,
    String? keyWord,
    bool isloadMore = false,
  }) async {
    try {
      busy = true;

      final result = await rpc.device
          .getDeviceListByPersonRoleAsync(GetPersonRoleDeviceRequest(
        token: Store.user.token,
        pageIndex: pageIndex,
        pageSize: 100,
        keyWord: keyWord,
      ));
      List<FSelectModel> deviceList = [];
      List<DeviceInfoDTO> deviceInfoList = result.pageData ?? [];

      for (int i = 0; i < deviceInfoList.length; i++) {
        deviceList.add(
          FSelectModel(
            name: deviceInfoList[i].displayName ?? '',
            code: deviceInfoList[i].deviceCode ?? '',
          ),
        );
      }
      if (isloadMore) {
        state.deviceList.addAll(deviceList);
      } else if (pageIndex == 1) {
        state.deviceList = deviceList;
      }
      //如果之前选择的会诊设备已解绑,则默认不选择任何设备
      state.selectedDeviceCode = setSelectValue(
          state.deviceList, state.appointmentInformation.appointmentDevice);
      busy = false;
      if (isloadMore) {
        return deviceList;
      }
      return state.deviceList;
    } catch (e) {
      printError(info: "getPersonDeviceDropdownListAsync exception:$e");
      logger.e("getPersonDeviceDropdownListAsync exception:", e);
      busy = false;
    }
    return [];
  }

  /// 获取扫查医生
  Future<void> getUserListAsync() async {
    try {
      busy = true;
      final result = await rpc.user.getUserListAsync(
        GetUserListRequest(
            token: Store.user.token,
            language: i18nBook.locale.toCodeString('-'),
            organizationCode: Store.user.rootOrganizationCode,
            organizationQueryType: OrganizationQueryTypeEnum.All,
            roleCodes: [RoleType.certifiedExpert, RoleType.certifiedPhysician]),
      );
      List<FSelectModel> scannDoctorList = [];
      for (int i = 0; i < result.length; i++) {
        scannDoctorList.add(
          FSelectModel(
            name: result[i].displayName!,
            code: result[i].userCode ?? '',
          ),
        );
      }
      state.scannDoctorList = scannDoctorList;
      //如果之前选择的扫查医生已解绑，则默认不选择任何扫查医生
      state.appointmentDocter = setSelectValue(state.scannDoctorList,
          state.appointmentInformation.appointmentDocter);

      busy = false;
    } catch (e) {
      printError(info: "getUserListAsync exception:$e");
      logger.e("getUserListAsync exception:", e);
      busy = false;
    }
  }

  /// 处理病人数据
  void handleConsultationPatient(
    List<ClientPatientInfoBaseDTO> clientPatients,
  ) {
    final List<PatientInfo> patientList = [];
    PatientInfo patientInfo;

    for (int i = 0; i < clientPatients.length; i++) {
      final List<DataItemDTO> patientData = clientPatients[i].patientData ?? [];
      Map<String, String> patientValues =
          realTimeConsultationController.getPatientValue(patientData);
      final String name = _getPatientName(patientValues);
      final String age = patientValues['Age'] ?? '';
      final String sex = patientValues['Sex'] ?? '';
      final String phone = patientValues['Phone'] ?? '';
      final String birthday = patientValues['Birthday'] ?? '';
      final String ageYear = patientValues['AgeYear'] ?? '';
      final String ageMonth = patientValues['AgeMonth'] ?? '';
      final String ageWeek = patientValues['AgeWeek'] ?? '';
      final String ageDay = patientValues['AgeDay'] ?? '';
      final String ageUnits = patientValues['AgeUnits'] ?? '';
      final String anamnesis = patientValues['Anamnesis'] ?? '';
      final String headImgUrl = patientValues['HeadImgUrl'] ?? '';
      final String identityCard = patientValues['IdentityCard'] ?? '';
      patientInfo = PatientInfo(
        isValid: clientPatients[i].isValid,
        createTime: clientPatients[i].createTime ?? DateTime.now(),
        patientCode: clientPatients[i].patientCode ?? '',
        name: name,
        age: age,
        sex: sex,
        phone: phone,
        birthday: birthday,
        ageYear: ageYear,
        ageMonth: ageMonth,
        ageWeek: ageWeek,
        ageDay: ageDay,
        ageUnits: ageUnits,
        anamnesis: anamnesis,
        headImgUrl: headImgUrl,
        identityCard: identityCard,
      );
      patientList.add(patientInfo);
    }
    state.patientList = patientList;
  }

  //完善会诊信息
  Future<void> improveConsultationInfo() async {
    try {
      if (!checkRequiredItemController.isCanApplyConsultation()) {
        PromptBox.toast(
            i18nBook.realTimeConsultation.requiredItemsNotCompleted.t);
        return;
      }

      if (_determineFormatOfPhoneNum(state.currentPatient.phone!) == false) {
        PromptBox.toast(i18nBook.errorCodes.errorCode6000.t);
        return;
      }
      final consultationsRecordInfos =
          realTimeConsultationController.state.consultationsRecordInfos;
      final appointmentInformation = state.appointmentInformation;
      await rpc.liveConsultation
          .improveConsultationInfoAsync(ImproveConsultationInfoRequest(
        consultationCode: consultationsRecordInfos.consultationCode,
        patientCode: state.currentPatient.patientCode,
        scanPositions: appointmentInformation.appointmentScanningPosition,
        diseases: appointmentInformation.appointmentDiseaseName,
        primaryDiagnosis: appointmentInformation.preliminaryDiagnosis,
        patientDatas: applyConsultationPatientInfo(),
        token: Store.user.token,
      ));
    } catch (e) {
      logger.e(
          'AppointmentConsultationController improveConsultationInfo ex:', e);
    }

    realTimeConsultationController.listController
        .findConsultationsByPageAsync();
    router.back();
    router.back(); //两层弹窗均关闭
  }

  /// 初始化病人数据
  void initGetPatients() async {
    state.patientName = '';
    findConsultationPatientAsync();
    getPersonDeviceDropdownListAsync();
    findScanPositionsAsync();
    getUserListAsync();
    findParentOrganizationsAsync();
    findOrganizationAssistantsAsync();
  }

  /// 在 [onDelete] 方法之前调用。
  @override
  void onClose() {
    super.onClose();
  }

  @override
  void onEnterPressed() {
    if (_isSearchHasFocus) {
      clickSelectPatient();
    }
  }

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

  /// 在 onInit() 之后调用 1 帧。这是进入的理想场所
  @override
  void onReady() {
    super.onReady();
    if (!isEmergency) {
      initGetPatients();
      _initConfigurationItemForm();
      _listenSearchFocusNode();
      _initOrgInfo();
    }
  }

  ///设置下拉框初始值
  String? setSelectValue(List<FSelectModel> source, String? code) {
    if (code.isNotNullOrEmpty) {
      if (source.any((element) => element.code == code)) {
        return code;
      }
    }
    return null;
  }

  /// 修改预约单
  Future<void> updateConsultationAsync() async {
    try {
      final appointmentInformation = state.appointmentInformation;

      /// 如果不是专家助理，而是专家或者医生，那申请人是自己
      if (!state.isApplyUserField) {
        appointmentInformation.appointmentApplicant = Store.user.code;
      }
      if (!checkRequiredItemController.isCanApplyConsultation()) {
        PromptBox.toast(
            i18nBook.realTimeConsultation.requiredItemsNotCompleted.t);
        return;
      }
      //获取今天的时间，从0点开始
      DateTime dateTimeNow = DateTime(DateTime.now().year, DateTime.now().month,
          DateTime.now().day, 0, 0, 0);

      //如果会诊时间早于当前时间则弹出提示
      if (appointmentInformation.appointmentTime!.compareTo(dateTimeNow) ==
          -1) {
        PromptBox.toast(i18nBook.realTimeConsultation.dateErrorNotice.t);
        return;
      }
      List<List<FSelectModel>> sourceList = [
        state.deviceList,
        state.scannDoctorList,
        state.consultationInstitution
      ];
      List<String?> codesList = [
        appointmentInformation.appointmentDevice,
        appointmentInformation.appointmentDocter,
        appointmentInformation.appointmentConsultationInstitution
      ];
      if (_isReselect(sourceList, codesList) == false) {
        return;
      }
      busy = true;
      final consultationsRecordInfos =
          realTimeConsultationController.state.consultationsRecordInfos;
      final result = await rpc.liveConsultation.updateConsultationAsync(
        UpdateConsultationRequest(
          token: Store.user.token,
          expertUserCode: appointmentInformation.appointmentCompetentExpert,
          deviceCode: appointmentInformation.appointmentDevice,
          scanPositions: appointmentInformation.appointmentScanningPosition,
          consultationTime: appointmentInformation.appointmentTime!.toUtc(),
          diseases: appointmentInformation.appointmentDiseaseName,
          scanUserCode: appointmentInformation.appointmentDocter,
          expertOrganizationCode:
              appointmentInformation.appointmentConsultationInstitution,
          applyUserCode: appointmentInformation.appointmentApplicant,
          primaryDiagnosis: appointmentInformation.preliminaryDiagnosis,
          consultationCode: consultationsRecordInfos.consultationCode,
        ),
      );
      if (result) {
        realTimeConsultationController.listController
            .findConsultationsByPageAsync();
        router.back();
      }
      busy = false;
    } catch (e) {
      printError(info: "updateConsultationAsync exception:$e");
      logger.e("updateConsultationAsync exception:", e);
      PromptBox.toast(i18nBook.errorCodes.errorCodeUN.t);
      busy = false;
    }
  }

  /// 接收会诊数据
  List<AppointmentModel> _acceptAppointmentJson(Map<String, dynamic> map) {
    return _acceptJson(
      map,
      (json) => AppointmentModel.fromJson(json),
      (key) =>
          realTimeConsultationController.getLanguageValues('consultation', key),
    );
  }

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

  /// 接收json数据
  List<T> _acceptJson<T>(
    Map<String, dynamic> map,
    T Function(Map<String, dynamic>) fromJson,
    String Function(String) getLanguageValues,
  ) {
    List<T> list = [];
    map.forEach((key, value) {
      if (value != null) {
        value['key'] = key;
        value['label'] = getLanguageValues(key);

        final model = fromJson(value);
        list.add(model);
      }
    });
    return list;
  }

  /// 接收病人数据
  List<PatientModel> _acceptPatientJson(Map<String, dynamic> map) {
    return _acceptJson(
      map,
      (json) => PatientModel.fromJson(json),
      (key) =>
          realTimeConsultationController.getLanguageValues('consultation', key),
    );
  }

  ///判断手机号格式
  bool _determineFormatOfPhoneNum(String phoneNumber) {
    if (orgInfo?.isEncryptedShow ?? false) {
      return true;
    }
    RegExp exp = RegExp(r'^[0-9]{11}$');
    return exp.hasMatch(phoneNumber);
  }

  /// 初始化配置项表单
  void _initConfigurationItemForm() {
    /// 病人信息
    state.patientKeyList = _acceptPatientJson(
      realTimeConsultationController.consultationService.getConsultationInfo(
        'Patient',
      ),
    );

    /// 预约信息
    state.appointmentKeyList = _acceptAppointmentJson(
      realTimeConsultationController.consultationService.getConsultationInfo(
        'ConsultationBaseInfo',
      ),
    );
  }

  ///如果会诊设备/扫查医生/会诊机构已解绑，判断是否重新选择了新的会诊设备/扫查医生/会诊机构
  bool _isReselect(List<List<FSelectModel>> sourceList, List<String?> codes) {
    List<FSelectModel> deviceList = sourceList[0];
    String? deviceCode = codes[0];
    List<FSelectModel> scanDoctorList = sourceList[1];
    String? scanDoctorCode = codes[1];
    List<FSelectModel> institutionList = sourceList[2];
    String? institutionCode = codes[2];
    if (setSelectValue(deviceList, deviceCode) == null) {
      PromptBox.toast(
          i18nBook.realTimeConsultation.pleaseSelectConsultationEquipment.t);
      return false;
    } else if (setSelectValue(scanDoctorList, scanDoctorCode) == null) {
      PromptBox.toast(
          i18nBook.realTimeConsultation.pleaseSelectScanningDoctor.t);
      return false;
    } else if (setSelectValue(institutionList, institutionCode) == null) {
      PromptBox.toast(
          i18nBook.realTimeConsultation.pleaseSelectConsultationInstitution.t);
      return false;
    }
    return true;
  }

  String _getPatientName(Map<String, String> patientValues) {
    var name = patientValues['Name'];
    if (name == null || name.isEmpty) {
      name = patientValues['AnimalInfoName'];
    }
    return name!;
  }

  fetchDevices(String pattern) {}

  Future<void> _initOrgInfo() async {
    orgInfo = await Get.find<IUserInfoManager>()
        .getOrganizationByCode(Store.user.rootOrganizationCode ?? '');
  }
}
