import 'dart:convert';
import 'dart:io';
import 'package:fis_jsonrpc/rpc.dart';
import 'package:vital_local_database/core/index.dart';
import 'package:vitalapp/architecture/storage/storage.dart';
import 'package:vitalapp/architecture/utils/upload.dart';
import 'package:vitalapp/database/entities/defines.dart';
import 'package:vitalapp/database/entities/diagnosis.dart';
import 'package:vitalapp/rpc.dart';
import 'package:vitalapp/store/store.dart';
import 'package:vitalapp/database/db.dart';
import 'interfaces/record_data_cache.dart';
import 'package:fis_common/logger/logger.dart';

class RecordDataCacheManager implements IRecordDataCacheManager {
  @override
  Future<bool> saveRecordData(
    String appDataId,
    String patientCode,
    Map<String, dynamic> diagnosisDataValue,
  ) async {
    try {
      String data = jsonEncode(diagnosisDataValue);

      ///更新内存缓存
      Store.resident.handleSaveMedicalData(data);

      var existData = await db.repositories.diagnosis.queryable
          .where((x) => [
                x.code.equals(appDataId),
                x.userCode.equals(Store.user.userCode), //添加用户Code
              ])
          .first();

      if (existData != null) {
        existData.isValid = true;
        existData.dataJson = data;
        existData.patientCode = patientCode;
        existData.syncState = OfflineDataSyncState.success;
        //更新数据库
        await db.repositories.diagnosis.update(existData);
      } else {
        final entity = DiagnosisEntity();
        entity.code = appDataId;
        entity.isValid = true;
        entity.dataJson = data;
        entity.patientCode = patientCode;
        entity.userCode = Store.user.userCode!; //添加用户Code
        entity.syncState = OfflineDataSyncState.wait;
        //新增数据
        await db.repositories.diagnosis.insert(entity);
      }

      return true;
    } catch (e) {
      logger.e('RecordDataCacheManager saveRecordData ex:', e);
    }
    return false;
  }

  ///更新记录状态
  @override
  Future<bool> recordSyncStateChange(
    String appDataId, {
    OfflineDataSyncState state = OfflineDataSyncState.success,
  }) async {
    try {
      var existData = await db.repositories.diagnosis.queryable
          .where((x) => [
                x.code.equals(appDataId),
                x.userCode.equals(Store.user.userCode), //添加用户code
              ])
          .first();
      if (existData != null) {
        existData.syncState = state;
        //更新数据库
        await db.repositories.diagnosis.update(existData);
      }
    } catch (e) {
      logger.e('RecordDataCacheManager recordSyncStateChange ex:', e);
    }
    return false;
  }

  ///根据病人Code与用户Code获取最近一条检查记录
  @override
  Future<DiagnosisEntity?> getLastRecordByPatientCode(
      String patientCode) async {
    var existDatas = db.repositories.diagnosis.queryable.where((x) => [
          x.patientCode.equals(patientCode),
          x.userCode.equals(Store.user.userCode), //添加用户code
        ]);
    var updateTimeData = await existDatas
        .orderBy((x) => x.updateTime, DbOrderByType.desc)
        .first();
    var createTimeData = await existDatas
        .orderBy((x) => x.createTime, DbOrderByType.desc)
        .first();
    if (updateTimeData != null && createTimeData != null) {
      final now = DateTime.now();

      ///如果存在更新时间的数据，则需要比较和创建时间哪个更新
      final diff1 = (updateTimeData.updateTime ?? DateTime(1970, 1, 1, 0, 0, 0))
          .difference(now);
      final diff2 = createTimeData.createTime.difference(now);
      if (diff1.abs() < diff2.abs()) {
        return updateTimeData;
      } else {
        return createTimeData;
      }
    } else if (createTimeData != null) {
      //如果不存在更新时间的数据，则直接返回创建时间的
      return createTimeData;
    }
    return null;
  }

  @override
  Future<List<DiagnosisEntity>> getNoSubmitRecords(String patientCode) async {
    List<DiagnosisEntity> result = [];
    try {
      result = await db.repositories.diagnosis.queryable
          .where((x) => [
                x.syncState.equals(OfflineDataSyncState.wait),
                x.patientCode.equals(patientCode),
                x.userCode.equals(Store.user.userCode), //添加用户code
              ])
          .toList();
    } catch (e) {
      logger.e('RecordDataCacheManager getRecordsByPatientCode ex:', e);
    }
    return result;
  }

  @override
  Future<List<DiagnosisItem>> convertDiagnosisDataToList(
      Map<String, dynamic> diagnosisDataValue) async {
    List<DiagnosisItem> diagnosisItems = [];
    for (var entry in diagnosisDataValue.entries) {
      var key = entry.key;
      var value = entry.value;
      if (value != null) {
        Store.app.setBusy("提交中");
        if (['Heart', 'TwelveHeart'].contains(key) && value is Map) {
          value = await uploadData(value);
        }
        Store.app.busy = false;
        diagnosisItems.add(
          DiagnosisItem(
            key: key,
            diagnosisData: jsonEncode(value),
          ),
        );
      }
      print('$key: $value');
    }
    Store.app.busy = false;
    return diagnosisItems;
  }

  @override
  Future<List<DiagnosisItem>> verifyDiagnosisDataList(
      Map<String, dynamic> diagnosisDataValue) async {
    List<DiagnosisItem> diagnosisItems = [];
    for (var entry in diagnosisDataValue.entries) {
      var key = entry.key;
      var value = entry.value;
      if (value != null) {
        if (['Heart', 'TwelveHeart'].contains(key) && value is Map) {
          if (value.isEmpty) {
            continue;
          }
        }
        diagnosisItems.add(
          DiagnosisItem(
            key: key,
            diagnosisData: jsonEncode(value),
          ),
        );
      }
      print('$key: $value');
    }
    return diagnosisItems;
  }

  bool isUploaded(String url) {
    return url.startsWith('https://') || url.startsWith('http://');
  }

  Future<Map> uploadData(Map data) async {
    if (data['ECG_POINT'] != null && !isUploaded(data['ECG_POINT'])) {
      File ecgPointFile =
          await rpc.storage.writeStringToFile(data['ECG_POINT']);
      String? ecgPointUrl = await rpc.storage.uploadFile(ecgPointFile);
      data['ECG_POINT'] = ecgPointUrl ?? '';
      // ... 上传点集
    }
    if (data['ECG'] != null && !isUploaded(data['ECG'])) {
      // ... 上传图片
      /// 图片地址
      final imageFile = UploadUtils.convertBase64ToXFile(data['ECG']);
      String? imageUrl = await rpc.storage.upload(imageFile!);
      data['ECG'] = imageUrl ?? '';
    }
    if (data['ECG_POINT12'] != null && !isUploaded(data['ECG_POINT12'])) {
      File ecgPointFile =
          await rpc.storage.writeStringToFile(data['ECG_POINT12']);
      String? ecgPointUrl = await rpc.storage.uploadFile(ecgPointFile);
      data['ECG_POINT12'] = ecgPointUrl ?? '';
      // ... 上传点集
    }
    if (data['ECG12'] != null && !isUploaded(data['ECG12'])) {
      // ... 上传图片
      final imageFile = UploadUtils.convertBase64ToXFile(data['ECG12']);
      String? imageUrl = await rpc.storage.upload(imageFile!);
      data['ECG12'] = imageUrl ?? '';
    }
    return data;
  }
}
