using adas_core.Domain.Enums;
using adas_core.Domain.Models;
using adas_core.Domain.Models.Filter;
using adas_core.Domain.Models.MongoModels;
using adas_core.Domain.Models.Responses;
using MongoDB.Bson;

namespace adas_core.Application.Services.Interfaces;

public interface ILightBeaconService
{
    /// <summary>
    /// Sends the specified color command to the light beacon associated with the given point of control identifier.
    /// </summary>
    /// <param name="pocId">The identifier of the point of control that targets the light beacon.</param>
    /// <param name="color">The color to apply to the light beacon.</param>
    Task SendColor(ObjectId pocId, LightBeaconColor color);
    /// <summary>
    /// Sends a color command to the light beacon of the specified point of care device,
    /// updating its visual indicator to reflect the requested state.
    /// </summary>
    /// <param name="pocId">The identifier of the point of care device whose light beacon will be updated.</param>
    /// <param name="color">The color to apply to the light beacon.</param>
    /// <returns>A task that represents the asynchronous color send operation.</returns>
    Task SendColor(PointOfCare pocId, LightBeaconColor color);
    /// <summary>
    /// Sends a light beacon broadcast for the specified point of care, setting the beacon to display the specified color.
    /// </summary>
    /// <param name="poc">The point of care device or location whose beacon will be updated.</param>
    /// <param name="color">The color to display on the light beacon.</param>
    Task SendBeaconBroadcast(PointOfCare poc, LightBeaconColor color);
    /// <summary>
    /// Sends a broadcast signal to the beacon associated with the specified point of care identifier using the given beacon color.
    /// </summary>
    /// <param name="poc">The identifier of the point of care (or beacon) that will receive the broadcast.</param>
    /// <param name="color">The color of the light beacon used for the broadcast.</param>
    Task SendBeaconBroadcast(ObjectId poc, LightBeaconColor color);
    /// <summary>
    /// Asynchronously powers off the LED associated with the specified point of connection identifier.
    /// </summary>
    /// <param name="pocId">The identifier of the point of connection whose LED will be turned off.</param>
    Task PowerOffLed(ObjectId pocId);
    /// <summary>
    /// Asynchronously powers off the LED indicator associated with the specified point of care.
    /// </summary>
    /// <param name="poc">The point of care whose LED indicator should be turned off.</param>
    Task PowerOffLed(PointOfCare poc);

    /// <summary>
    /// Generates a color-coded alert based on the provided patient observation.
    /// </summary>
    /// <param name="obs">The patient observation used to determine the alert level and color.</param>
    void GenerateColorAlert(PatientObservation obs);

    //TODO refactor, one patient can have multiple beacons
    /// <summary>
    /// Asynchronously retrieves the <see cref="LightBeaconColor"/> associated with the specified point of care identifier.
    /// </summary>
    /// <param name="pocId">The identifier of the point of care whose light beacon color is being requested.</param>
    /// <returns>A task that represents the asynchronous operation, containing the <see cref="LightBeaconColor"/> for the specified point of care.</returns>
    public Task<LightBeaconColor> GetColor(ObjectId pocId);
    /// <summary>
    /// Asynchronously retrieves the light beacon color associated with the specified point of care.
    /// </summary>
    /// <param name="poc">The point of care for which to look up the light beacon color.</param>
    /// <returns>A task that represents the asynchronous operation. The task result contains the <see cref="LightBeaconColor"/> for the specified point of care.</returns>
    public Task<LightBeaconColor> GetColor(PointOfCare poc);
    /// <summary>
    /// Updates a single light beacon record in the data store.
    /// Returns <see langword="null"/> when the beacon to update cannot be found.
    /// </summary>
    /// <param name="beacon">The light beacon containing the updated values to persist.</param>
    /// <returns>A task that represents the asynchronous operation, containing the updated <see cref="LightBeacon"/>, or <see langword="null"/> if no matching beacon was found.</returns>
    Task<LightBeacon?> UpdateOne(LightBeacon beacon);
    /// <summary>
    /// Inserts a single light beacon into the data store.
    /// </summary>
    /// <param name="beacon">The light beacon entity to insert.</param>
    /// <returns>A task that resolves to the inserted <see cref="LightBeacon"/>, or <c>null</c> when no result is produced.</returns>
    Task<LightBeacon?> InsertOne(LightBeacon beacon);
    /// <summary>
    /// Asynchronously retrieves a paginated collection of light beacons based on the specified pagination filter.
    /// </summary>
    /// <param name="request">The pagination filter containing the criteria used to page the beacon results.</param>
    /// <returns>A task that represents the asynchronous operation, containing a pagination response with the requested light beacons.</returns>
    Task<PaginationResponse<LightBeacon>> GetPaginatedBeacons(PaginationFilter request);
    /// <summary>
    /// Asynchronously searches for light beacons by name using the specified search text.
    /// </summary>
    /// <param name="textToSearch">The text used to search for matching light beacons by name.</param>
    /// <returns>A task that represents the asynchronous operation. The task result contains a list of <see cref="LightBeacon"/> objects matching the search criteria.</returns>
    Task<List<LightBeacon>> GetSearchByName(string textToSearch);
}