import 'package:fis_common/index.dart';
import 'package:fis_i18n/i18n.dart';
import 'package:fis_ui/index.dart';
import 'package:fis_ui/interface/interactive_container.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.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/prompt_box.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/language.dart';
import 'package:flyinsono/managers/interfaces/remedical.dart';
import 'package:flyinsono/managers/interfaces/report.dart';
import 'package:fis_theme/theme.dart';
import 'package:flyinsono/pages/remedical/consultation/widgets/exam_images_view.dart';
import 'package:flyinsono/pages/remedical/consultation/widgets/report/report_preview.dart';
import 'package:flyinsono/pages/remedical/consultation/widgets/report/reportinfo_card_mobile.dart';
import 'package:flyinsono/pages/remedical/consultation/widgets/report/write_report.dart';
import 'package:flyinsono/rpc.dart';
import 'package:get/get.dart';
import 'package:fis_common/event/event_type.dart';
import 'package:fis_jsonrpc/rpc.dart';
import 'package:fis_ui/widgets/scroll/refreshIndicator.dart';
import 'package:fis_common/helpers/encrypt.dart';
import 'package:fis_common/logger/logger.dart';
import 'dart:convert';
import 'package:flyinsono/managers/interfaces/report_template.dart';
import 'package:flyinsono/managers/interfaces/user_info.dart';
import 'package:flyinsono/pages/remedical/consultation/state.dart';
import 'package:fis_lib_report/report/report_template_document.dart';
import 'package:fis_lib_report/report_info/report_info.dart' as report;
import 'package:fis_lib_report/report_info/input_text_info.dart';
import 'package:fis_lib_report/report_info/element_info.dart';
import 'package:fis_lib_report/report_info/single_selected_info.dart';
import 'package:fis_lib_report/report_info/element_tag_names.dart';
import 'package:fis_lib_report/report_info/input_image_list_info.dart';

/// 新版报告列表【仅用于群聊页】
class MobileReportsContentViewNew extends FStatefulWidget
    implements FInteractiveContainer {
  @override
  final String pageName;
  final List<ReportDTO> reportList;
  final void Function(int) onTapImage;
  final void Function(String) onTapShare;
  final void Function()? onTapCheck;
  final Future<List<ReportDTO>> Function() onRefresh;
  final PatientInfo patientInfo;
  final SimpleRecordInfoDTO recordInfo;
  String get patientName => patientInfo.name ?? '';
  MobileReportsContentViewNew({
    required this.reportList,
    required this.onTapShare,
    required this.onRefresh,
    required this.onTapImage,
    required this.patientInfo,
    required this.recordInfo,
    this.onTapCheck,
    this.pageName = 'MobileReportsContentViewNew',
  });

  @override
  FState<FStatefulWidget> createState() {
    return MobileReportsContentViewNewState();
  }
}

class MobileReportsContentViewNewState
    extends FState<MobileReportsContentViewNew> {
  final reportManager = Get.find<IReportManager>();

  final FEventHandler<List<String>> onSelectedImages =
      FEventHandler<List<String>>();
  final remedicalManager = Get.find<IRemedicalManager>();
  final consualationController = TextEditingController();
  final desController = TextEditingController();
  List<String> _selectedImages = [];
  final _reportScrollController = ScrollController();
  bool _isCanWriteReport = false;
  String recordCode = '';
  List<ReportDTO> _reportList = [];

  List<String> _selectedRemedicalImages = [];

  ///超声机描述
  final TextEditingController _desController = TextEditingController();

  ///超声机提示
  final TextEditingController _consualationController = TextEditingController();

  final FEventHandler<List<String>> _onSelectedImages =
      FEventHandler<List<String>>();

  @override
  void initState() {
    recordCode = widget.recordInfo.recordCode ?? '';
    _isCanWriteReport = widget.recordInfo.canCreateReport;
    _reportList = widget.reportList;
    // widget.onReportsChange?.addListener((sender, e) {
    //   setState(() {
    //     _reportList = e;
    //   });
    // });
    // widget.onCreatePermissionChange?.addListener(_onEditPermissionChange);
    super.initState();
  }

  @override
  void dispose() {
    // widget.onCreatePermissionChange?.removeListener(_onEditPermissionChange);
    super.dispose();
  }

  @override
  void didUpdateWidget(MobileReportsContentViewNew oldWidget) {
    if (_reportList != widget.reportList) {
      setState(() {
        _reportList = widget.reportList;
      });
    }
    super.didUpdateWidget(oldWidget);
  }

  @override
  FWidget build(BuildContext context) {
    return FScaffold(
      appBar: FAppBar(
        title: FText(i18nBook.remedical.checkReport.t),
        backgroundColor: FTheme.ins.colorScheme.primary,
        elevation: 0,
        centerTitle: true,
        leading: FIconButton(
          icon: FIcon(Icons.arrow_back_ios_new),
          onPressed: () {
            final currentRouter = router.getCurrentNameByNavId(NavIds.HOME);
            if (currentRouter == RouteNames.Remedical.ConsultationRecordView ||
                currentRouter == RouteNames.User.Center) {
              router.back();
            } else {
              router.offAll(RouteNames.Remedical.ConsultationRecordView,
                  id: NavIds.HOME);
            }
          },
          businessParent: widget,
          name: "back",
        ),
        actions: [
          if (_isCanWriteReport) ...[
            FIconButton(
              icon: FIcon(Icons.edit),
              onPressed: () async {
                createNewReport();
              },
              businessParent: widget,
              name: 'edit',
            )
          ] else ...[
            FIconButton(
              icon: FIcon(Icons.refresh),
              onPressed: () async {
                var reportList = await widget.onRefresh.call();
                setState(() {
                  _reportList = reportList;
                });
              },
              businessParent: widget,
              name: 'refersh',
            )
          ],
        ],
      ),
      body: _buildReportsView(context),
      backgroundColor: Colors.grey[200],
    );
  }

  //预览报告
  Future<void> onTapCard(int index) async {
    final baseReportInfo = _reportList[index];
    var reportCode = baseReportInfo.reportCode ?? '';
    var reportInfo = await reportManager.findReportByCodeAsync(reportCode);
    final preList = reportInfo.reportPreviewList ?? [];
    if (preList.isEmpty) {
      PromptBox.toast(i18nBook.remedical.reportNoInit.t);
    } else {
      Get.to(() => ReportPreview(
            reportInfo: reportInfo,
            reportList: _reportList,
          ));
    }
  }

  ///报告列表视图
  FWidget _buildReportsView(BuildContext context) {
    if (_reportList.isEmpty) {
      return FContainer(
        margin: EdgeInsets.only(top: 80),
        child: FColumn(
          children: [
            FCenter(
              child: FImage.asset(
                "assets/images/no_data.png",
                width: 300,
                height: 300,
                fit: BoxFit.cover,
              ),
            ),
            FText(i18nBook.common.noneDataTip.t),
          ],
        ),
      );
    }
    return FRefreshIndicator(
      onRefresh: () async {
        var reportList = await widget.onRefresh.call();
        setState(() {
          _reportList = reportList;
        });
      },
      child: FAlwaysScrollListView(
        scrollController: _reportScrollController,
        child: QuickFWidget(ScrollConfiguration(
          behavior: ScrollConfiguration.of(context).copyWith(scrollbars: false),
          child: FListView.builder(
            shrinkWrap: true,
            itemCount: _reportList.length,
            controller: _reportScrollController,
            itemBuilder: (context, index) {
              final reportInfo = _reportList[index];
              return FGestureDetector(
                name: "findReports",
                businessParent: widget,
                onTap: () async {
                  onTapCard(index);
                },
                child: ReportCardMobileLayout(
                  reportInfo,
                  index,
                  onTapEditReport: () =>
                      editExistReport(reportInfo.reportCode ?? ''),
                  businessParent: widget,
                  patientName: widget.patientName,
                  onTapShare: widget.onTapShare,
                  onTapImage: widget.onTapImage,
                ),
              );
            },
          ),
        )),
      ),
    );
  }

  // void _onEditPermissionChange(Object sender, bool e) {
  //   setState(() {
  //     _isCanWriteReport = e;
  //   });
  // }

  Future<void> createNewReport(
      {bool isLandscapeMode = false, bool resizeFactor = false}) async {
    bool isAnimailReport = false;
    String _gender = '';
    String _specie = '';
    try {
      var orgInfo = await Get.find<IUserInfoManager>()
          .getOrganizationByCode(Store.user.rootOrganizationCode ?? '');
      isAnimailReport =
          orgInfo.patientType == OrganizationPatientTypeEnum.Animals;
    } catch (e) {
      print(e);
    }
    TextEditingController? hospitalController;
    TextEditingController? ownerController;
    TextEditingController? nameController;
    TextEditingController? ageController;
    TextEditingController? speciesController;
    TextEditingController? inspectionPhysicianController;
    TextEditingController? reportPhysicianController;
    List<String>? genderItems;
    List<String>? speciesItems;
    ElementInfo? hospitalElement;
    ElementInfo? ownerElement;
    ElementInfo? nameElement;
    ElementInfo? genderElement;
    ElementInfo? ageElement;
    ElementInfo? idElement;
    ElementInfo? speciesElement;
    ElementInfo? inspectionPhysicianElement;
    ElementInfo? reportPhysicianElement;
    void Function(String)? onSelectedGender;
    void Function(String)? onSelectedSpecies;
    String? reportTemplate;

    if (isAnimailReport) {
      var patientInfoDto = await remedicalManager
          .findPatientByCode(widget.patientInfo.patientCode);
      var patientInfo =
          remedicalManager.dtoConvertToPatientInfo(patientInfoDto);
      var reportTemplateInfo =
          await Get.find<IReportTemplateManager>().getDefaultTemplate();
      reportTemplate = reportTemplateInfo.reportTemplateJson;

      if (reportTemplate.isNotNullOrEmpty) {
        var recordDetail =
            await remedicalManager.queryRecordInfoAsync(recordCode);
        var reportTempalteDoc =
            ReportTemplateDocument.fromJson(jsonDecode(reportTemplate!));
        report.FReportInfo.instance.init(
          reportTempalteDoc,
          DateTime.now(),
          "",
          revoke: i18nBook.common.revoke.t,
          selectEntry: i18nBook.remedical.selectWord.t,
          selectImageHint: i18nBook.remedical.clickAndSelectImage.t,
        );
        hospitalElement = report.FReportInfo.instance
            .getElementInfoByTagName(PETREPORTTAGS[0]);
        if (hospitalElement != null && hospitalElement is InputTextInfo) {
          hospitalController = TextEditingController();
          if (Store.user.rootOrganizationName.isEmpty) {
            hospitalController.text = recordDetail?.deviceOrganzationName ?? "";
          } else {
            hospitalController.text = Store.user.rootOrganizationName;
          }
        }
        ownerElement = report.FReportInfo.instance
            .getElementInfoByTagName(PETREPORTTAGS[1]);
        if (ownerElement != null && ownerElement is InputTextInfo) {
          ownerController = TextEditingController();
        }
        nameElement = report.FReportInfo.instance
            .getElementInfoByTagName(PETREPORTTAGS[2]);
        if (nameElement != null && nameElement is InputTextInfo) {
          nameController = TextEditingController();
          nameController.text = patientInfo.name ?? '';
        }
        genderElement = report.FReportInfo.instance
            .getElementInfoByTagName(PETREPORTTAGS[3]);
        if (genderElement != null && genderElement is SingleSelectedInfo) {
          genderItems = genderElement.items ?? [];
          onSelectedGender = (v) {
            _gender = v;
          };
        }

        ageElement = report.FReportInfo.instance
            .getElementInfoByTagName(PETREPORTTAGS[4]);
        if (ageElement != null && ageElement is InputTextInfo) {
          ageController = TextEditingController();
          ageController.text = patientInfo.ageYear ?? '';
        }
        idElement = report.FReportInfo.instance
            .getElementInfoByTagName(PETREPORTTAGS[5]);
        if (idElement != null && idElement is InputTextInfo) {
          if (patientInfoDto.devicePatientIDs?.isNotEmpty ?? false) {
            idElement.text = patientInfoDto.devicePatientIDs?.first ?? '';
          }
        }
        speciesElement = report.FReportInfo.instance
            .getElementInfoByTagName(PETREPORTTAGS[6]);
        if (speciesElement != null && speciesElement is SingleSelectedInfo) {
          speciesItems = speciesElement.items;
          onSelectedSpecies = (v) {
            _specie = v;
          };
        }
        inspectionPhysicianElement = report.FReportInfo.instance
            .getElementInfoByTagName(PETREPORTTAGS[7]);
        if (inspectionPhysicianElement != null &&
            inspectionPhysicianElement is InputTextInfo) {
          inspectionPhysicianController = TextEditingController();
          inspectionPhysicianController.text = Store.user.displayName;
        }
        reportPhysicianElement = report.FReportInfo.instance
            .getElementInfoByTagName(PETREPORTTAGS[8]);
        if (reportPhysicianElement != null &&
            reportPhysicianElement is InputTextInfo) {
          reportPhysicianController = TextEditingController();
          reportPhysicianController.text = Store.user.displayName;
        }
      }
    }
    await Get.to(
      () => WriteReport(
        isNew: true,
        onSelectedImages: _onSelectedImages,
        isLandscapeMode: isLandscapeMode,
        selectedRemedicalImages: _selectedRemedicalImages,
        onSubmit: () {
          if (isAnimailReport) {
            if (hospitalElement != null && hospitalElement is InputTextInfo) {
              hospitalElement.text = hospitalController?.text ?? '';
            }
            if (ownerElement != null && ownerElement is InputTextInfo) {
              ownerElement.text = ownerController?.text ?? '';
            }
            if (nameElement != null && nameElement is InputTextInfo) {
              nameElement.text = nameController?.text ?? '';
            }
            if (genderElement != null && genderElement is SingleSelectedInfo) {
              genderElement.selectedItem = _gender;
            }
            if (ageElement != null && ageElement is InputTextInfo) {
              ageElement.text = ageController?.text ?? '';
            }
            if (speciesElement != null &&
                speciesElement is SingleSelectedInfo) {
              speciesElement.selectedItem = _specie;
            }
            if (inspectionPhysicianElement != null &&
                inspectionPhysicianElement is InputTextInfo) {
              inspectionPhysicianElement.text =
                  inspectionPhysicianController?.text ?? '';
            }
            if (reportPhysicianElement != null &&
                reportPhysicianElement is InputTextInfo) {
              reportPhysicianElement.text =
                  reportPhysicianController?.text ?? '';
            }

            var consualationElement = report.FReportInfo.instance
                .getElementInfoByTagName(TagNames.REPORTDES);
            if (consualationElement != null &&
                consualationElement is InputTextInfo) {
              consualationElement.text = _desController.text;
            }
            var desElement = report.FReportInfo.instance
                .getElementInfoByTagName(TagNames.REPORTSUMARY);
            if (desElement != null && desElement is InputTextInfo) {
              desElement.text = _consualationController.text;
            }
            var inputImageElement = report.FReportInfo.instance
                .getElementInfoByTagName(TagNames.SELECTIMAGES);
            if (inputImageElement != null &&
                inputImageElement is InputImageListInfo) {
              inputImageElement.selectedImages = _selectedRemedicalImages;
            }

            report.FReportInfo.instance.toJson();
            if (report.FReportInfo.instance.jsonItems.isNotEmpty) {
              var reportDataJson =
                  jsonEncode(report.FReportInfo.instance.jsonItems);
              onSubmitReport(
                reportDataJson: reportDataJson,
                templateJson: reportTemplate!,
                isLandscapeMode: isLandscapeMode,
                resizeFactor: resizeFactor,
              );
            }
          } else {
            onSubmitReport(
                isLandscapeMode: isLandscapeMode, resizeFactor: resizeFactor);
          }
        },
        onRemoveImage: (image) {
          if (_selectedRemedicalImages.contains(image)) {
            setState(() {
              _selectedRemedicalImages.remove(image);
            });
          }
        },
        conTextController: _consualationController,
        desTextController: _desController,
        onTapSelectImage: () async {
          await openImagesSelector();
        },
        hospitalController: hospitalController,
        ownerController: ownerController,
        nameController: nameController,
        ageController: ageController,
        speciesController: speciesController,
        inspectionPhysicianController: inspectionPhysicianController,
        reportPhysicianController: reportPhysicianController,
        genderItems: genderItems,
        speciesItems: speciesItems,
        onSelectedGender: onSelectedGender,
        onSelectedSpecies: onSelectedSpecies,
      ),
    );
    _selectedRemedicalImages.clear();
  }

  ///选择图像
  Future<void> openImagesSelector() async {
    List<RemedicalMeasuredInfoDTO> measureImages =
        await remedicalManager.findRemedicalMeasuredInfoAsync(recordCode);
    RemedicalListResult cloudImageInfo =
        await reportManager.getRemedicalListByRecordInfoAsync(recordCode);

    Get.to(
      () => ExamImagesView(
        patientCode: widget.patientInfo.patientCode,
        measureImages: measureImages,
        selectedImags: _selectedRemedicalImages,
        isSingle: true,
        isSelectImageModel: true,
        cloudImageInfos: [cloudImageInfo],
        onSubmit: (List<String> v) {
          setState(() {
            _selectedRemedicalImages = v;
          });
          _onSelectedImages.emit(this, v);
          print(v);
        },
        isShowConsultationImage: false,
      ),
    );
  }

  ///提交报告
  Future<void> onSubmitReport(
      {String? templateJson,
      String? reportDataJson,
      bool resizeFactor = false,
      bool isLandscapeMode = false}) async {
    PromptBox.loading(i18nBook.common.submitting.t);
    var patientInfoDto = await remedicalManager
        .findPatientByCode(widget.patientInfo.patientCode);
    var patientInfo = remedicalManager.dtoConvertToPatientInfo(patientInfoDto);
    var recordDetail = await remedicalManager.queryRecordInfoAsync(recordCode);
    String reportDatasJson;
    var deviceOrganzationName = recordDetail?.deviceOrganzationName ?? '';
    var languageManager = Get.find<ILanguageConfigManager>();
    if (reportDataJson == null) {
      reportDatasJson = reportManager.getMobileReportDatasJson(
        patientName: patientInfo.name,
        patientSex: languageManager.getExamLanguageValue(patientInfo.sex ?? ''),
        age: patientInfo.age,
        imageInfos: _selectedRemedicalImages,
        des: _desController.text,
        summary: _consualationController.text,
        creatorName: recordDetail?.creatorName ?? '',
        fullName: Store.user.displayName,
        customDoctor: recordDetail?.customDoctor ?? '',
        customOrganzation: recordDetail?.customOrganzation ?? '',
        deviceOrganzationName: deviceOrganzationName,
      );
    } else {
      reportDatasJson = reportDataJson;
    }
    String defaultTemplate;
    if (templateJson == null) {
      defaultTemplate = await reportManager.getReportTemplate();
    } else {
      defaultTemplate = templateJson;
    }
    final addRequest = AddReportRequest(
        token: Store.user.token,
        patientName: FEncryptHelper.encodeBase64(patientInfo.name ?? ''),
        recordCode: recordCode,
        reportTemplateJson: defaultTemplate,
        reportDatasJson: reportDatasJson,
        platformLabels: ["Flyinsono", "Mobile", "RemoteDiagnosis"]);
    if (widget.recordInfo.referralType.index > 0) {
      ///转诊报告
      addRequest.isReferral = true;
    }
    final submitResult = await rpc.report.addReportAsync(addRequest);
    PromptBox.dismiss();
    if (submitResult.isNotEmpty) {
      PromptBox.toast(i18nBook.remedical.submitSuccess.t);
    }
    _selectedRemedicalImages.clear();
    _desController.text = '';
    _consualationController.text = '';

    Future.delayed(Duration(milliseconds: 200), () {
      if (isLandscapeMode) {
        SystemChrome.setPreferredOrientations(
            [DeviceOrientation.portraitUp, DeviceOrientation.portraitDown]);
        router.back();
        router.back();
        router.back();
      } else {
        router.back();
        if (!resizeFactor) {
          router.back();
        }
      }
    });

    Get.find<IReportManager>().onMobileSubmitReport.emit(this, true);
    var reportList = await remedicalManager.findExamReports(recordCode);
    _reportList = reportList;
  }

  Future<void> editExistReport(String reportCode) async {
    var report = await reportManager.findReportByCodeAsync(reportCode);
    final jsonStr = report.reportDatasJson ?? '';
    var reportElements = reportManager.convertReportData(jsonStr);
    var imageElement = reportElements.firstWhereOrNull(
        (element) => element.name == FReportElementNames.ReportImages);

    if (imageElement != null && imageElement.value != null) {
      var imageValues = imageElement.value as List<dynamic>;
      if (imageValues.isNotEmpty) {
        _selectedImages = imageValues.map((e) => e.toString()).toList();
      }
    }
    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: _selectedImages,
        onSubmit: () {
          _onsubmit(reportCode);
        },
        onRemoveImage: (image) {
          if (_selectedImages.contains(image)) {
            _selectedImages.remove(image);
          }
        },
        conTextController: consualationController,
        desTextController: desController,
        onTapSelectImage: _onTapSelectedImage,
        onSelectedImages: onSelectedImages,
      ),
    );
    _reportList = await reportManager.findReportsAsync(recordCode);
  }

  Future<void> _onTapSelectedImage() async {
    var measureImages =
        await remedicalManager.findRemedicalMeasuredInfoAsync(recordCode);
    var cloudImageInfos =
        await reportManager.getRemedicalListByRecordInfoAsync(recordCode);

    await Get.to(
      () => ExamImagesView(
        measureImages: measureImages,
        consultationImages: [],
        patientCode: widget.patientInfo.patientCode,
        cloudImageInfos: [cloudImageInfos],
        isSelectImageModel: true,
        isSingle: true,
        onSubmit: (List<String> v) {
          _selectedImages = v;
        },
        selectedImags: _selectedImages,
        isShowConsultationImage: true,
      ),
    );
  }

  ///提交报告
  Future<void> _onsubmit(String reportCode) async {
    Store.app.setBusy(i18nBook.common.submitting.t);
    bool submitResult = false;
    try {
      var patientInfo = widget.patientInfo;
      var patientName = patientInfo.name ?? '';
      var recordDetail =
          await remedicalManager.queryRecordInfoAsync(recordCode);
      var languageManager = Get.find<ILanguageConfigManager>();
      var deviceOrganzationName = recordDetail?.deviceOrganzationName ?? '';
      final reportDatasJson = reportManager.getMobileReportDatasJson(
        patientName: patientName,
        patientSex: languageManager.getExamLanguageValue(patientInfo.sex ?? ''),
        age: patientInfo.ageYear,
        imageInfos: _selectedImages,
        des: desController.text,
        summary: consualationController.text,
        creatorName: Store.user.displayName,
        fullName: Store.user.displayName,
        deviceOrganzationName: deviceOrganzationName,
      );
      var defaultTemplate = await reportManager.getReportTemplate();
      submitResult = await rpc.report.modifyReportAsync(
        ModifyReportRequest(
          reportType: ReportTypeEnum.RemoteDiagnosis,
          token: Store.user.token,
          patientName: FEncryptHelper.encodeBase64(patientName),
          recordCode: recordCode,
          reportTemplateJson: defaultTemplate,
          reportDatasJson: reportDatasJson,
          platformLabels: ["Flyinsono", "Mobile", "Remedical"],
          reportCode: reportCode,
        ),
      );
    } catch (e) {
      logger.e('save report error:', e);
    }
    Store.app.busy = false;

    if (submitResult) {
      PromptBox.toast(i18nBook.remedical.submitSuccess.t);
      router.back();
      _selectedImages = [];
      desController.text = '';
      consualationController.text = '';
      Future.delayed(Duration(milliseconds: 500), () async {
        var reportList = await widget.onRefresh.call();
        setState(() {
          _reportList = reportList;
        });
      });
    }
  }
}
