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 ICameraRepository : IMongoRepository<Camera>
{
    /// <summary>
    /// Asynchronously retrieves a <see cref="Camera"/> by its unique identifier.
    /// </summary>
    /// <param name="cameraId">The unique identifier of the camera to look up.</param>
    /// <returns>A task that represents the asynchronous operation. The task result contains the matching <see cref="Camera"/>, or <c>null</c> if no camera is found with the specified identifier.</returns>
    Task<Camera?> GetById(ObjectId cameraId);
    /// <summary>
    /// Asynchronously retrieves a camera by its name, returning <c>null</c> if no matching camera is found.
    /// </summary>
    /// <param name="name">The name of the camera to look up.</param>
    /// <returns>A <see cref="Task{TResult}"/> that resolves to the matching <see cref="Camera"/>, or <c>null</c> if no camera with the specified name exists.</returns>
    Task<Camera?> GetByName(string name);
    /// <summary>
    /// Retrieves the list of <see cref="Camera"/> objects associated with the specified configuration relays.
    /// </summary>
    /// <param name="configurationRelayList">The list of <see cref="ObjectId"/> values identifying the configuration relays whose cameras should be returned.</param>
    /// <returns>A <see cref="List{Camera}"/> containing the cameras linked to the provided configuration relays; returns an empty list when no matching cameras are found.</returns>
    List<Camera> GetCameraInList(List<ObjectId> configurationRelayList);
    /// <summary>
    /// Retrieves a paginated, fluent queryable collection of cameras based on the supplied pagination filter.
    /// </summary>
    /// <param name="request">The pagination filter containing the page number and page size used to page the camera results.</param>
    /// <returns>An <see cref="IFindFluent{Camera, Camera}"/> representing the paged query of cameras.</returns>
    IFindFluent<Camera, Camera> GetPaginatedCameras(PaginationFilter request);
    /// <summary>
    /// Inserts a new camera record into the data store and returns the persisted entity, or <c>null</c> if the camera could not be inserted.
    /// </summary>
    /// <param name="camera">The <see cref="Camera"/> instance containing the data to be inserted.</param>
    /// <returns>A <see cref="Task{T}"/> that resolves to the inserted <see cref="Camera"/>, or <c>null</c> when the insertion is not performed.</returns>
    Task<Camera?> InsertOneCamera(Camera camera);
    /// <summary>
    /// Asynchronously updates an existing camera identified by the specified object identifier.
    /// </summary>
    /// <param name="objectId">The unique identifier of the camera to update.</param>
    /// <param name="camera">The camera object containing the updated information.</param>
    /// <returns>A task that represents the asynchronous update operation. The task result contains the updated <see cref="Camera"/>, or <c>null</c> if no camera with the specified identifier was found.</returns>
    Task<Camera?> UpdateCameraAsync(ObjectId objectId, Camera camera);
    /// <summary>
    /// Asynchronously searches for cameras whose name matches the specified text.
    /// </summary>
    /// <param name="textToSearch">The text used to filter cameras by name.</param>
    /// <returns>A task that represents the asynchronous operation, containing a list of <see cref="Camera"/> objects matching the search criteria.</returns>
    Task<List<Camera>> GetSearchByNameCameras(string textToSearch);
}