import 'dart:convert';

import 'package:fis_jsonrpc/services/patient.m.dart';
import 'package:vital_local_database/core/interface/queryable.dart';
import 'package:vitalapp/database/db.dart';
import 'package:vitalapp/database/entities/defines.dart';
import 'package:vitalapp/database/entities/patient.dart';
import 'package:vitalapp/managers/adapters/offline/patient.dart';
import 'package:vitalapp/managers/interfaces/models/common.dart';
import 'package:vitalapp/rpc.dart';
import 'package:vitalapp/store/store.dart';
import 'interfaces/data_sync.dart';
import 'package:fis_common/logger/logger.dart';

class DataSyncManager implements IDataSyncManager {
  @override
  Future<PagedDataCollection<PatientEntity>> getPatientPagedList(
    int pageIndex, {
    int pageSize = 50,
    OfflineDataSyncState? syncState,
  }) async {
    try {
      final query = db.repositories.patient.queryable.where((x) {
        final list = <IDbColumnCondition>[];
        list.add(x.isValid.equals(true));
        list.add(x.userCode.equals(Store.user.userCode)); //添加用户code
        if (syncState != null) {
          list.add(x.syncState.equals(syncState));
        }
        return list;
      });
      final count = await query.count();
      final offset = pageSize * (pageIndex - 1);
      final entities = await query.offset(offset).limit(pageSize).toList();
      return PagedDataCollection<PatientEntity>(
        totalCount: count,
        pageIndex: pageIndex,
        pageSize: pageSize,
        data: entities,
      );
    } catch (e) {
      logger.e("DataSyncManager getPatientPagedList error.", e);
      return PagedDataCollection<PatientEntity>(
        totalCount: 0,
        pageIndex: pageIndex,
        pageSize: pageSize,
        data: [],
      );
    }
  }

  @override
  Future<bool> syncPatient(PatientEntity entity) async {
    try {
      final jsonMap = jsonDecode(entity.dataJson);
      final dto = PatientDTO.fromJson(jsonMap);

      bool syncResult = false;
      if (entity.syncType == OfflineDataSyncType.create) {
        final request = PatientDtoConverter.dto2Create(dto);
        request.token = Store.user.token;
        final code = await rpc.patient.createPatientAsync(request);
        syncResult = code.isNotEmpty;
      } else {
        final request = PatientDtoConverter.dto2Update(dto);
        request.token = Store.user.token;
        syncResult = await rpc.patient.updatePatientAsync(request);
      }

      entity.syncState =
          syncResult ? OfflineDataSyncState.success : OfflineDataSyncState.fail;
      await db.repositories.patient.update(entity);

      return syncResult;
    } catch (e) {
      logger.e("DataSyncManager syncPatient error.", e);
      return false;
    }
  }
}
