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/states/states.dart';
import 'package:flyinsono/architecture/values/features.dart';
import 'package:flyinsono/utils/export_status_type.dart';
import 'package:flyinsono/views/desktop/index.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';

///主页状态
class RealTimeConsultationState {
  final Rx<int> _selectIndex = Rx(0);
  final Rx<int> _pageIndex = Rx(1);
  final Rx<int> _totalCount = Rx(0);
  final Rx<double> _exportProgress = Rx(0);
  final Rx<ExportStatusType> _exportState = Rx(ExportStatusType.Starting);
  final Rx<bool> _isExporting = Rx(false);

  final Rx<String> _keyWord = Rx('');
  final RxString _currentConsultationCode = RxString('');
  final Rx<List<ConsultationsRecordCard>> _consultationsRecordCardList =
      Rx(<ConsultationsRecordCard>[]);
  final Rx<ConsultationDetailDTO> _consultationsRecordInfos =
      Rx(ConsultationDetailDTO());
  final Rx<ConsultationQueryTypeEnum?> _consultationQueryType =
      Rx(ConsultationQueryTypeEnum.All);
  final Rx<QueryConsultationStatusEnum?> _consultationStatus =
      Rx(QueryConsultationStatusEnum.All);

  final Rx<QueryEvaluateGradeEnum?> _consultationEvaluationType =
      Rx(QueryEvaluateGradeEnum.All);
  final Rx<String> _filterTimeType = Rx('1');
  final Rx<List<ConsultationDetailDTO>> _consultationDetailList =
      Rx(<ConsultationDetailDTO>[]);
  final Rx<List<FSelectModel>> _consultationInstitutionList =
      Rx(<FSelectModel>[]);
  final Rx<List<FSelectModel>> _competentExpertList =
      Rx(<FSelectModel>[FSelectModel(name: i18nBook.common.all.t, code: '')]);
  final Rx<List<FSelectModel>> _applicantInstitutionList =
      Rx(<FSelectModel>[FSelectModel(name: i18nBook.common.all.t, code: '')]);

  final Rx<String> _currentConsultationInstitution = Rx('');
  final Rx<String> _currentCompetentExpert = Rx('');
  final Rx<String> _currentApplicantInstitution = Rx('');
  final Rx<String> _currentSex = Rx('');
  final Rx<int?> _currentMinAge = Rx(null);
  final Rx<int?> _currentMaxAge = Rx(null);
  final Rx<QueryAgeUnitsEnum> _currentUnit = Rx(QueryAgeUnitsEnum.Year);
  final Rx<String> _currentPatientDiseases = Rx('');
  final Rx<String> _currentPatientPrimaryDiagnosis = Rx('');

  final Rx<String?> _startDate = Rx(DateFormat('yyyy-MM-dd')
      .format(DateTime.now().toLocal().subtract(Duration(days: 30))));
  final Rx<String?> _endDate = Rx(DateFormat('yyyy-MM-dd')
      .format(DateTime.now().toLocal().add(Duration(days: 30))));

  /// 实时会诊下标
  int get selectIndex => _selectIndex.value;
  set selectIndex(int val) => _selectIndex.value = val;

  /// 当前页数
  int get pageIndex => _pageIndex.value;
  set pageIndex(int val) => _pageIndex.value = val;

  /// 当前表格总数
  int get totalCount => _totalCount.value;
  set totalCount(int val) => _totalCount.value = val;

  ///导出进度
  set exportProgress(double v) => _exportProgress.value = v;
  double get exportProgress => _exportProgress.value;

  ///导出状态
  set exportState(ExportStatusType v) => _exportState.value = v;
  ExportStatusType get exportState => _exportState.value;

  ///是否正在导出
  set isExporting(bool v) => _isExporting.value = v;
  bool get isExporting => _isExporting.value;


  /// 当前选择的会诊编码
  String get currentConsultationCode => _currentConsultationCode.value;
  set currentConsultationCode(String val) =>
      _currentConsultationCode.value = val;

  /// 当前筛选出的关键字
  String get keyWord => _keyWord.value;
  set keyWord(String val) => _keyWord.value = val;

  /// 当前筛选出的开始时间
  String? get endDate => _endDate.value;
  set endDate(String? val) => _endDate.value = val;

  /// 当前筛选出的结束时间
  String? get startDate => _startDate.value;
  set startDate(String? val) => _startDate.value = val;

  /// 预约大列表数据
  List<ConsultationDetailDTO> get consultationDetailList =>
      _consultationDetailList.value;
  set consultationDetailList(List<ConsultationDetailDTO> val) =>
      _consultationDetailList.value = val;

  /// 预约会诊卡片列表
  List<ConsultationsRecordCard> get consultationsRecordCardList =>
      _consultationsRecordCardList.value;
  set consultationsRecordCardList(List<ConsultationsRecordCard> val) =>
      _consultationsRecordCardList.value = val;

  /// 预约会诊详情
  ConsultationDetailDTO get consultationsRecordInfos =>
      _consultationsRecordInfos.value;
  set consultationsRecordInfos(ConsultationDetailDTO val) =>
      _consultationsRecordInfos.value = val;

  /// 筛选分类
  ConsultationQueryTypeEnum? get consultationQueryType =>
      _consultationQueryType.value;
  set consultationQueryType(ConsultationQueryTypeEnum? val) =>
      _consultationQueryType.value = val;

  /// 筛选会诊状态
  QueryConsultationStatusEnum? get consultationStatus =>
      _consultationStatus.value;
  set consultationStatus(QueryConsultationStatusEnum? val) =>
      _consultationStatus.value = val;

  /// 筛选会诊评价
  QueryEvaluateGradeEnum? get consultationEvaluationType =>
      _consultationEvaluationType.value;
  set consultationEvaluationType(QueryEvaluateGradeEnum? val) =>
      _consultationEvaluationType.value = val;

  /// 筛选会诊时间
  String get filterTimeType => _filterTimeType.value;
  set filterTimeType(String val) => _filterTimeType.value = val;

  /// 筛选会诊机构列表
  List<FSelectModel> get consultationInstitutionList =>
      _consultationInstitutionList.value;
  set consultationInstitutionList(List<FSelectModel> val) =>
      _consultationInstitutionList.value = val;

  /// 当前的会诊机构
  String get currentConsultationInstitution =>
      _currentConsultationInstitution.value;
  set currentConsultationInstitution(String val) =>
      _currentConsultationInstitution.value = val;

  /// 筛选会诊专家列表
  List<FSelectModel> get competentExpertList => _competentExpertList.value;
  set competentExpertList(List<FSelectModel> val) =>
      _competentExpertList.value = val;

  /// 当前的会诊专家
  String get currentCompetentExpert => _currentCompetentExpert.value;
  set currentCompetentExpert(String val) => _currentCompetentExpert.value = val;

  /// 申请机构列表
  List<FSelectModel> get applicantInstitutionList =>
      _applicantInstitutionList.value;
  set applicantInstitutionList(List<FSelectModel> val) =>
      _applicantInstitutionList.value = val;

  /// 当前的申请机构
  String get currentApplicantInstitution => _currentApplicantInstitution.value;
  set currentApplicantInstitution(String val) =>
      _currentApplicantInstitution.value = val;

  /// 当前的性别
  String get currentSex => _currentSex.value;
  set currentSex(String val) => _currentSex.value = val;

  /// 当前的最小年龄
  int? get currentMinAge => _currentMinAge.value;
  set currentMinAge(int? val) => _currentMinAge.value = val;

  /// 当前的最大年龄
  int? get currentMaxAge => _currentMaxAge.value;
  set currentMaxAge(int? val) => _currentMaxAge.value = val;

  /// 当前年龄的单位
  QueryAgeUnitsEnum get currentUnit => _currentUnit.value;
  set currentUnit(QueryAgeUnitsEnum val) => _currentUnit.value = val;

  /// 当前的疾病名称
  String get currentPatientDiseases => _currentPatientDiseases.value;
  set currentPatientDiseases(String val) => _currentPatientDiseases.value = val;

  /// 当前的初步诊断
  String get currentPatientPrimaryDiagnosis =>
      _currentPatientPrimaryDiagnosis.value;
  set currentPatientPrimaryDiagnosis(String val) =>
      _currentPatientPrimaryDiagnosis.value = val;

  /// 申请分类
  List<FSelectModel> get classificationList => [
        FSelectModel(
          code: ConsultationQueryTypeEnum.All.index.toString(),
          name: i18nBook.common.all.t,
        ),
        FSelectModel(
          code: ConsultationQueryTypeEnum.MyApply.index.toString(),
          name: i18nBook.realTimeConsultation.iApplied.t,
        ),
        FSelectModel(
          code: ConsultationQueryTypeEnum.MyArrange.index.toString(),
          name: i18nBook.realTimeConsultation.iOrganized.t,
        ),
        FSelectModel(
          code: ConsultationQueryTypeEnum.MyJoin.index.toString(),
          name: i18nBook.realTimeConsultation.iInvolved.t,
        ),
      ];

  /// 会诊评价
  List<FSelectModel> get consultationEvaluationList => [
        FSelectModel(
          code: QueryEvaluateGradeEnum.All.index.toString(),
          name: i18nBook.common.all.t,
        ),
        FSelectModel(
          code: QueryEvaluateGradeEnum.UnSet.index.toString(),
          name: i18nBook.realTimeConsultation.notSet.t,
        ),
        FSelectModel(
          code: QueryEvaluateGradeEnum.Dissatisfaction.index.toString(),
          name: i18nBook.realTimeConsultation.unsatisfactory.t,
        ),
        FSelectModel(
          code: QueryEvaluateGradeEnum.General.index.toString(),
          name: i18nBook.realTimeConsultation.general.t,
        ),
        FSelectModel(
          code: QueryEvaluateGradeEnum.Satisfaction.index.toString(),
          name: i18nBook.realTimeConsultation.satisfactory.t,
        ),
      ];

  /// 会诊状态
  List<FSelectModel> get consultationStatusList => [
        FSelectModel(
          code: QueryConsultationStatusEnum.All.index.toString(),
          name: i18nBook.common.all.t,
        ),
        FSelectModel(
          code: QueryConsultationStatusEnum.Applied.index.toString(),
          name: i18nBook.user.underVerification.t,
        ),
        FSelectModel(
          code: QueryConsultationStatusEnum.Withdrawn.index.toString(),
          name: i18nBook.realTimeConsultation.withdrawn.t,
        ),
        FSelectModel(
          code: QueryConsultationStatusEnum.Rejected.index.toString(),
          name: i18nBook.realTimeConsultation.rejected.t,
        ),
        FSelectModel(
          code: QueryConsultationStatusEnum.ToStart.index.toString(),
          name: i18nBook.realTimeConsultation.toBeStarted.t,
        ),
        FSelectModel(
          code: QueryConsultationStatusEnum.InProgress.index.toString(),
          name: i18nBook.realTimeConsultation.haveInHand.t,
        ),
        FSelectModel(
          code: QueryConsultationStatusEnum.PendingReport.index.toString(),
          name: i18nBook.realTimeConsultation.toBeReported.t,
        ),
        FSelectModel(
          code: QueryConsultationStatusEnum.Expired.index.toString(),
          name: i18nBook.realTimeConsultation.expired.t,
        ),
        FSelectModel(
          code: QueryConsultationStatusEnum.End.index.toString(),
          name: i18nBook.realTimeConsultation.closed.t,
        ),
      ];

  /// 会诊筛选年龄
  List<FSelectModel> get consultationUnitList => [
        FSelectModel(
          code: QueryAgeUnitsEnum.Year.index.toString(),
          name: i18nBook.remedical.years.t,
        ),
        FSelectModel(
          code: QueryAgeUnitsEnum.Month.index.toString(),
          name: i18nBook.calendar.month.t,
        ),
        FSelectModel(
          code: QueryAgeUnitsEnum.Week.index.toString(),
          name: i18nBook.calendar.week.t,
        ),
      ];

  /// 会诊筛选性别
  List<FSelectModel> get consultationSexList => [
        FSelectModel(
          code: '',
          name: i18nBook.common.all.t,
        ),
        FSelectModel(
          code: 'Male',
          name: i18nBook.realTimeConsultation.male.t,
        ),
        FSelectModel(
          code: 'Female',
          name: i18nBook.realTimeConsultation.female.t,
        ),
      ];

  /// 同意或拒绝邀请权限
  bool get auditInvitation =>
      Store.user.hasFeature(FeatureKeys.AuditInvitation);

  /// 同意或拒绝申请权限
  bool get auditApplication =>
      Store.user.hasFeature(FeatureKeys.AuditApplication);

  /// 修改或撤回申请
  bool get updateApplyConsultation =>
      Store.user.hasFeature(FeatureKeys.UpdateApplyConsultation);

  /// 申请机构是否非当前账号机构
  bool get isCurrentOrganizationCode =>
      Store.user.rootOrganizationCode ==
      consultationsRecordInfos.applyOrganizationCode;

  /// 是否有修改权限 已撤回&已拒绝&已申请（待审核）
  bool get isModifyAuth =>
      updateApplyConsultation &&
      [
        TransactionStatusEnum.Applied,
        TransactionStatusEnum.Withdrawn,
        TransactionStatusEnum.Rejected
      ].contains(consultationsRecordInfos.consultationStatus) &&
      isCurrentOrganizationCode;

  /// 是否显示修改按钮（从后端字段判断）
  bool get isShowModifyButton =>
      consultationsRecordInfos.isUpdateConsultationShow;

  /// 是否显示撤回按钮（从后端字段判断）
  bool get isShowWithdrawButton => consultationsRecordInfos.isRevokeShow;

  /// 是否显示同意按钮（从后端字段判断）
  bool get isShowAgreeButton => consultationsRecordInfos.isApprovalShow;

  /// 是否显示拒绝按钮（从后端字段判断）
  bool get isShowRefuseButton => consultationsRecordInfos.isRejectShow;

  /// 是否显示接受邀请
  bool get isShowAcceptInvitationButton =>
      consultationsRecordInfos.isAcceptInvitationShow;

  /// 是否显示拒绝邀请
  bool get isShowRefuseInvitationButton =>
      consultationsRecordInfos.isRejectInvitationShow;

  /// 是否显示开始会诊
  bool get isShowStartConsultationButton =>
      consultationsRecordInfos.isInitiateShow;

  /// 是否显示进入会诊
  bool get isShowEnterConsultationButton =>
      consultationsRecordInfos.isJoinInShow;

  /// 是否显示撰写报告
  bool get isShowWriteReportButton => consultationsRecordInfos.isReportShow;

  bool get isEditReport => consultationsRecordInfos.isEditReportShow;

  /// 是否显示评价按钮
  bool get isShowEvaluateButton => consultationsRecordInfos.isEvaluateShow;

  /// 是否显示随访按钮
  bool get isShowFollowUpButton => consultationsRecordInfos.isFollowUpShow;

  bool get isImproveShow => consultationsRecordInfos.isImproveShow;

  /// 是否有撤回权限 已申请（待审核）
  bool get isWithdrawAuth =>
      updateApplyConsultation &&
      [
        TransactionStatusEnum.Applied,
      ].contains(consultationsRecordInfos.consultationStatus) &&
      isCurrentOrganizationCode;

  /// 是否有同意权限 已申请（待审核）
  /// 并且非申请机构
  bool get isAgreeAuth =>
      auditApplication &&
      [
        TransactionStatusEnum.Applied,
      ].contains(consultationsRecordInfos.consultationStatus) &&
      !isCurrentOrganizationCode;

  /// 是否有拒绝权限 已申请（待审核）
  /// 并且非申请机构
  bool get isRefusedAuth =>
      auditApplication &&
      [
        TransactionStatusEnum.Applied,
      ].contains(consultationsRecordInfos.consultationStatus) &&
      !isCurrentOrganizationCode;

  /// 是否作为第三方
  bool get isThirdPart => (consultationsRecordInfos.consultationMembers ?? [])
      .any((element) => element.memberCode == Store.user.code);

  /// 邀约是否为未处理状态
  bool get isDefaultStatus =>
      isShowAcceptInvitationButton && isShowRefuseInvitationButton;

  /// 如果已处理邀约，当前状态是否为已同意
  bool get isAgreeStatus => !isDefaultStatus && isShowRefuseInvitationButton;

  /// 如果已处理邀约，当前状态是否为已拒绝
  bool get isRefuseStatus => !isDefaultStatus && isShowAcceptInvitationButton;

  ///拒绝理由
  String? refuseReason;

  ///会诊描述
  String? description;

  ///拒绝理由输入框controller
  late final reasonController = TextEditingController();

  ///会诊描述输入框controller
  late final descriptionController = TextEditingController();

  ///申请信息
  ApplicationInfo applicationInfo = new ApplicationInfo();

  ///可转诊的所有机构的信息
  List<FSelectModel> organizations = [];

  ///所有可选择的参与人
  List<SimpleInfoItem> allSelectableParticipants = [];

  ///已选择的参与人员详细信息
  List<SimpleInfoItem> choosedParticipantsDetails = [];

  ///确认申请页面的助理医师名称
  String assistantPhysicianName = '';

  ///确认申请页面的会诊专家编码
  String? expertCode = '';

  ///确认申请页面的助理医师code
  String assistantPhysicianCode = '';

  ///实时会诊的图片
  Rx<List<ConsultationImagesDTO>> _realTimeConsultationImageList = Rx([]);
  List<ConsultationImagesDTO> get realTimeConsultationImageList =>
      _realTimeConsultationImageList.value;
  set realTimeConsultationImageList(List<ConsultationImagesDTO> val) =>
      _realTimeConsultationImageList.value = val;

  ///会诊随访信息
  List<FollowUpVisitDTO> followUpVisistInfoList = [];

  ///会诊评价内容
  String consultationEvaluation = "";

  ///会诊评分
  double score = 0;

  ///会诊详情
  ConsultationEvaluateDTO? consultationEvaluateDetail;

  ///评价 好/中/差
  Rx<String> _gradeDescription = Rx("");
  String get gradeDescription => _gradeDescription.value;
  set gradeDescription(String val) => _gradeDescription.value = val;

  ///差评和中评的分界线
  double bad = 1.5;

  ///中评和好评的分界线
  double good = 3.5;

  ///报告列表
  RxList<ReportDTO> _reportList = RxList([]);
  List<ReportDTO> get reportList => _reportList;
  set reportList(List<ReportDTO> val) => _reportList.value = val;
}
