using adas_core.Domain.Models;
using MongoDB.Bson;

namespace adas_core.Application.Repositories.Interfaces;

public interface IObservationArchiveRepository : IMongoRepository<PatientObservation>
{
    /// <summary>
    /// Asynchronously inserts a single <see cref="PatientObservation"/> into the data store.
    /// </summary>
    /// <param name="patientObservation">The patient observation to insert.</param>
    new Task InsertOneAsync(PatientObservation patientObservation);
    /// <summary>
    /// Deletes the records that have a date earlier than the specified cutoff date.
    /// </summary>
    /// <param name="date">The cutoff date; records dated before this value will be removed.</param>
    Task DeleteBeforeDate(DateTime date);
    /// <summary>
    /// Asynchronously inserts a batch of patient observation records into the underlying data store.
    /// </summary>
    /// <param name="observations">The collection of <see cref="PatientObservation"/> entities to be inserted.</param>
    /// <returns>A <see cref="Task{TResult}"/> that represents the asynchronous insert operation, returning a <see cref="long"/> value (such as the number of affected rows or a generated identifier) produced by the batch insertion.</returns>
    Task<long> InsertBatch(IEnumerable<PatientObservation> observations);

    /// <summary>
    /// Retrieves the most recent aggregated patient observations for the specified patient, limited by a count and an upper date bound, and optionally filtered by observation names.
    /// </summary>
    /// <param name="patientId">The unique identifier of the patient whose observations are being queried.</param>
    /// <param name="num">The maximum number of recent observations to return.</param>
    /// <param name="lastDate">The cutoff date; only observations on or before this date are considered.</param>
    /// <param name="filterObservations">An optional list of observation names to restrict the results to; pass an empty or null list to include all observations.</param>
    /// <returns>A task that resolves to a list of <see cref="PatientObservation"/> entries representing the aggregated last observations matching the criteria.</returns>
    Task<List<PatientObservation>> AggregatedPatientLastObservations(ObjectId patientId, int num, DateTime lastDate,
            List<string> filterObservations);

    /// <summary>
    /// Retrieves all patient observations associated with the specified patient.
    /// </summary>
    /// <param name="patientId">The identifier of the patient whose observations are being retrieved.</param>
    /// <returns>A task that represents the asynchronous operation, containing a list of <see cref="PatientObservation"/> records for the patient.</returns>
    Task<List<PatientObservation>> FindAllFromPatient(ObjectId patientId);
}