namespace inutralia.Abstractions
{
    using System.Collections.Generic;
    using System.Threading.Tasks;

    /// <summary>
    /// Interfaz genérico de almacenamiento de entidades
    /// </summary>
    public interface IDataPersistenceService
    {
        /// <summary>
        /// Recupera de forma asíncrona los datos de una entidad a partir de su
        /// identificador
        /// </summary>
        /// <typeparam name="T">Tipo de dato de cada entidad</typeparam>
        /// <param name="id">Identificador de la entidad</param>
        /// <returns>Instancia de T correspondiente al identificador</returns>
        Task<T> GetItemAsync<T>(int id) where T : IIdentifiableEntity;

        /// <summary>
        /// Obtiene de forma asíncrona una lista de entidades
        /// </summary>
        /// <typeparam name="T">Tipo de dato de cada entidad</typeparam>
        /// <returns>Lista de elementos obtenidos</returns>
        Task<List<T>> RefreshListAsync<T>() where T : IIdentifiableEntity;

        /// <summary>
        /// Recupera de forma asíncrona los datos de una entidad
        /// </summary>
        /// <typeparam name="T">Tipo de dato de la entidad</typeparam>
        /// <param name="item">La entidad a actualizar</param>
        /// <returns>Si la operación se realizó correctamente</returns>
        Task<bool> RefreshItemAsync<T>(T item) where T : IIdentifiableEntity;

        /// <summary>
        /// Actualiza de forma asíncrona los datos de una entidad
        /// </summary>
        /// <typeparam name="T">Tipo de dato de la entidad</typeparam>
        /// <param name="item">La entidad a actualizar</param>
        /// <param name="isNew">Indica si hay que crear una entidad nueva o modificar una existente</param>
        /// <returns>El ID de la entidad. Null en caso de error</returns>
        Task<int?> UpdateItemAsync<T>(T item, bool isNew = false) where T : IIdentifiableEntity;

        /// <summary>
        /// Elimina de forma asíncrona una entidad
        /// </summary>
        /// <typeparam name="T">Tipo de dato de la entidad</typeparam>
        /// <param name="item">La entidad a eliminar</param>
        /// <returns>Si la operación se realizó correctamente</returns>
        Task<bool> DeleteItemAsync<T>(T item) where T : IIdentifiableEntity;
    }
}
