import 'package:fis_common/env/env.dart';
import 'package:fis_common/js_plateform/js_platform.dart';
import 'package:fis_i18n/i18n.dart';
import 'package:fis_jsonrpc/rpc.dart';
import 'package:fis_lib_pdf/pdf_objects/report/report_helper/report_dic.dart';
import 'package:fis_lib_report/converts/event_type.dart';
import 'package:fis_lib_report/report_info/element_tag_names.dart';
import 'package:fis_lib_report/report_info/input_text_info.dart';
import 'package:fis_lib_report/report_info/report_info.dart';
import 'package:fis_ui/index.dart';
import 'package:flutter/foundation.dart';
import 'package:get/get.dart';
import 'package:intl/intl.dart';
import 'package:universal_html/html.dart' as html;
import 'package:fis_lib_pdf/ultils/pdf_type_enum.dart';
import 'package:vitalapp/architecture/defines.dart';
import 'package:vitalapp/architecture/storage/file_storage.dart';
import 'package:vitalapp/architecture/utils/prompt_box.dart';
import 'package:vitalapp/managers/interfaces/report.dart';
import 'package:vitalapp/pages/report_edit/widgets/report_share_dialog.dart';
import 'package:vitalapp/pages/report_preview/state.dart';
import 'package:vitalapp/rpc.dart';
import 'package:vitalapp/store/store.dart';

import '../medical_checkup_station/registration/widgets/report/qrcode_report_share_dialog.dart';

///报告预览控制器
class ReportPreviewController extends FControllerBase {
  ///报告预览控制器状态
  final state = ReportPreviewState();

  ///选中事件
  final FEventHandler<String> onSelect = new FEventHandler<String>();

  String? recordCode;

  ///是否来自编辑器
  static bool isFromEditor = false;

  ///报告图片列表
  static List<String> imageOrFileUrls = [];

  /// 载入类型
  static PDFTypeEnum pdfType =
      isFromEditor ? PDFTypeEnum.report : PDFTypeEnum.pdfJpeg;

  final fileStorage = FileStorage(directory: "remedical/report");

  String _patientName = "";
  String _recordCode = "";
  ReportDTO? reportDTO;

  Future<bool> shareReport() async {
    if (imageOrFileUrls.isEmpty) {
      PromptBox.toast('获取分享数据失败');
    }

    Get.dialog(
      QRCodeShareDialog(
        imageOrFileUrls.first,
        "",
        isQROnly: true,
        pageName: 'QRCodeShareDialog',
      ),
    );
    return true;
  }

  @override
  void onReady() {
    initDatas();
    super.onReady();
  }

  @override
  void dispose() {
    super.dispose();
  }

  ///初始化数据
  Future<void> initDatas() async {
    pdfType = isFromEditor ? PDFTypeEnum.report : PDFTypeEnum.pdfJpeg;
    imageOrFileUrls = [];
    Map parameters = Get.arguments ?? {};

    if (parameters.containsKey('reportCode')) {
      var reportCode = parameters['reportCode'] ?? '';
      state.reportCode = reportCode;
    }
    if (parameters.containsKey('isFromEditor')) {
      var isFromEditorStr = parameters['isFromEditor'] ?? '';
      if (isFromEditorStr == 'true') {
        isFromEditor = true;
      } else {
        isFromEditor = false;
      }
    }
    if (parameters.containsKey('recordCode')) {
      recordCode = parameters['recordCode'] ?? '';
      await _initPreviewReportByRecordCode(recordCode!);
      state.qualityType = reportDTO?.qualityType ?? QualityType.None;
    } else {
      state.isLoaded = true;
    }
    _generateReportName();
  }

  ///关闭PDF预览
  void onPDFClose() {
    Get.back();
  }

  Future<List<ReportDTO>> findExamReportsAsync(String recordCode) async {
    int retries = 0;
    while (retries < 5) {
      //最多重试5次
      try {
        print('findExamReportsAsync start');
        print("recordCode:" + recordCode);
        var reportInfo = await rpc.ultrasoundReport.vitalFindReportsAsync(
          FindReportsRequest(
            token: Store.user.token,
            recordCode: recordCode,
            languageCode: i18nBook.locale.toCodeString('-'),
          ),
        );
        print('findExamReportsAsync end');
        return reportInfo;
      } catch (e) {
        print('findExamReportsAsync rpc error:' + e.toString());
        retries++; //重试次数增加
        await Future.delayed(Duration(seconds: retries)); //等待时间逐渐增加
      }
    }
    return []; //最终返回[],因为已经达到最大尝试次数
  }

  Future<void> _initPreviewReportByRecordCode(String recordCode) async {
    try {
      busy = true;
      final reportCode = state.reportCode;
      var reportInfos = await findExamReportsAsync(recordCode);
      if (reportInfos.any((element) => element.reportCode == reportCode)) {
        reportDTO = reportInfos
            .firstWhere((element) => element.reportCode == reportCode);
      } else if (reportInfos.isNotEmpty) {
        reportDTO = reportInfos.last;
      }

      /// 从 _reportDTO 中获取编号、姓名,后续用于文件命名
      if (reportDTO != null) {
        _recordCode = reportDTO!.reportCode ?? '';
        _patientName = reportDTO!.patientName ?? '';
      } else {
        _recordCode = recordCode;
      }

      /// 如果没有 PDF file 那么从 _reportDTO 中获取图像列表
      var images = reportDTO?.reportPreviewList?.where(
              (element) => element.fileType == UploadFileTypeEnum.JPG) ??
          [];
      List<String> imageList = images.map((e) => e.fileToken ?? '').toList();
      for (var image in imageList) {
        if (image.contains(';')) {
          imageOrFileUrls
              .addAll(image.split(';').where((element) => element.isNotEmpty));
        } else {
          imageOrFileUrls.add(image);
        }
      }
      if (kIsMobile && imageOrFileUrls.isNotEmpty) {
        ///平板预览报告使用图像
        busy = false;
        // 此时会触发 reportImageList 进入 FPDFRenderContainer 的渲染逻辑(会做图像压缩,缓存)
        state.isLoaded = true;
        return;
      }

      var pdfFiles = reportDTO?.reportPreviewList?.where(
              (element) => element.fileType == UploadFileTypeEnum.PDF) ??
          [];
      List<String> pdfList = pdfFiles.map((e) => e.fileToken ?? '').toList();
      if (pdfList.isNotEmpty) {
        imageOrFileUrls.clear();
        pdfType = PDFTypeEnum.pdfBytes;
        for (var pdf in pdfList) {
          if (pdf.contains(';')) {
            imageOrFileUrls
                .addAll(pdf.split(';').where((element) => element.isNotEmpty));
          } else {
            imageOrFileUrls.add(pdf);
          }
        }
      }

      /// 设置报告文件名
      if (imageOrFileUrls.isNotEmpty) {
        String fileName = _generateReportFileNameWithReportInfo(reportDTO!);
        if (state.reportName == "") {
          state.reportName = fileName;
        }
      }
    } catch (e) {
      print(e);
    }
    busy = false;
    // 此时会触发 reportImageList 进入 FPDFRenderContainer 的渲染逻辑(会做图像压缩,缓存)
    state.isLoaded = true;
  }

  void _generateReportName() {
    var reportInfo = FReportInfo.instance;
    var inputTextInfo;
    String patientName = '';
    var patientElement =
        reportInfo.getElementInfoByTagName(TagNames.PATIENT_NAME_TAG);
    if (patientElement != null) {
      inputTextInfo = patientElement as InputTextInfo;
      patientName = inputTextInfo.text;
    } else {
      patientName = _patientName;
    }
    var creatTime =
        reportInfo.reportDate ?? reportDTO?.reportTime ?? DateTime.now();
    var reportCode = reportInfo.id ?? _recordCode;

    DateFormat format = DateFormat("yyyMMddHHmmss");

    var dateStr = format.format(creatTime);
    var fileName = "[$patientName]-[$dateStr]-[$reportCode].pdf";
    if (state.reportName == '') {
      state.reportName = fileName;
    }
  }

  String _generateReportFileNameWithReportInfo(ReportDTO reportDTO) {
    var patientName = reportDTO.patientName!.replaceAll("*", "x");
    DateFormat format = DateFormat("yyyMMddHHmmss");
    var dateStr = format.format(reportDTO.reportTime!.toLocal());
    var fileName = "[$patientName]-[$dateStr]-[${reportDTO.reportCode!}].pdf";
    return fileName;
  }
}