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 ICameraService
{
    /// <summary>
    /// Retrieves the camera associated with the specified relay identifier.
    /// </summary>
    /// <param name="relayId">The unique identifier of the relay used to look up the camera.</param>
    /// <returns>A task that represents the asynchronous operation. The task result contains the <see cref="Camera"/> if a matching record is found; otherwise, <c>null</c>.</returns>
    Task<Camera?> GetById(ObjectId relayId);
    /// <summary>
    /// Retrieves the list of cameras associated with the specified configuration relay identifiers.
    /// </summary>
    /// <param name="configurationRelayList">The list of configuration relay object identifiers used to look up the associated cameras.</param>
    /// <returns>A list of cameras that correspond to the provided configuration relay identifiers.</returns>
    List<Camera> GetCameraInList(List<ObjectId> configurationRelayList);
    /// <summary>
    /// Retrieves a paginated list of cameras based on the provided pagination filter.
    /// </summary>
    /// <param name="request">The pagination filter containing the page size, page number, and optional search criteria used to query cameras.</param>
    /// <returns>A task that represents the asynchronous operation. The task result contains a <see cref="PaginationResponse{Camera}"/> with the requested page of cameras and pagination metadata.</returns>
    Task<PaginationResponse<Camera>> GetPaginatedCameras(PaginationFilter request);
    /// <summary>
    /// Inserts a new camera into the system asynchronously.
    /// </summary>
    /// <param name="camera">The camera entity to insert.</param>
    /// <returns>A task that represents the asynchronous operation. The task result contains the inserted camera with its generated identifier, or <c>null</c> if the camera could not be inserted.</returns>
    Task<Camera?> InsertCamera(Camera camera);
    /// <summary>
    /// Updates an existing camera identified by the specified object identifier with the provided camera data.
    /// Returns <see langword="null"/> when no camera with the given identifier exists.
    /// </summary>
    /// <param name="objectId">The unique identifier of the camera to update.</param>
    /// <param name="camera">The camera data containing the updated values to apply.</param>
    /// <returns>A task that represents the asynchronous operation. The task result contains the updated camera, or <see langword="null"/> if the camera was not found.</returns>
    Task<Camera?> UpdateCameraById(ObjectId objectId, Camera camera);
    /// <summary>
    /// Deletes a camera identified by the specified object identifier.
    /// </summary>
    /// <param name="objectId">The unique identifier of the camera to delete.</param>
    /// <returns>A task that represents the asynchronous delete operation. The result is <c>true</c> if the camera was successfully deleted; otherwise, <c>false</c>.</returns>
    Task<bool> DeleteCamera(ObjectId objectId);
    /// <summary>
    /// Asynchronously retrieves a list of cameras whose names match the specified search text.
    /// </summary>
    /// <param name="textToSearch">The text used to search camera names.</param>
    /// <returns>A task that represents the asynchronous operation. The task result contains a list of <see cref="Camera"/> objects matching the search criteria; an empty list is returned if no matches are found.</returns>
    Task<List<Camera>> GetSearchByNameCameras(string textToSearch);
}