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/router/router.dart';
import 'package:flyinsono/architecture/states/states.dart';
import 'package:flyinsono/architecture/utils/prompt_box.dart';
import 'package:flyinsono/managers/interfaces/appointment_consultation.dart';
import 'package:flyinsono/managers/interfaces/entities/patient_Info.dart';
import 'package:flyinsono/managers/interfaces/language.dart';
import 'package:flyinsono/pages/schedule/calendar/calendar_page/detail_dialog/schedule_detail_dialog.dart';
import 'package:flyinsono/pages/schedule/schedule_notification/schedule_notification_binding.dart';
import 'package:flyinsono/rpc.dart';
import 'package:flyinsono/utils/export_status_type.dart';
import 'package:flyinsono/views/desktop/index.dart';
import 'package:flyinsono/views/desktop/real_time_consultation/state.dart';
import 'package:get/get.dart';

import 'real_time_consultation_controller.dart';

class RealTimeConsultationListController {
  static const pageSize = 20;
  RealTimeConsultationController controller;
  late final RealTimeConsultationState state;
  final appointmentConsultationManager = Get.find<IAppointmentConsultation>();
  RealTimeConsultationListController(this.controller) {
    this.state = controller.state;
  }

  /// 导出
  Future<ExportConsultationDataResult> exportConsultationsAsync({
    bool? isExportConsultation,
    bool? isExportConsultationFileData,
    bool? isExportReport,
  }) async {
    List<String> expertCodes = state.currentCompetentExpert.isEmpty
        ? []
        : [state.currentCompetentExpert];
    List<String> applyOrganizationCodes =
        state.currentApplicantInstitution.isEmpty
            ? []
            : [state.currentApplicantInstitution];
    List<String> expertOrganizationCodes =
        state.currentConsultationInstitution.isEmpty
            ? []
            : [state.currentConsultationInstitution];
    final result =
        await appointmentConsultationManager.exportConsultationsAsync(
      state.consultationQueryType!,
      keyword: state.keyWord,
      startDate:
          state.startDate == null ? null : DateTime.parse(state.startDate!),
      endDate: state.endDate == null ? null : DateTime.parse(state.endDate!),
      consultationStatus: state.consultationStatus,
      evaluateGrade: state.consultationEvaluationType,
      expertCodes: expertCodes,
      applyOrganizationCodes: applyOrganizationCodes,
      expertOrganizationCodes: expertOrganizationCodes,
      patientSex: state.currentSex,
      patientAgeLimit: QueryPatientAgeLimitDTO(
        minAge: state.currentMinAge ?? 0,
        maxAge: state.currentMaxAge ?? 0,
        unit: state.currentUnit,
      ),
      patientDiseases: state.currentPatientDiseases,
      patientPrimaryDiagnosis: state.currentPatientPrimaryDiagnosis,
      isExportConsultation: isExportConsultation,
      isExportConsultationFileData: isExportConsultationFileData,
      isExportReport: isExportReport,
    );
    final languageConfigManager = Get.find<ILanguageConfigManager>();
    for (ConsultationExportData i in result.consultationList ?? []) {
      for (ConsultationItem j in i.consultationItemList ?? []) {
        List<String> scanPositions = [];
        j.scanPositions?.forEach((element) {
          scanPositions
              .add(languageConfigManager.getConsultationLanguageValue(element));
        });
        j.scanPositions = scanPositions;
      }
    }
    return result;
  }

  void filterConsultationInstitution(String value) {
    state.currentConsultationInstitution = value;

    /// 会诊专家是根据会诊机构走的
    state.currentCompetentExpert = '';
    findOrganizationExpertsAsync();
  }

  /// 会诊记录列表
  Future<void> findConsultationsByPageAsync() async {
    try {
      controller.busy = true;
      if (!onFilterDateComparison()) {
        return;
      }
      List<String> expertCodes = state.currentCompetentExpert.isEmpty
          ? []
          : [state.currentCompetentExpert];
      List<String> applyOrganizationCodes =
          state.currentApplicantInstitution.isEmpty
              ? []
              : [state.currentApplicantInstitution];
      List<String> expertOrganizationCodes =
          state.currentConsultationInstitution.isEmpty
              ? []
              : [state.currentConsultationInstitution];
      final result =
          await appointmentConsultationManager.findConsultationsByPageAsync(
        state.consultationQueryType!,
        state.pageIndex,
        pageSize,
        keyword: state.keyWord,
        startDate:
            state.startDate == null ? null : DateTime.parse(state.startDate!),
        endDate: state.endDate == null ? null : DateTime.parse(state.endDate!),
        consultationStatus: state.consultationStatus,
        evaluateGrade: state.consultationEvaluationType,
        expertCodes: expertCodes,
        applyOrganizationCodes: applyOrganizationCodes,
        expertOrganizationCodes: expertOrganizationCodes,
        patientSex: state.currentSex,
        patientAgeLimit: QueryPatientAgeLimitDTO(
          minAge: state.currentMinAge ?? 0,
          maxAge: state.currentMaxAge ?? 0,
          unit: state.currentUnit,
        ),
        language: i18nBook.locale.toCodeString('-'),
        patientDiseases: state.currentPatientDiseases,
        patientPrimaryDiagnosis: state.currentPatientPrimaryDiagnosis,
      );
      final List<ConsultationPageDTO> resultPageData = result.pageData ?? [];
      List<ConsultationsRecordCard> consultationsRecordCardList = [];
      for (int i = 0; i < resultPageData.length; i++) {
        consultationsRecordCardList.add(
          ConsultationsRecordCard(
            consultationCode: resultPageData[i].consultationCode ?? '',
            patientName: resultPageData[i].patientName ?? '',
            sex: resultPageData[i].sex,
            age: resultPageData[i].patientAge,
            phone: resultPageData[i].phone,
            applyOrganizationName: resultPageData[i].applyOrganizationName,
            state: resultPageData[i].consultationStatus,
            consultationTime: resultPageData[i].consultationTime?.toLocal(),
            consultationTimeEnd:
                resultPageData[i].consultationTimeEnd?.toLocal(),
            expertUserName:
                resultPageData[i].expertUserName ?? i18nBook.homePage.notYet.t,
            consultationEvaluate: resultPageData[i].consultationEvaluate,
          ),
        );
      }
      state.consultationsRecordCardList = consultationsRecordCardList;

      /// 【如果初始化不存在初始值】默认列表第一个
      if (consultationsRecordCardList.isNotEmpty &&
          controller.initConsultationCode == null) {
        state.currentConsultationCode =
            consultationsRecordCardList[0].consultationCode;
        controller.findConsultationDetailAsync();
        state.totalCount = result.totalCount;
      } else {
        /// 分页数据总数置空
        state.totalCount = 0;
      }
    } catch (e) {
      printError(info: "findConsultationsByPageAsync exception:$e");
      logger.e("findConsultationsByPageAsync exception:", e);
      PromptBox.toast(i18nBook.errorCodes.errorCodeUN.t);
    }
    controller.busy = false;
  }

  /// 获取申请机构列表
  Future<void> findGrassRootsOrganizationsAsync() async {
    try {
      final result =
          await rpc.liveConsultation.findGrassRootsOrganizationsAsync(
        FindGrassRootsOrganizationsRequest(
          token: Store.user.token,
        ),
      );
      List<FSelectModel> applicantInstitutionList = [];
      for (int i = 0; i < result.length; i++) {
        applicantInstitutionList.add(
          FSelectModel(
            name: result[i].organizationName ?? '',
            code: result[i].organizationCode ?? '',
          ),
        );
      }
      applicantInstitutionList.insert(
          0, FSelectModel(name: i18nBook.common.all.t, code: ''));
      state.applicantInstitutionList = applicantInstitutionList;
    } catch (e) {
      printError(info: "findGrassRootsOrganizationsAsync exception:$e");
      logger.e("findGrassRootsOrganizationsAsync exception:", e);
      controller.busy = false;
    }
  }

  /// 获取会诊专家
  Future<void> findOrganizationExpertsAsync() async {
    try {
      final result = await rpc.liveConsultation.findOrganizationExpertsAsync(
        FindOrganizationExpertsRequest(
          token: Store.user.token,
          organizationCode: state.currentConsultationInstitution,
          pageIndex: 1,
          pageSize: 100,
        ),
      );
      var pageData = result.pageData ?? [];
      List<FSelectModel> competentExpertList = [];
      for (int i = 0; i < pageData.length; i++) {
        competentExpertList.add(
          FSelectModel(
            name: pageData[i].displayName!,
            code: pageData[i].userCode ?? '',
          ),
        );
      }
      competentExpertList.insert(
          0, FSelectModel(name: i18nBook.common.all.t, code: ''));
      state.competentExpertList = competentExpertList;
    } catch (e) {
      printError(info: "findOrganizationExpertsAsync exception:$e");
      logger.e("findOrganizationExpertsAsync exception:", e);
      controller.busy = false;
    }
  }

  /// 获取会诊机构
  Future<void> findParentOrganizationsAsync() async {
    try {
      final result = await rpc.liveConsultation.findParentOrganizationsAsync(
        FindHigherOrganizationsRequest(
          token: Store.user.token,
        ),
      );
      List<FSelectModel> consultationInstitutionList = [];
      for (int i = 0; i < result.length; i++) {
        consultationInstitutionList.add(
          FSelectModel(
            name: result[i].organizationName ?? '',
            code: result[i].organizationCode ?? '',
          ),
        );
      }

      consultationInstitutionList.insert(
          0, FSelectModel(name: i18nBook.common.all.t, code: ''));
      state.consultationInstitutionList = consultationInstitutionList;
    } catch (e) {
      printError(info: "findParentOrganizationsAsync exception:$e");
      logger.e("findParentOrganizationsAsync exception:", e);
      controller.busy = false;
    }
  }

  /// 进度条
  void handleProgressChanged(progress, exportState) {
    var exportStatInt = int.parse(exportState);
    state.exportState = ExportStatusType.values[exportStatInt];
    if (state.exportState == ExportStatusType.Finished) {
      state.isExporting = false;
      logger.e(
          "RealTimeConsultationListController handleProgressChanged exportState:${state.exportState}");
    }
    state.exportProgress = (double.parse(progress)).toPrecision(2);
  }

  /// 校验表格时间筛选 开始时间不能大于结束时间
  bool onFilterDateComparison() {
    if (state.startDate != null && state.endDate != null) {
      DateTime startDate = DateTime.parse(state.startDate!);
      DateTime endDate = DateTime.parse(state.endDate!);
      if (startDate.isAfter(endDate)) {
        PromptBox.toast(i18nBook.errorCodes.errorCode4022.t);
        return false;
      }
    } else if ((state.currentMinAge != null && state.currentMaxAge != null) &&
        state.currentMinAge! > state.currentMaxAge!) {
      PromptBox.toast(i18nBook.realTimeConsultation.errorFilteringAge.t);
      return false;
    }
    return true;
  }

  /// 表格单行点击事件
  Future<void> onTableRowClick(int index) async {
    var consultationCode =
        state.consultationsRecordCardList[index].consultationCode;
    state.currentConsultationCode = consultationCode;

    ///获取会诊详情
    await controller.findConsultationDetailAsync();

    ///获取报告信息
    await controller.reportController.getReportInfoAsync();

    ///获取随访信息
    await controller.visitController.getFollowUpVisitInfo();

    /// 详情页面弹框
    await router.dialog(
      () => ScheduleDetailDialog(
        isDetailDialog: false,
      ),
      transitionDuration: Duration(milliseconds: 500),
      transitionCurve: Curves.easeInOut,
      binding: ScheduleNotificationBinding(
        consultationCode: state.currentConsultationCode,
      ),
    );
    controller.listController.findConsultationsByPageAsync();
    state.selectIndex = 0;
  }

  ///开启急诊
  Future<bool> startEmergencyConsultation(
      String selectedUser,
      String selectedDevice,
      String deviceCode,
      PatientInfo? patientInfo) async {
    return appointmentConsultationManager.startEmergencyConsultation(
      selectedUser,
      selectedDevice,
      deviceCode,
      patientInfo,
    );
  }
}
