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

namespace adas_core.Application.Repositories.Interfaces;

public interface IRelayRepository : IMongoRepository<Relay>
{
    /// <summary>
    /// Asynchronously retrieves a relay entity by its unique identifier.
    /// </summary>
    /// <param name="relayId">The unique identifier of the relay to retrieve.</param>
    /// <returns>A task that represents the asynchronous operation. The task result contains the <see cref="Relay"/> if found; otherwise, <c>null</c>.</returns>
    Task<Relay?> GetById(ObjectId relayId);
    /// <summary>
    /// Retrieves the relays of the specified type from the provided configuration relay list.
    /// </summary>
    /// <param name="configurationRelayList">The list of relay object identifiers to search through.</param>
    /// <param name="type">The relay type used to filter the configuration relay list.</param>
    /// <returns>A list of relays matching the specified type; an empty list if no relays of that type are found.</returns>
    List<Relay> GetRelayByTypeInList(List<ObjectId> configurationRelayList, RelayEnum.Type type);
    /// <summary>
    /// Retrieves the <see cref="Relay"/> objects that correspond to the supplied configuration relay identifiers.
    /// </summary>
    /// <param name="configurationRelayList">The list of <see cref="ObjectId"/> values identifying the configuration relays to look up.</param>
    /// <returns>A <see cref="List{Relay}"/> containing the relays that match the provided configuration relay identifiers.</returns>
    List<Relay> GetRelayInList(List<ObjectId> configurationRelayList);
    /// <summary>
    /// Retrieves a paginated, filterable query of relays based on the specified pagination filter.
    /// </summary>
    /// <param name="filter">The pagination filter used to control paging and additional query criteria for the relay lookup.</param>
    /// <returns>An <see cref="IFindFluent{Relay, Relay}"/> representing the paginated query that can be further refined and executed.</returns>
    IFindFluent<Relay, Relay> GetPaginatedRelays(PaginationFilter filter);
    /// <summary>
    /// Asynchronously inserts a single <see cref="Relay"/> record and returns the inserted entity, or <see langword="null"/> if the insertion did not produce a result.
    /// </summary>
    /// <param name="request">The <see cref="Relay"/> entity to be inserted.</param>
    /// <returns>A task that represents the asynchronous insert operation. The result is the inserted <see cref="Relay"/>, or <see langword="null"/> when no relay is returned.</returns>
    Task<Relay?> InsertOneRelayAsync(Relay request);
    /// <summary>
    /// Updates an existing relay identified by the specified object identifier.
    /// </summary>
    /// <param name="objectId">The unique identifier of the relay to update.</param>
    /// <param name="relay">The relay object containing the updated information.</param>
    /// <returns>A task that represents the asynchronous operation. The task result contains the updated relay, or <see langword="null"/> if no relay with the specified identifier was found.</returns>
    Task<Relay?> UpdateRelayAsync(ObjectId objectId, Relay relay);
    /// <summary>
    /// Retrieves a relay by its name asynchronously, returning null if no matching relay is found.
    /// </summary>
    /// <param name="requestRelayName">The name of the relay to look up. May be null.</param>
    /// <returns>A task that represents the asynchronous lookup. The task result contains the matching relay, or null if no relay with the specified name exists.</returns>
    Task<Relay?> GetByName(string? requestRelayName);
}