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

namespace adas_core.Application.Repositories.Interfaces;

public interface IDiagnosisRepository : IMongoRepository<PatientDiagnosis>
{
    /// <summary>
    /// Asynchronously retrieves a list of patient diagnoses associated with the specified patient identifier.
    /// </summary>
    /// <param name="patientId">The unique identifier of the patient whose diagnoses are to be retrieved.</param>
    /// <returns>A task that represents the asynchronous operation, containing a list of <see cref="PatientDiagnosis"/> objects for the specified patient.</returns>
    Task<List<PatientDiagnosis>> GetByPatient(ObjectId patientId);

    /// <summary>
    /// Asynchronously inserts a single patient diagnosis record into the data store.
    /// </summary>
    /// <param name="diagnosis">The patient diagnosis entity to insert.</param>
    new Task InsertOneAsync(PatientDiagnosis diagnosis);
    /// <summary>
    /// Asynchronously deletes the entity identified by the specified identifier.
    /// </summary>
    /// <param name="id">The unique identifier of the entity to delete.</param>
    new Task DeleteAsync(ObjectId id);
    /// <summary>
    /// Updates many records by replacing the existing <see cref="ObjectId"/> identified by <paramref name="oldId"/> with the new <see cref="ObjectId"/> <paramref name="id"/>, scoped to the specified <paramref name="nameId"/>.
    /// </summary>
    /// <param name="nameId">The identifier of the field or collection on which the update is performed.</param>
    /// <param name="id">The new <see cref="ObjectId"/> value to assign.</param>
    /// <param name="oldId">The existing <see cref="ObjectId"/> value to be replaced.</param>
    Task UpdateManyObjectId(string nameId, ObjectId id, ObjectId oldId);
    /// <summary>
    /// Asynchronously finds all patient diagnoses associated with the specified patient identifier, returning a cursor to iterate over the matching documents.
    /// </summary>
    /// <param name="patientId">The unique identifier of the patient whose diagnoses should be retrieved.</param>
    /// <returns>A task that represents the asynchronous operation, containing an IAsyncCursor of PatientDiagnosis that yields the matching documents.</returns>
    Task<IAsyncCursor<PatientDiagnosis>> FindByPatientIdAsync(ObjectId patientId);
    /// <summary>
    /// Asynchronously deletes records associated with the specified patient identifier.
    /// </summary>
    /// <param name="patientId">The unique <see cref="ObjectId"/> of the patient whose related records should be removed.</param>
    Task DeleteByPatientId(ObjectId patientId);
    /// <summary>
    /// Asynchronously retrieves the <see cref="PatientDiagnosis"/> associated with the specified patient, diagnosis code, and coding system.
    /// Returns null when no matching diagnosis is found.
    /// </summary>
    /// <param name="patientId">The unique identifier of the patient whose diagnosis is being looked up.</param>
    /// <param name="diagnosisCode">The diagnosis code to match. May be null.</param>
    /// <param name="codingSystem">The coding system of the diagnosis code (for example, ICD-10 or SNOMED). May be null.</param>
    /// <returns>A task that resolves to the matching <see cref="PatientDiagnosis"/>, or null if no diagnosis matches the given criteria.</returns>
    Task<PatientDiagnosis?> FindByPatientIdAndCode(ObjectId patientId, string? diagnosisCode, string? codingSystem);
}