using adas_core.Application.Subscriptions;
using adas_core.Domain.Models;
using adas_core.Domain.Models.GroupedObservations;
using MongoDB.Bson;

namespace adas_core.Application.Services.Interfaces;

public interface ISubscriberGroupedService
{
    /// <summary>
    /// Retrieves a list of subscribers organized into groups.
    /// </summary>
    /// <returns>A list of <see cref="WsSubscriberGrouped"/> instances representing the grouped subscribers.</returns>
    List<WsSubscriberGrouped> GetGrouped();
    /// <summary>
    /// Removes grouped observations associated with the specified patient identifier.
    /// </summary>
    /// <param name="patientId">The unique identifier of the patient whose grouped observations should be removed.</param>
    void RemoveGroupedObsByPatientId(string patientId);
    /// <summary>
    /// Removes a WebSocket subscriber associated with the specified patient based on the provided location.
    /// </summary>
    /// <param name="patientId">The identifier of the patient whose WebSocket subscriber should be removed.</param>
    /// <param name="newLocation">The new patient location used to identify the subscriber to remove, or null to remove without location filtering.</param>
    void RemoveWsSubscriberByLocation(string patientId, PatientLocation? newLocation);
    /// <summary>
    /// Removes the specified workstation identifier associated with a patient's WS subscriber entry.
    /// </summary>
    /// <param name="patientId">The identifier of the patient whose WS subscriber entry will be updated.</param>
    /// <param name="wsIdToRemove">The workstation identifier to remove from the patient's WS subscriber entry.</param>
    void RemoveWsSubscriberPatientIdAndWsId(string patientId, string wsIdToRemove);
    /// <summary>
    /// Validates the provided <see cref="WsSubscriberGrouped"/> instance to identify empty subscriber groups.
    /// </summary>
    /// <param name="wsl">The subscriber group instance to be checked for empty groups.</param>
    /// <returns>A <see cref="List{String}"/> containing validation messages for any empty subscriber groups found; returns an empty list if all groups are valid.</returns>
    List<string> CheckEmptySubscriberGroup(WsSubscriberGrouped wsl);
    /// <summary>
    /// Adds a new subscriber together with its associated group information to the system.
    /// </summary>
    /// <param name="wsSubscriberGrouped">The web service representation of the subscriber and its group assignments to be added.</param>
    void AddSubscriberGrouped(WsSubscriberGrouped wsSubscriberGrouped);

    /// <summary>
    /// Checks subscription-related conditions for a grouped field and its associated grouped observation.
    /// </summary>
    /// <param name="groupedField">The grouped field to evaluate.</param>
    /// <param name="patientId">The identifier of the patient associated with the observation.</param>
    /// <param name="timeZoneId">The time zone identifier used for the observation context.</param>
    /// <param name="connectionId">The connection identifier for the current request or session.</param>
    /// <param name="go">The grouped observation to be checked against the subscription.</param>
    void CheckOnSubscriptionGroup(GroupedField groupedField, ObjectId patientId, string timeZoneId, string connectionId,
            GroupedObservation go);

    /// <summary>
    /// Updates the most recent grouped observation in the group identified by the specified hash code with the new grouped observation.
    /// </summary>
    /// <param name="wsgHashCode">The hash code identifying the group whose last grouped observation should be updated.</param>
    /// <param name="newGroupedObservation">The new grouped observation to set as the last grouped observation in the group.</param>
    void UpdateLastGroupedObsInGroup(string wsgHashCode, GroupedObservation newGroupedObservation);
}