using adas_core.Domain.Models;
using adas_core.Domain.Models.Filter;
using adas_core.Domain.Models.GroupedObservations;
using adas_core.Domain.Models.MongoModels;
using MongoDB.Bson;
using MongoDB.Driver;

namespace adas_core.Application.Repositories.Interfaces;

public interface IObservationRepository : IMongoRepository<PatientObservation>
{
    Task<List<BsonDocument>> AggregatedPatientGroupedObservations(ObjectId patientId, GroupedField groupedField);

    Task<List<PatientObservation>> AggregatedPatientLastObservations(ObjectId patientId, int num,
        List<string>? filterObservations = null);

    Task<List<PatientObservation>> AggregatedPatientLastObservationsByLastDate(ObjectId patientId, int num,
        DateTime lastDate, List<string>? filterObservations = null);

    Task<List<PatientObservation>> AggregatedPatientLastObservationsByField(ObjectId patientId,
        List<Field>? filterObservations = null);

    Task<IEnumerable<PatientObservation>> FindLastObservations(ObjectId patientId, string codingSystem, string code,
        int num = 2);

    Task<List<PatientObservation>> FindLastObservationsByCodingSystem(ObjectId patientId, string codingSystem,
        int num = 10);

    Task<PatientObservation?> FindLastObservationBeforeDate(ObjectId patientId, string? name, DateTime date);

    Task UpdateExpiredObservations(List<PatientObservation> expiredObservations);

    Task<List<PatientObservation>?> FindAnyWithSameDate(ObjectId patientId, string? name, DateTime date);
    Task<List<PatientObservation>> FindAnyBeforeDate(ObjectId patientId, DateTime date);

    Task<List<PatientObservation>> FindLatestUniqueValuesByName(ObjectId patientId, string name, int? expires);

    new Task InsertOneAsync(PatientObservation patientObservation);
    Task DeleteByPatientId(ObjectId id);
    Task<IAsyncCursor<PatientObservation>> FindByPatientIdAsync(ObjectId patientId);

    Task<IAsyncCursor<PatientObservation>> FindByPatientIdAndCodingSystemAsync(ObjectId patientId, string codingSystem,
        string name);

    new Task DeleteAsync(ObjectId id);
    Task<List<PatientObservation>> DeleteOlderDaysAsync(string name, int retentionPolicyValue);
    Task<List<PatientObservation>> DeleteOlderNumberAsync(string name, int retentionPolicyValue);
    Task<bool> ExistBySystemId(ObjectId patientid, string systemId);
    Task<List<PatientObservation>> DeleteOlderSecondsAsync(string name, int value);
    Task<List<PatientObservation?>> AggregatedPatientActiveIntravenousLinesObservations(ObjectId patientId);
    Task<Dictionary<ObjectId, DateTime>> FindAllLastPatientObservationTime();

    Task<PatientObservation?> FindById(ObjectId id);

    Task<List<PatientObservation>?> FindByPatientId(ObjectId id);
    Task Update(PatientObservation observation);
    Task UpdateManyObjectId(string nameId, ObjectId id, ObjectId oldId);

    Task<IEnumerable<PatientObservation>> FindNotExpired(List<string?>? filterObservations);

    Task<IEnumerable<PatientObservation>> FindByName(string name, DateTime? date);

    Task UpdateMany(IEnumerable<PatientObservation> patientObservations, UpdateDefinition<PatientObservation> update);

    Task<IEnumerable<PatientObservation>> FindAll();

    Task ExpireExpiredObservations(List<ConfigObservation> configObservationsToExpire);
    //Task<PaginationResponse<PatientObservation>> GetPaginatedObservations(PaginationFilter filter);

    IFindFluent<PatientObservation, PatientObservation> GetPaginatedObservations(PaginationFilter filter);

    Task<IEnumerable<PatientObservation>> FindLastNotExpiredObservatonsByPatient(ObjectId patientId, string name,
        int? endAfter = null, int? num = null);
}