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/global.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)])
          .first();

      if (existData != null) {
        existData.isValid = true;
        existData.dataJson = data;
        existData.patientCode = patientCode;
        existData.syncState = OfflineDataSyncState.wait;
        //更新数据库
        await db.repositories.diagnosis.update(existData);
      } else {
        final entity = DiagnosisEntity();
        entity.code = appDataId;
        entity.isValid = true;
        entity.dataJson = data;
        entity.patientCode = patientCode;
        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)])
          .first();
      if (existData != null) {
        existData.syncState = state;
        //更新数据库
        await db.repositories.diagnosis.update(existData);
      }
    } catch (e) {
      logger.e('RecordDataCacheManager recordSyncStateChange ex:', e);
    }
    return false;
  }

  ///根据病人Code获取最近一条检查记录
  @override
  Future<Map<String, dynamic>?> getLastRecordByPatientCode(
      String patientCode) async {
    var existDatas = db.repositories.diagnosis.queryable
        .where((x) => [x.patientCode.equals(patientCode)]);
    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 jsonDecode(updateTimeData.dataJson);
      } else {
        return jsonDecode(createTimeData.dataJson);
      }
    } else if (createTimeData != null) {
      //如果不存在更新时间的数据，则直接返回创建时间的
      return jsonDecode(createTimeData.dataJson);
    }
    return null;
  }

  ///根据病人Code获取最近一条检查记录
  @override
  Future<List<DiagnosisEntity>> getNoSubmitRecords() async {
    List<DiagnosisEntity> result = [];
    try {
      result = await db.repositories.diagnosis.queryable
          .where((x) => [x.syncState.equals(OfflineDataSyncState.wait)])
          .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) {
        if (key == 'Heart' && value is Map) {
          if (value.isEmpty) {
            return [];
          }
          if (kIsOnline) {
            String allPoint = value['ECG_POINT'];
            String imageBase64 = value['ECG'];

            /// 点集地址
            File ecgPointFile = await rpc.storage.writeStringToFile(allPoint);
            String? ecgPointUrl = await rpc.storage.uploadFile(ecgPointFile);

            /// 图片地址
            final imageFile = UploadUtils.convertBase64ToXFile(imageBase64);
            String? imageUrl = await rpc.storage.upload(imageFile!);

            value['ECG_POINT'] = ecgPointUrl ?? '';
            value['ECG'] = imageUrl ?? '';
          }
        }
        diagnosisItems.add(
          DiagnosisItem(
            key: key,
            diagnosisData: jsonEncode(value),
          ),
        );
      }
      print('$key: $value');
    }
    return diagnosisItems;
  }
}
