import 'dart:convert';
import 'package:fis_jsonrpc/rpc.dart';
import 'package:get/get.dart';
import 'package:vital_local_database/core/index.dart';
import 'package:vitalapp/consts/diagnosis.dart';
import 'package:vitalapp/database/db.dart';
import 'package:vitalapp/database/entities/defines.dart';
import 'package:vitalapp/database/entities/diagnosis.dart';
import 'package:vitalapp/database/entities/patient.dart';
import 'package:vitalapp/global.dart';
import 'package:vitalapp/managers/interfaces/diagnosis.dart';
import 'package:vitalapp/managers/interfaces/dictionary.dart';
import 'package:vitalapp/managers/interfaces/models/diagnosis_aggregation_record_model.dart';
import 'package:vitalapp/rpc.dart';
import 'package:vitalapp/store/store.dart';
import 'package:fis_common/logger/logger.dart';

class DiagnosisManager implements IDiagnosisManager {
  DiagnosisManager();

  @override
  Future<PageCollection<DiagnosisAggregationRecordModel>?>
      getDiagnosisAggregationPageAsync(
          String patientCode, int pageIndex, int pageSize) async {
    PageCollection<DiagnosisAggregationRecordModel> diagnosisAggregationRecord =
        PageCollection<DiagnosisAggregationRecordModel>();
    try {
      var request = DiagnosisPageRequest(
        token: Store.user.token,
        pageIndex: pageIndex,
        pageSize: pageSize,
        patientCode: patientCode,
      );
      diagnosisAggregationRecord.pageData = [];
      var result =
          await rpc.diagnosis.getDiagnosisAggregationPageAsync(request);
      diagnosisAggregationRecord.pageIndex = result.pageIndex;
      diagnosisAggregationRecord.pageSize = result.pageSize;
      diagnosisAggregationRecord.dataCount = result.dataCount;
      for (var element in result.pageData!) {
        var record = DiagnosisAggregationRecordModel.fromJson(element.toJson());
        record.isExistLocalData = false;
        diagnosisAggregationRecord.pageData!.add(record);
      }
    } catch (e) {}
    return diagnosisAggregationRecord;
  }

  @override
  Future<List<DiagnosisAggregationRecordModel>?> getListByPatientCode(
      String patientCode) async {
    try {
      List<DiagnosisAggregationRecordModel> records =
          <DiagnosisAggregationRecordModel>[];
      List<DiagnosisEntity> localRecords = [];
      localRecords = await db.repositories.diagnosis
          .getNotUploadedListByPatientCode(patientCode, Store.user.userCode!);
      if (!kIsOnline) {
        localRecords = await db.repositories.diagnosis
            .getListByPatientCode(patientCode, userCode: Store.user.userCode!);
      }
      var currentPatient = Store.user.currentSelectPatientInfo!;
      for (var element in localRecords) {
        Map<String, dynamic> data = jsonDecode(element.dataJson);
        List<DiagnosisAggregationData> list = [];
        for (var key in data.keys) {
          list.add(DiagnosisAggregationData(
              key: key, diagnosisData: jsonEncode(data[key])));
        }
        records.add(DiagnosisAggregationRecordModel(
          patientCode: element.patientCode,
          patientName: currentPatient.patientName,
          doctorName: Store.user.displayName,
          diagnosisTime: element.createTime,
          diagnosisAggregationData: list,
          isExistLocalData: element.syncState != OfflineDataSyncState.success,
        ));
      }
      return records;
    } catch (e) {}
    return null;
  }

  /// 创建健康检测
  @override
  Future<bool> submitDiagnosisAsync(SubmitDiagnosisRequest request) async {
    request.token = Store.user.token;
    print(jsonEncode(request.toJson()));
    var result = await rpc.diagnosis.submitDiagnosisAsync(request);

    return result;
  }

  /// 创建健康检测（在线）
  @override
  Future<bool> syncPatientAndDiagnosisData(
      SyncPatientAndDiagnosisDataRequest request) async {
    try {
      var result = await rpc.diagnosis.syncPatientAndDiagnosisDataAsync(
        request,
      );
      if (result) {
        final code = request.cardNo!;
        var existEntity = await _checkPatientExist(code);

        if (existEntity != null) {
          existEntity.syncState = OfflineDataSyncState.success;
          await db.repositories.patient.update(existEntity);
        }
      }
      return result;
    } catch (e) {
      logger.e(
          "syncPatientAndDiagnosisData - Check patient exist error. Code: ${request.cardNo}.",
          e);
      return false;
    }
  }

  Future<PatientEntity?> _checkPatientExist(String code) async {
    try {
      final entity = await db.repositories.patient
          .singleByCode(code, Store.user.userCode!);
      return entity;
    } catch (e) {
      logger.e(
          "PatientServiceMock - Check patient exist error. Code: $code.", e);
    }
    return null;
  }

  ///获取所有userCode为空的数据，并赋值
  @override
  Future<void> resettingUsercodeIsEmptyData() async {
    var version = await db.database.getVersion();
    if (version > 0) {
      final list = await db.repositories.diagnosis.queryable.where((x) {
        final List<IDbColumnCondition> arr = [];
        arr.add(x.isValid.equals(true));
        arr.add(x.userCode.equals(''));
        return arr;
      }).toList();
      logger.w(
          "DiagnosisManager resettingUsercodeIsEmptyData list.count:${list.length}.");
      for (var element in list) {
        if (element.syncState == OfflineDataSyncState.success) {
          var result = await getDiagnosisAggregationPageAsync(
              element.patientCode, 1, 1000);
          if (result != null && result.pageData != null) {
            var diagnosisAggregationRecord = result.pageData!
                .firstWhereOrNull((x) => x.appDataId == element.code);
            if (diagnosisAggregationRecord != null) {
              element.userCode = diagnosisAggregationRecord.doctorCode ?? '';
            }
          }
        } else {
          element.userCode = Store.user.userCode!;
        }
        await db.repositories.diagnosis.update(element);
      }
    }
  }

  @override
  Future<List<List<String>>> getTableData(DiagnosisAggregationRecordModel dto,
      {bool isLastRecord = false}) async {
    var currentDiagnosis = <List<String>>[];
    var index = 1;
    for (var element in dto.diagnosisAggregationData!) {
      if (element.diagnosisData != "null") {
        var jsonData = json.decode(element.diagnosisData!);
        List<String> keys = jsonData.keys.toList();

        List<DictionaryWithUnitDTO>? dtos = [];
        if (!kIsOnline) {
          for (var key in keys) {
            dtos.add(DictionaryWithUnitDTO(
                key: key,
                name: DiagnosisTranslator.reportTr(key),
                unit: DiagnosisTranslator.getExamUnit(key)));
          }
        } else {
          dtos = await Get.find<IDictionaryManager>()
                  .getDictionaryNameAndUnitByKeysAsync(keys) ??
              [];
        }

        for (var key in keys) {
          if (key == "ECG_POINT" || key == "ECG_POINT12") {
            continue;
          }
          var dto = dtos.firstWhereOrNull((item) => item.key == key);
          final value = jsonData[key].toString();
          if (value.isEmpty) {
            // 不展示空值
            continue;
          }
          currentDiagnosis.add([
            if (!isLastRecord) (index++).toString(),
            dto?.name ?? '',
            value,
            dto?.unit ?? '',
          ]);
        }
      }
    }
    return currentDiagnosis;
  }
}
