import 'dart:async';
import 'dart:convert';
import 'package:fis_common/env/env.dart';
import 'package:fis_common/js_plateform/js_platform.dart';
import 'package:fis_common/logger/logger.dart';
import 'package:fis_i18n/i18n.dart';
import 'package:fis_jsonrpc/rpc.dart';
import 'package:fis_lib_report/report_info/report_info.dart';
import 'package:flyinsono/architecture/memory_cache/report.dart';
import 'package:flyinsono/architecture/router/index.dart';
import 'package:flyinsono/architecture/services/entity/local_setting.dart';
import 'package:flyinsono/architecture/services/entity/report_editor_setting.dart';
import 'package:flyinsono/architecture/services/modules/report_editor_configuration.dart';
import 'package:flyinsono/architecture/states/states.dart';
import 'package:flyinsono/managers/interfaces/entities/reportEditSource.dart';
import 'package:flyinsono/pages/main/home/controller.dart';
import 'package:flyinsono/pages/remedical/consultation/controller.dart';
import 'package:flyinsono/pages/remedical/report/report_edit/controller.dart';
import 'package:flyinsono/rpc.dart';
import 'package:get/get.dart';
import 'package:universal_html/html.dart' as html;
import 'package:flyinsono/pages/remedical/report/report_edit/state.dart';
import 'package:crypto/crypto.dart';
import 'package:fis_ui/index.dart';
import 'package:fis_common/index.dart';

class ReportCacheController {
  late final ReportEditController controller;
  late final ReportEditState state;

  /// 本地报告编辑器持久化缓存服务
  LocalReportEditorService localReportEditorService =
      Get.find<LocalReportEditorService>();
  ReportEditorSetting reportEditorSetting = ReportEditorSetting.ins;

  ///定时刷新缓存
  Timer? _timer;

  /// 本地的报告草稿【json格式的文本持久化存储】
  String _localReportCache = '';

  ReportCacheController(ReportEditController controller) {
    this.controller = controller;
    this.state = controller.state;
  }

  ///从Server加载报告
  Future<ReportDTO> initServerReport() async {
    final ReportDTO report = await rpc.report.findReportByCodeAsync(
      FindReportByCodeRequest(
        token: Store.user.token,
        reportCode: state.reportCode,
        language: i18nBook.locale.toCodeString('-'),
      ),
    );
    final serverTempalte = ReportTemplateDTO(
      reportTemplateName: report.reportTemplateName,
      reportTemplateCode: report.reportTemplateCode,
      reportTemplateJson: report.reportTemplateJson,
    );
    var selectedTemplate = state.templates.firstWhereOrNull(
        (element) => element.value == report.reportTemplateCode);

    if (selectedTemplate != null) {
      state.selectedTemplate = serverTempalte;
    } else {
      state.templates.add(FSelectOptionModel(
        value: serverTempalte.reportTemplateCode,
        title: serverTempalte.reportTemplateName ?? '',
      ));
      state.selectedTemplate = serverTempalte;
    }
    if (report.reportTemplateJson == null ||
        report.reportTemplateJson!.isEmpty) {
      controller.initUserDefaultTemplate();
    }

    final jsonStr = report.reportDatasJson ?? '';
    final List<dynamic> jsonItems = jsonDecode(jsonStr) as List<dynamic>;
    final measureJsonStr = report.reportMeasureDatasJson;
    if (measureJsonStr.isNotNullOrEmpty) {
      final measureJsonItems = jsonDecode(measureJsonStr!) as List<dynamic>;
      jsonItems.addAll(measureJsonItems);
    }
    await Future.delayed(Duration(milliseconds: 500), () {
      FReportInfo.instance.fromJson(jsonItems);
    });
    return report;
  }

  /// 加载报告缓存
  void initReportCache() {
    Future.delayed(
      Duration(milliseconds: 200),
      () async {
        if (state.reportCode.isNotEmpty) {
          String jsonStr;
          if (ReportCache.cache.keys.contains(state.reportCode)) {
            final reportCache = ReportCache.cache[state.reportCode];
            jsonStr = reportCache!.reportInfoJson;
          } else {
            final reportInfo =
                await rpc.report.findReportByCodeAsync(FindReportByCodeRequest(
              token: Store.user.token,
              reportCode: state.reportCode,
            ));
            jsonStr = reportInfo.reportDatasJson ?? '';
          }
          if (jsonStr.isNotEmpty) {
            final json = jsonDecode(jsonStr) as List<dynamic>;
            FReportInfo.instance.fromJson(json);
          }
        } else {
          if (ReportCache.cache.keys.contains(state.recordCode)) {
            final reportCache = ReportCache.cache[state.recordCode];
            controller.initReportInfoFromJson(reportCache!);
          }
        }
      },
    );
  }

  /// 启动自动缓存策略，每隔5秒缓存一次报告【不同于_updateReportCache，这里的缓存是指持久化到本地】
  void setScheduledCacheReport() {
    // 如果已经存在定时器，先取消
    if (_timer != null) {
      _timer!.cancel();
      _timer = null;
    }
    final timeout = const Duration(seconds: 5);
    _timer = Timer.periodic(timeout, (timer) {
      _cacheReportToLocal();
    });
  }

  /// 移除自动缓存策略
  void removeScheduledCacheReport() {
    if (_timer != null) {
      _cacheReportToLocal();
      _timer!.cancel();
    }
  }

  /// 本地持久化报告的草稿
  /// 存草稿 写入本地缓存做持久化
  void _cacheReportToLocal() async {
    FReportInfo.instance.toJson();
    final reportInfoJson = jsonEncode(FReportInfo.instance.jsonItems);
    if (_getHash(reportInfoJson) != _getHash(_localReportCache)) {
      // print('♻️ 当前内容 hash 为 ${_getHash(reportInfoJson)} 更新本地缓存');
      _localReportCache = reportInfoJson;
      reportEditorSetting.setReportDraft(
          reportInfoJson, state.selectedTemplate.reportTemplateCode ?? '');
      String draftRecordCode = '';
      if (state.recordCode.isNotEmpty) {
        draftRecordCode = state.recordCode;
      } else if (state.consultationCode.isNotEmpty) {
        draftRecordCode = state.consultationCode;
      }
      if (draftRecordCode.isNotEmpty) {
        reportEditorSetting.setReportDraftRecordCode(draftRecordCode);
        localReportEditorService.save();
      }
    } else {
      // print('⛔ 当前内容 hash 为 ${_getHash(reportInfoJson)} 与本地缓存相同，不更新本地缓存');
    }
  }

  /// 取hash值
  Digest _getHash(String str) {
    return sha1.convert(utf8.encode(str));
  }

  /// 更新报告缓存
  void _updateReportCache() {
    FReportInfo.instance.toJson();
    if (FReportInfo.instance.jsonItems.isNotEmpty) {
      if (state.reportCode.isNotEmpty) {
        ReportCache.cache[state.reportCode] = ReportInfoItem(
            jsonEncode(FReportInfo.instance.jsonItems),
            state.selectedTemplate.reportTemplateJson ?? '');
      } else {
        final recordCode = state.recordCode;
        print(recordCode);
        ReportCache.cache[recordCode] = ReportInfoItem(
            jsonEncode(FReportInfo.instance.jsonItems),
            state.selectedTemplate.reportTemplateJson ?? '');
      }
    }
  }

  /// 跟据检查 Code 更新报告缓存
  void updateReportCacheByRecordCode(String recordCode) async {
    if (_timer != null) {
      _timer!.cancel();
    }
    if (ReportCache.cache.containsKey(recordCode)) {
      ReportCache.cache.remove(recordCode);
    }
  }

  /// 返回上级页面
  void back() {
    try {
      if (_timer != null) {
        _timer!.cancel();
      }
      if (LocalSetting.ins.isUseSecondWindow! &&
          (FPlatform.isMacOS || FPlatform.isWindows)) {
        if (state.reportCode.isNotEmpty) _updateReportCache();
        FReportInfo.instance.onClose.emit(this, null);
        FReportInfo.instance.onClose.dispose();
        FReportInfo.instance.onDiagnosticTap.dispose();
        if (state.reportEditSource == ReportEditSource.UserGroup) {
          router.back(id: NavIds.HOME);
        } else {
          JSPlateForm.closeSlaveWindow();
        }
      } else if (FPlatform.isPureWeb && Store.app.enableNewTab) {
        html.window.close();
      } else {
        router.back(id: (kIsMobile) ? null : NavIds.HOME);
        try {
          final consultationController = Get.find<ConsultationController>();
          consultationController.inspectionRecordsController
              .getCheckLists(state.patientId);
          consultationController.patientInfoController
              .getPatientInfo(state.patientId);
        } catch (e) {}
        try {
          final _navController = Get.find<HomeNavigatorController>();
          _navController.subBack();
        } catch (e) {}
      }
    } catch (e) {
      print(e);
      logger.e('report back ex:', e);
    }
  }

  //根据缓存实例化报告信息
  void initReportInfoFromJson(ReportInfoItem reportCache) {
    try {
      final jsonStr = reportCache.reportInfoJson;
      final templateJson = reportCache.reportTemplateJson;

      ///应缓存reportTemplateJson,初始化时就选择指定模板
      if (state.selectedTemplate.reportTemplateJson != templateJson) {
        state.selectedTemplate.reportTemplateJson = templateJson;
        FReportInfo.instance.reload(
          Store.user.fullName ?? '',
          DateTime.now(),
          templateJson,
          controller.onSelect,
          i18nBook.common.revoke.t,
          i18nBook.remedical.selectWord.t,
          i18nBook.remedical.clickAndSelectImage.t,
        );
      }
      final json = jsonDecode(jsonStr) as List<dynamic>;
      FReportInfo.instance.fromJson(json);
    } catch (e) {
      print(e);
      logger.e('ReportEditController _initReportInfoFromJson ex:', e);
    }
  }

  void dispose() {
    if (_timer != null) {
      _timer!.cancel();
      _timer = null;
    }
  }
}
