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

namespace adas_core.Application.Repositories.Interfaces;

public interface IPumpAlarmStateRepository
{
    /// <summary>
    /// Asynchronously retrieves the active alarm state for a specified device, optionally filtered by alarm type and alarm code.
    /// Returns <c>null</c> when no matching active alarm state is found.
    /// </summary>
    /// <param name="deviceId">The identifier of the device whose active alarm state is being queried.</param>
    /// <param name="alarmType">The optional alarm type to filter the search by; if <c>null</c>, no alarm type filter is applied.</param>
    /// <param name="alarmCodeMdc">The optional MDC alarm code to further filter the search; if <c>null</c>, no alarm code filter is applied.</param>
    /// <returns>A <see cref="Task{TResult}"/> containing the active <see cref="PumpAlarmState"/>, or <c>null</c> if no matching active alarm state exists.</returns>
    Task<PumpAlarmState?> FindActiveAsync(
            string deviceId,
            PumpEnum.AlarmType? alarmType,
            string? alarmCodeMdc = null);

    /// <summary>
    /// Asynchronously retrieves all active pump alarm states associated with the specified device.
    /// </summary>
    /// <param name="deviceId">The unique identifier of the device whose active pump alarm states are being queried.</param>
    /// <returns>A task representing the asynchronous operation, containing a collection of active <see cref="PumpAlarmState"/> entries for the given device.</returns>
    Task<IEnumerable<PumpAlarmState>> FindAllActiveByDeviceAsync(string deviceId);

    /// <summary>
    /// Inserts a new active pump alarm state or updates the existing one, maintaining the current state for the alarm.
    /// </summary>
    /// <param name="state">The pump alarm state to upsert as the active record.</param>
    Task UpsertActiveAsync(PumpAlarmState state);

    /// <summary>
    /// Asynchronously removes alarm records associated with the specified device, optionally filtered by alarm type and alarm code.
    /// </summary>
    /// <param name="deviceId">The identifier of the device whose alarms should be removed.</param>
    /// <param name="alarmType">The optional alarm type to filter the removal; when null, all alarm types are considered.</param>
    /// <param name="alarmCodeMdc">The optional alarm code (MDC) to further filter the removal; when null, no code filter is applied.</param>
    Task RemoveAsync(
            string deviceId,
            PumpEnum.AlarmType? alarmType,
            string? alarmCodeMdc = null);

    //cleanup
    /// <summary>
    /// Deletes records associated with the specified patient identifier.
    /// </summary>
    /// <param name="patientId">The unique identifier of the patient whose related records should be removed.</param>
    Task DeleteByPatientId(ObjectId patientId);
    
    /// <summary>
    /// Asynchronously updates the <see cref="ObjectId"/> value in multiple documents identified by the specified field name, replacing <paramref name="oldId"/> with <paramref name="newId"/>, and returns the number of documents affected.
    /// </summary>
    /// <param name="fieldName">The name of the field whose value will be updated.</param>
    /// <param name="newId">The new <see cref="ObjectId"/> value to assign.</param>
    /// <param name="oldId">The existing <see cref="ObjectId"/> value to be replaced.</param>
    /// <returns>A <see cref="Task{T}"/> that represents the asynchronous operation. The task result contains the number of documents updated.</returns>
    Task<long> UpdateManyObjectIdByFieldNameAsync(string fieldName, ObjectId newId, ObjectId oldId);
}