import 'package:fis_common/event/event_type.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_measure/utils/prompt_box.dart';
import 'package:fis_ui/index.dart';
import 'package:flyinsono/architecture/define.dart';
import 'package:flyinsono/architecture/router/desktop/names.dart';
import 'package:flyinsono/architecture/router/router.dart';
import 'package:flyinsono/architecture/services/entity/local_setting.dart';
import 'package:flyinsono/architecture/services/modules/hardware_setting_configuration.dart';
import 'package:flyinsono/architecture/states/states.dart';
import 'package:flyinsono/managers/interfaces/entities/live_consultation.dart';
import 'package:flyinsono/managers/interfaces/live_consultation.dart';
import 'package:flyinsono/rpc.dart';
import 'package:flyinsono/utils/utc_dateTime_converter.dart';
import 'package:flyinsono/views/desktop/real_time_consultation/live_consultation/controller.dart';
import 'package:get/get.dart';
import 'package:universal_html/html.dart' as html;
import 'interfaces/appointment_consultation.dart';
import 'interfaces/entities/patient_Info.dart';
import 'interfaces/permission.dart';
import 'interfaces/remedical.dart';

class AppointmentConsultationManager implements IAppointmentConsultation {
  final onDataChange = FEventHandler<bool>();

  /// 手机端添加申请人 取消事件通知
  final FEventHandler<bool> onCancelAddedParticipant = FEventHandler<bool>();

  ///打开会诊直播间
  @override
  Future<void> startConsultation(String consultationCode,
      {bool isJoin = false, int pageIndex = 1}) async {
    try {
      final liveConsultationManager = Get.find<ILiveConsultationManager>();
      var consulationInfo = await liveConsultationManager
          .findConsultationDetailAsync(consultationCode);
      if (consulationInfo == null) {
        return;
      }
      var expertUserCode = consulationInfo.expertUserCode;
      LiveConsultation? liveConsultation;
      if (isJoin) {
        liveConsultation = await liveConsultationManager
            .joinInLiveConsultationAsync(consultationCode, checkOnly: true);
      } else if (consulationInfo.isEmergency &&
          consulationInfo.applyUserCode != Store.user.code) {
        liveConsultation = await liveConsultationManager
            .acceptLiveConsultationAsync(consultationCode, checkOnly: true);
      } else if (expertUserCode == Store.user.code ||
          (consulationInfo.isEmergency &&
              consulationInfo.applyUserCode == Store.user.code)) {
        liveConsultation = await liveConsultationManager
            .initiateLiveConsultationAsync(consultationCode, checkOnly: true);
      } else {
        liveConsultation = await liveConsultationManager
            .acceptLiveConsultationAsync(consultationCode, checkOnly: true);
      }
    } catch (e) {
      logger.e('AppointmentConsultationManager checkConsultation ex:', e);
      return;
    }
    if ((FPlatform.isMacOS || FPlatform.isWindows) &&
        !CartSystemPlatform.isCartSystemVersion &&
        LocalSetting.ins.isUseSecondWindow!) {
      await Get.find<HardwareSettingService>().syncToShell();
      await rpc.platform.openLiveConsultationAsync(
          consultationCode, isJoin, pageIndex, Store.user.token);
    } else if (FPlatform.isPureWeb &&
        // !kDebugMode &&
        LocalSetting.ins.isUseSecondWindow!) {
      final url = html.window.location.origin;
      html.window.open(
          '$url/index.html?page=${LiveConsultationController.pageName}&consultationCode=$consultationCode&isJoin=$isJoin&pageIndex=$pageIndex&token=${Store.user.token}',
          '');
    } else {
      var checkPermission =
          await Get.find<IPermissionManager>().checkMediaPermission();
      if (checkPermission) {
        router.to(
          RouteNames.RealTimeRemedical.LiveConsultation,

          ///SP60全屏显示 id为null
          id: (kIsMobile ||
                  CartSystemPlatform.isCartSystemVersion ||
                  !LocalSetting.ins.isUseSecondWindow!)
              ? null
              : NavIds.HOME,
          parameters: {
            "consultationCode": consultationCode,
            "pageIndex": pageIndex.toString(),
            "isJoin": isJoin.toString(),
          },
        );
      }
    }
  }

  ///会诊页打开报告编辑页面
  @override
  void openReportEdit(String consultationCode, String patientCode) {
    var token = Store.user.token;
    if ((FPlatform.isWindows || FPlatform.isMacOS) &&
        LocalSetting.ins.isUseSecondWindow!) {
      router.back();
      rpc.platform.openReportEditAsync(
        token,
        patientCode,
        '',
        '',
        '',
        consultationCode,
      );
      return;
    } else if (FPlatform.isPureWeb && LocalSetting.ins.isUseSecondWindow!) {
      final url = html.window.location.origin;
      var empty = '';
      var languageCode = i18nBook.locale.toCodeString("-");
      router.back();
      html.window.open(
          '$url/index.html?page=report&patientCode=$patientCode&token=$token&reportCode=$empty&recordCode=$empty&referralRecordCode=$empty&consultationCode=$consultationCode&lagCode=$languageCode',
          '');

      return;
    }
    router.back();
    Map<String, String> arguments = {
      'token': token,
      'consultationCode': consultationCode,
      'patientCode': patientCode,
    };

    router.to(
      RouteNames.Remedical.ReportEdit,
      id: NavIds.HOME,
      parameters: arguments,
    );
  }

  ///添加随访信息
  @override
  Future<bool> addFollowUpVisitInfo(String? phone, String patientName,
      String currentConsultationCode, String? visitRecord) async {
    try {
      var addFollowUpVisitInfoRequest = AddFollowUpVisitInfoRequest();
      addFollowUpVisitInfoRequest.token = Store.user.token;
      addFollowUpVisitInfoRequest.consultationRecordCode =
          currentConsultationCode;
      addFollowUpVisitInfoRequest.occurredTime = DateTime.now();
      addFollowUpVisitInfoRequest.generalCase = visitRecord;
      var result = await rpc.liveConsultation
          .addFollowUpVisitInfoAsync(addFollowUpVisitInfoRequest);
      return result;
    } catch (e) {
      logger.e('AppointmentConsultationManager addFollowUpVisitInfo ex:' +
          e.toString());
    }
    return false;
  }

  ///获取会诊随访信息
  Future<List<FollowUpVisitDTO>> getFollowUpVisitInfo(
      String currentConsultationCode) async {
    try {
      var result = await rpc.liveConsultation.getFollowUpVisitInfoAsync(
        GetFollowUpVisitInfoRequest(
          token: Store.user.token,
          consultationRecordCode: currentConsultationCode,
        ),
      );
      return result;
    } catch (e) {
      logger.e('RealTimeConsultationVisitController getFollowUpVisitInfo ex:' +
          e.toString());
      return [];
    }
  }

  @override
  Future<bool> addConsultationEvaluateAsync(
      String consultationCode, double evaluateScore, String feedback) async {
    try {
      var result = await rpc.liveConsultation
          .addConsultationEvaluateAsync(AddConsultationEvaluateRequest(
        consultationRecordCode: consultationCode,
        evaluateScore: evaluateScore,
        feedback: feedback,
        token: Store.user.token,
      ));
      if (result) {
        PromptBox.toast(i18nBook.remedical.submitSuccess.t);
        router.back();
      }
      return result;
    } catch (e) {
      logger.e('AppointmentConsultationManager addEvaluationInfo ex:', e);
    }
    return false;
  }

  ///获取会诊评价详情
  Future<ConsultationEvaluateDTO?> getEvaluationInfo(
      String consultationCode) async {
    try {
      var result =
          await rpc.liveConsultation.getConsultationEvaluateDetailAsync(
        GetConsultationEvaluateRequest(
          token: Store.user.token,
          consultationRecordCode: consultationCode,
        ),
      );
      return result;
    } catch (e) {
      logger.e('AppointmentConsultationManager getEvaluationInfo ex:', e);
    }
    return null;
  }

  ///获取会诊图像
  @override
  Future<List<ConsultationImagesDTO>> getConsultationImages(
      String consultationCode) async {
    try {
      if (consultationCode.isEmpty) {
        return [];
      }
      var realTimeConsultationImageList =
          await rpc.liveConsultation.getConsultationFilesAsync(
        FindConsultationDetailRequest(
            consultationCode: consultationCode, token: Store.user.token),
      );
      return realTimeConsultationImageList;
    } catch (e) {
      logger.e('RealTimeConsultationImageController getConsultationImages ex:' +
          e.toString());
    }
    return [];
  }

  //分页查询会诊记录
  @override
  Future<PageResult<ConsultationPageDTO>> findConsultationsByPageAsync(
    ConsultationQueryTypeEnum consultationQueryType,
    int pageIndex,
    int pageSize, {
    String? keyword,
    DateTime? startDate,
    DateTime? endDate,
    QueryConsultationStatusEnum? consultationStatus,
    QueryEvaluateGradeEnum? evaluateGrade,
    String? language,
    List<String>? expertCodes,
    List<String>? applyOrganizationCodes,
    List<String>? expertOrganizationCodes,
    String? patientSex,
    String? patientDiseases,
    String? patientPrimaryDiagnosis,
    QueryPatientAgeLimitDTO? patientAgeLimit,
  }) async {
    return await rpc.liveConsultation.findConsultationsByPageAsync(
      FindConsultationByPageRequest(
        token: Store.user.token,
        pageIndex: pageIndex,
        pageSize: pageSize,
        consultationQueryType: consultationQueryType,
        keyword: keyword,
        startDate: UtcDateConverter.getDayStartOrEndUTCTime(startDate),
        endDate: UtcDateConverter.getDayStartOrEndUTCTime(endDate, isEnd: true),
        language: language,
        expertCodes: expertCodes,
        patientSex: patientSex,
        patientAgeLimit: patientAgeLimit,
        patientDiseases: patientDiseases,
        patientPrimaryDiagnosis: patientPrimaryDiagnosis,
        applyOrganizationCodes: applyOrganizationCodes,
        expertOrganizationCodes: expertOrganizationCodes,
        consultationStatus:
            consultationStatus ?? QueryConsultationStatusEnum.All,
        evaluateGrade: evaluateGrade ?? QueryEvaluateGradeEnum.All,
      ),
    );
  }

  //根据会诊单号查询会诊中可直接切换的会诊单列表
  Future<List<ConsultationPageDTO>> findCanSwitchConsultationsAsync(
      String consultationCode) async {
    var rpcRst = await rpc.liveConsultation.findCanSwitchConsultationsAsync(
      FindCanSwitchConsultationsRequest(
        consultationCode: consultationCode,
        language: i18nBook.locale.toCodeString('-'),
        token: Store.user.token,
      ),
    );

    return rpcRst;
  }

  //分页查询会诊记录
  @override
  Future<ExportConsultationDataResult> exportConsultationsAsync(
    ConsultationQueryTypeEnum consultationQueryType, {
    String? keyword,
    DateTime? startDate,
    DateTime? endDate,
    QueryConsultationStatusEnum? consultationStatus,
    QueryEvaluateGradeEnum? evaluateGrade,
    String? language,
    List<String>? expertCodes,
    List<String>? applyOrganizationCodes,
    List<String>? expertOrganizationCodes,
    String? patientSex,
    String? patientDiseases,
    String? patientPrimaryDiagnosis,
    QueryPatientAgeLimitDTO? patientAgeLimit,
    bool? isExportConsultation = false,
    bool? isExportConsultationFileData = false,
    bool? isExportReport = false,
  }) async {
    return await rpc.liveConsultation.exportConsultationsAsync(
      ExportConsultationsRequest(
        token: Store.user.token,
        consultationQueryType: consultationQueryType,
        keyword: keyword,
        startDate: startDate,
        endDate: endDate,
        language: language,
        expertCodes: expertCodes,
        patientSex: patientSex,
        patientAgeLimit: patientAgeLimit,
        patientDiseases: patientDiseases,
        patientPrimaryDiagnosis: patientPrimaryDiagnosis,
        applyOrganizationCodes: applyOrganizationCodes,
        expertOrganizationCodes: expertOrganizationCodes,
        isExportConsultation: isExportConsultation!,
        isExportConsultationFileData: isExportConsultationFileData!,
        isExportReport: isExportReport!,
        consultationStatus:
            consultationStatus ?? QueryConsultationStatusEnum.All,
        evaluateGrade: evaluateGrade ?? QueryEvaluateGradeEnum.All,
      ),
    );
  }

  @override
  Future<bool> startEmergencyConsultation(
    String selectedUser,
    String selectedDevice,
    String deviceCode,
    PatientInfo? patientInfo,
  ) async {
    try {
      List<DataItemDTO>? patientDatas;
      if (patientInfo != null) {
        ///急诊不需要年龄这个单位
        patientInfo.ageUnits = "";
        patientDatas = Get.find<IRemedicalManager>()
            .convertPatientInfoToPatientDatas(patientInfo);
      }
      var consultationId = await rpc.liveConsultation.applyEmergencyTreatment(
        ApplyEmergencyTreatmentRequest(
          token: Store.user.token,
          expertCode: selectedUser,
          deviceCode: deviceCode,
          patientDatas: patientDatas,
          patientCode: patientInfo?.patientCode ?? '',
        ),
      );
      if (consultationId.isNotEmpty) {
        startConsultation(consultationId);
        return true;
      }
    } catch (e) {
      logger.e(
          'RealTimeConsultationListController startEmergencyConsultation', e);
    }
    return false;
  }
}
