import 'package:fis_common/event/event_type.dart';
import 'package:fis_common/helpers/encrypt.dart';
import 'package:fis_common/env/env.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:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flyinsono/architecture/states/states.dart';
import 'package:flyinsono/managers/interfaces/appointment_consultation.dart';
import 'package:flyinsono/managers/interfaces/entities/patient_Info.dart';
import 'package:flyinsono/managers/interfaces/entities/report_element_info.dart';
import 'package:flyinsono/managers/interfaces/report.dart';
import 'package:flyinsono/managers/interfaces/live_consultation.dart';
import 'package:flyinsono/pages/consultation/widgets/consultation_images_view.dart';
import 'package:flyinsono/pages/consultation/widgets/mobile_add_follow_up_page.dart';
import 'package:flyinsono/pages/consultation/widgets/mobile_follow_up_page.dart';
import 'package:fis_measure/process/workspace/rpc_bridge.dart';

import 'package:flyinsono/pages/remedical/consultation/widgets/exam_images_view.dart';
import 'package:flyinsono/pages/remedical/consultation/widgets/report/write_report.dart';
import 'package:flyinsono/pages/remedical/report/report_edit/widgets/consultation_image_view.dart';
import 'package:flyinsono/rpc.dart';
import 'package:flyinsono/views/desktop/index.dart';
import 'package:get/get.dart';

import '../../architecture/router/index.dart';
import 'index.dart';
import 'widgets/consultation_report_card.dart';
import 'widgets/evaluation_page.dart';

class MobileConsultationController extends GetxController {
  /// 焦点控制器
  final searchFocusNode = FocusNode();

  /// 输入框文本控制器
  final TextEditingController serachInput = TextEditingController();

  /// 滑动控制器
  final patientCardScrollController = ScrollController();

  final state = FConsultationState();

  ///每页会诊单数量
  final int _pageSize = 20;

  final evaluationController = TextEditingController();
  final followUpController = TextEditingController();
  final TextEditingController desController = TextEditingController();
  final TextEditingController consualationController = TextEditingController();
  final FEventHandler<List<String>> onSelectedImages =
      FEventHandler<List<String>>();
  final reportManager = Get.find<IReportManager>();
  final appointmentConsultationManager = Get.find<IAppointmentConsultation>();

  ///当前页数
  int _pageIndex = 1;

  ///总数
  int _totalCount = 0;

  final ScrollController reportController = ScrollController();

  late final String _defaultTemplate;

  /// 在 widget 内存中分配后立即调用。
  @override
  void onInit() {
    super.onInit();
    _initTemplate();
    reportManager.initFluwx();
    _initConsultations();
    _addListener();
  }

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

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

  /// dispose 释放内存
  @override
  void dispose() {
    super.dispose();
    RPCBridge.ins.source = VidImageSource.Remedical;
  }

  ///跟据关键字获取会诊列表
  Future<void> getConsultations() async {
    final consultationDatas =
        await appointmentConsultationManager.findConsultationsByPageAsync(
      ConsultationQueryTypeEnum.All,
      _pageIndex,
      _pageSize,
      keyword: serachInput.text,
      language: i18nBook.locale.toCodeString('-'),
      startDate: DateTime(1970, 01, 01),
      endDate: DateTime.now(),
    );
    state.consultationsRecordCardList.clear();
    _addConsultationDatas(consultationDatas.pageData ?? []);
  }

  ///刷新列表
  void refreshConsultation() {
    state.consultationsRecordCardList.clear();
    _initConsultations();
  }

  ///跟据枚举获取状态
  String getConsultationState(TransactionStatusEnum? state) {
    if (state == null) {
      return '';
    }
    switch (state) {
      case TransactionStatusEnum.placeHolder_0:
        return '';
      case TransactionStatusEnum.Applied:
        return i18nBook.user.underVerification.t;
      case TransactionStatusEnum.Withdrawn:
        return i18nBook.realTimeConsultation.withdraw.t;
      case TransactionStatusEnum.Rejected:
        return i18nBook.realTimeConsultation.rejected.t;
      case TransactionStatusEnum.ToStart:
        return i18nBook.realTimeConsultation.toBeStarted.t;
      case TransactionStatusEnum.InProgress:
        return i18nBook.realTimeConsultation.haveInHand.t;
      case TransactionStatusEnum.PendingReport:
        return i18nBook.realTimeConsultation.toBeReported.t;
      case TransactionStatusEnum.End:
        return i18nBook.realTimeConsultation.closed.t;
      case TransactionStatusEnum.Expired:
        return i18nBook.realTimeConsultation.expired.t;
      default:
        return '';
    }
  }

  void setEvaluateScore(double score) {
    state.score = score;
    if (score <= state.bad) {
      state.gradeDescription = i18nBook.realTimeConsultation.negative.t;
    } else if (score > state.bad && score <= state.good) {
      state.gradeDescription = i18nBook.realTimeConsultation.medium.t;
    } else if (score > state.good) {
      state.gradeDescription = i18nBook.realTimeConsultation.good.t;
    }
  }

  ///提交会诊评价
  Future<void> submitEvaluateDetail() async {
    if (state.score == 0) {
      PromptBox.toast(
          i18nBook.realTimeConsultation.requiredItemsNotCompleted.t);
      return;
    }
    await appointmentConsultationManager.addConsultationEvaluateAsync(
      state.currentConsultation.consultationCode,
      state.score,
      evaluationController.text,
    );
  }

  ///获取会诊评价详情
  Future<void> getEvaluationInfo() async {
    state.consultationEvaluateDetail = await appointmentConsultationManager
        .getEvaluationInfo(state.currentConsultation.consultationCode);
    if (state.consultationEvaluateDetail != null) {
      evaluationController.text =
          state.consultationEvaluateDetail!.feedback ?? '';
    }
  }

  /// 点击进入会诊详情页
  void openConsultationDetail(String consultationCode) async {
    try {
      await router.to(MobileRouteNames.RealTimeRemedical.ConsultationDetail,
          parameters: {
            'consultationCode': consultationCode,
          });
    } catch (e) {
      logger.e("openEditInit exception:", e);
      printError(info: e.toString());
    }
  }

  Future<void> _initConsultations() async {
    final consultationDatas =
        await appointmentConsultationManager.findConsultationsByPageAsync(
      ConsultationQueryTypeEnum.All,
      _pageIndex,
      _pageSize,
      language: i18nBook.locale.toCodeString('-'),
    );
    _totalCount = consultationDatas.totalCount;
    _addConsultationDatas(consultationDatas.pageData ?? []);
  }

  void _addListener() {
    patientCardScrollController.addListener(() async {
      try {
        if (patientCardScrollController.offset >=
                patientCardScrollController.position.maxScrollExtent &&
            !patientCardScrollController.position.outOfRange) {
          if (_pageIndex * _pageSize >= _totalCount) {
            return;
          }
          _pageIndex++;
          final consultationDatas =
              await appointmentConsultationManager.findConsultationsByPageAsync(
                  ConsultationQueryTypeEnum.All, _pageIndex, _pageSize);
          _addConsultationDatas(consultationDatas.pageData ?? []);
        }
      } catch (e) {}
    });
  }

  void _addConsultationDatas(List<ConsultationPageDTO> pageDatas) {
    var consultationsRecordCardList = pageDatas.map((e) {
      return ConsultationsRecordCard(
        consultationCode: e.consultationCode ?? '',
        patientName: e.patientName,
        applyOrganizationName: e.applyOrganizationName,
        sex: e.sex,
        age: e.patientAge,
        state: e.consultationStatus,
        consultationTime: e.consultationTime,
        consultationTimeEnd: e.consultationTimeEnd,
      );
    }).toList();
    state.consultationsRecordCardList.addAll(consultationsRecordCardList);
  }

  ///评价
  Future<void> onTapEvaluation(int index) async {
    state.currentIndex = index;
    await _findConsultationDetailAsync();
    var currentConsultationDetail = state.currentConsultationDetail;
    if ((currentConsultationDetail != null &&
            currentConsultationDetail.isEvaluateShow) ||
        currentConsultationDetail?.consultationStatus ==
            TransactionStatusEnum.End) {
      await getEvaluationInfo();
      if (state.consultationEvaluateDetail == null &&
          !(currentConsultationDetail?.isEvaluateShow ?? true)) {
        PromptBox.toast(i18nBook.errorCodes.errorCode4001.t);
        return;
      }
      await Get.to(
        () => EvaluationPage(
          consultationDetail: currentConsultationDetail,
        ),
      );
      evaluationController.text = '';
    } else {
      PromptBox.toast(i18nBook.realTimeConsultation.noAppraise.t);
    }
  }

  ///随访
  Future<void> onTapFollowUp(int index) async {
    state.currentIndex = index;
    await _findConsultationDetailAsync();
    var currentConsultationDetail = state.currentConsultationDetail;
    if (currentConsultationDetail == null) {
      return;
    }
    if (currentConsultationDetail.consultationStatus !=
            TransactionStatusEnum.End ||
        !currentConsultationDetail.isFollowUpShow) {
      PromptBox.toast(i18nBook.errorCodes.errorCode4001.t);
    } else {
      await getFollowUpVisitInfo();
      await Get.to(() => MobileFollowUpPage());
      followUpController.text = '';
      state.currentFollowUpIndex = 0;
    }
  }

  /// 新建随访
  Future<void> onTapNewFollowUp() async {
    await Get.to(() => AddFollowUpPage());
  }

  ///会诊图像查看
  Future<void> onTapConsultationImages() async {
    await getConsultationImages();
    if (state.currentConsultationImages.isEmpty) {
      PromptBox.toast(i18nBook.common.noImageInfo.t);
    } else {
      Get.to(() => ConsultationImagesView());
    }
  }

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

  ///获取会诊随访信息
  Future<List<FollowUpVisitDTO>> getFollowUpVisitInfo() async {
    state.followUpVisistInfoList = await appointmentConsultationManager
        .getFollowUpVisitInfo(state.currentConsultation.consultationCode);
    state.isFollowUpInfoListEmpty = state.followUpVisistInfoList.isEmpty;
    return state.followUpVisistInfoList;
  }

  ///提交随访信息
  Future<void> submitFollowUp(String? phone, String name) async {
    if (followUpController.text.isEmpty) {
      PromptBox.toast(i18nBook.realTimeConsultation.pleaseWriteFollowUp.t);
      return;
    }
    if (followUpController.text.replaceAll(' ', '').isEmpty) {
      PromptBox.toast(i18nBook.realTimeConsultation.pleaseWriteFollowUp.t);
      followUpController.text = '';
      return;
    }
    var result = await appointmentConsultationManager.addFollowUpVisitInfo(
      phone,
      name,
      state.currentConsultation.consultationCode,
      followUpController.text,
    );
    if (result) {
      PromptBox.toast(i18nBook.remedical.submitSuccess.t);
    }
    await getFollowUpVisitInfo();
    state.currentFollowUpIndex = state.followUpVisistInfoList.length - 1;
    state.isFollowUpInfoListEmpty = state.followUpVisistInfoList.isEmpty;

    /// 返回上一级
    router.back();
  }

  ///获取会诊图像
  Future<void> getConsultationImages() async {
    try {
      state.currentConsultationImages = await appointmentConsultationManager
          .getConsultationImages(state.currentConsultation.consultationCode);
    } catch (e) {
      logger.e('RealTimeConsultationImageController getConsultationImages ex:' +
          e.toString());
    }
  }

  Future<void> onTapConsultationImage(ConsultationFileDTO imageInfo) async {
    // 手机强制横屏
    if (FPlatform.isIOS || FPlatform.isAndroid) {
      SystemChrome.setPreferredOrientations(
          [DeviceOrientation.landscapeLeft, DeviceOrientation.landscapeRight]);
    }
    await Get.to(() => ConsultationImagePage(imageInfo));
    // 强制竖屏
    SystemChrome.setPreferredOrientations(
        [DeviceOrientation.portraitUp, DeviceOrientation.portraitDown]);
  }

  Future<void> onTapCloudImage(RemedicalInfoDTO imageInfo) async {
    await _findConsultationDetailAsync();
    RPCBridge.ins.source = VidImageSource.Consultation;
    router.to(
      RouteNames.Remedical.Measure,
      parameters: {
        "patientCode": state.currentConsultationDetail?.patientCode ?? '',
        "remedicalCode": imageInfo.remedicalCode ?? '',
        "recordCode": state.currentConsultation.consultationCode,
      },
    );
  }

  Future<void> findReportByCodeAsync() async {
    state.reportInfo =
        await reportManager.findReportByCodeAsync(state.reportCode);
  }

  Future<void> onTabReport() async {
    await _findConsultationDetailAsync();
    var currentConsultationDetail = state.currentConsultationDetail;
    state.reportList = await reportManager
        .findReportsAsync(state.currentConsultation.consultationCode);
    if (state.reportList.isNotEmpty) {
      state.reportCode = state.reportList.first.reportCode ?? '';
      await findReportByCodeAsync();
      await Get.to(() => ConsultationReportCards());
    } else if (currentConsultationDetail != null &&
        currentConsultationDetail.isReportShow) {
      await Get.to(
        () => WriteReport(
          isNew: false,
          selectedRemedicalImages: state.selectedImages,
          onSubmit: _onsubmit,
          onRemoveImage: (image) {
            if (state.selectedImages.contains(image)) {
              state.selectedImages.remove(image);
            }
          },
          conTextController: consualationController,
          desTextController: desController,
          onTapSelectImage: _onTapSelectedImage,
          onSelectedImages: onSelectedImages,
        ),
      );
    } else {
      PromptBox.toast(i18nBook.remedical.noReport.t);
      // PromptBox.toast(i18nBook.errorCodes.errorCode4001.t);
    }
  }

  Future<void> _findConsultationDetailAsync() async {
    final liveConsultationManager = Get.find<ILiveConsultationManager>();
    var currentConsultationDetail =
        await liveConsultationManager.findConsultationDetailAsync(
            state.currentConsultation.consultationCode);
    state.currentConsultationDetail = currentConsultationDetail;
  }

  Future<void> _onTapSelectedImage() async {
    var imagesInfo = await appointmentConsultationManager
        .getConsultationImages(state.consultationCode);
    List<ConsultationFileDTO> consultationImages = [];
    List<RemedicalMeasuredInfoDTO> measureImages = [];
    List<RemedicalListResult> remedicalImages = [];
    for (var images in imagesInfo) {
      var remedicalInfos = images.ultrasoundImageList ?? [];
      List<RemedicalItemList> items = [];
      items.add(RemedicalItemList(remedicalList: remedicalInfos));
      remedicalImages.add(RemedicalListResult(
          scanDate: reportManager
              .getTime((images.imageDate ?? DateTime.now()).toString()),
          remedicalItemList: items));
      measureImages.addAll(images.measurementImageList ?? []);
      consultationImages.addAll(images.screenshotList ?? []);
    }
    await Get.to(
      () => ExamImagesView(
        measureImages: measureImages,
        consultationImages: consultationImages,
        patientCode: state.currentConsultationDetail?.patientCode ?? '',
        cloudImageInfos: remedicalImages,
        isSelectImageModel: true,
        isSingle: true,
        onSubmit: (List<String> v) {
          state.selectedImages = v;
        },
        selectedImags: state.selectedImages,
        isShowConsultationImage: true,
      ),
    );
  }

  Future<void> _initTemplate() async {
    _defaultTemplate = await reportManager.getReportTemplate();
  }

  ///提交报告
  Future<void> _onsubmit() async {
    var patientInfo = state.currentConsultationDetail?.patientDatas ?? [];
    var patientName = state.currentConsultationDetail?.patientName;
    final reportDatasJson = reportManager.getMobileReportDatasJson(
      patientName: state.currentConsultationDetail?.patientName,
      patientSex: state.currentConsultationDetail?.sex,
      age: patientInfo
          .firstWhereOrNull((element) => element.key == 'age')
          ?.value,
      imageInfos: state.selectedImages,
      des: desController.text,
      summary: consualationController.text,
      creatorName: Store.user.displayName,
      fullName: Store.user.displayName,
    );
    bool submitResult;
    if (state.reportCode.isEmpty) {
      var result = await rpc.report.addReportAsync(
        AddReportRequest(
          reportType: ReportTypeEnum.LiveConsultation,
          token: Store.user.token,
          patientName: FEncryptHelper.encodeBase64(patientName ?? ''),
          recordCode: state.consultationCode,
          reportTemplateJson: _defaultTemplate,
          reportDatasJson: reportDatasJson,
          platformLabels: ["Flyinsono", "Mobile", "Consultation"],
        ),
      );
      submitResult = result.isNotEmpty;
    } else {
      submitResult = await rpc.report.modifyReportAsync(
        ModifyReportRequest(
          reportType: ReportTypeEnum.LiveConsultation,
          token: Store.user.token,
          patientName: FEncryptHelper.encodeBase64(patientName ?? ''),
          recordCode: state.consultationCode,
          reportTemplateJson: _defaultTemplate,
          reportDatasJson: reportDatasJson,
          platformLabels: ["Flyinsono", "Mobile", "Consultation"],
          reportCode: state.reportCode,
        ),
      );
    }
    if (submitResult) {
      PromptBox.toast(i18nBook.remedical.submitSuccess.t);
      router.back();
      state.selectedImages = [];
      desController.text = '';
      consualationController.text = '';
      refreshConsultation();
    }
  }

  Future<void> editReport() async {
    state.selectedImages = [];
    consualationController.text = '';
    desController.text = '';
    var report = await reportManager.findReportByCodeAsync(state.reportCode);
    final jsonStr = report.reportDatasJson ?? '';
    var reportElements = reportManager.convertReportData(jsonStr);
    var imageElement = reportElements.firstWhereOrNull(
        (element) => element.name == FReportElementNames.ReportImages);
    List<String> images = [];
    if (imageElement != null && imageElement.value != null) {
      var imageValues = imageElement.value as List<dynamic>;
      if (imageValues.isNotEmpty) {
        images = imageValues.map((e) => e.toString()).toList();
        state.selectedImages = images;
      }
    }
    var reportSummaryElement = reportElements.firstWhereOrNull(
        (element) => element.name == FReportElementNames.ReportSummary);
    if (reportSummaryElement != null && reportSummaryElement.value != null) {
      consualationController.text = reportSummaryElement.value;
    }
    var desElement = reportElements.firstWhereOrNull(
        (element) => element.name == FReportElementNames.ReportDescription);
    if (desElement != null && desElement.value != null) {
      desController.text = desElement.value;
    }
    await Get.to(
      () => WriteReport(
        isNew: false,
        selectedRemedicalImages: state.selectedImages,
        onSubmit: _onsubmit,
        onRemoveImage: (image) {
          if (state.selectedImages.contains(image)) {
            state.selectedImages.remove(image);
          }
        },
        conTextController: consualationController,
        desTextController: desController,
        onTapSelectImage: _onTapSelectedImage,
        onSelectedImages: onSelectedImages,
      ),
    );
    state.reportList = await reportManager
        .findReportsAsync(state.currentConsultation.consultationCode);
  }
}
