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

namespace adas_core.Application.Services.Interfaces;

public interface IHistoricalConfigChangesService
{
    /// <summary>
    /// Asynchronously retrieves all historical configuration changes recorded in the system.
    /// </summary>
    /// <returns>A task that represents the asynchronous operation. The task result contains a collection of all <see cref="HistoricalConfigChanges"/> entries.</returns>
    Task<ICollection<HistoricalConfigChanges>> GetAll();
    /// <summary>
    /// Asynchronously retrieves a historical configuration change entry by its unique identifier.
    /// Returns null when no matching historical configuration change is found for the specified id.
    /// </summary>
    /// <param name="id">The unique identifier of the historical configuration change to retrieve.</param>
    /// <returns>A task that represents the asynchronous operation, containing the matching <see cref="HistoricalConfigChanges"/> or null if not found.</returns>
    Task<HistoricalConfigChanges?> Get(ObjectId id);
    /// <summary>
    /// Asynchronously retrieves a collection of historical configuration changes filtered by the specified configuration type.
    /// </summary>
    /// <param name="type">The configuration type used to filter the historical changes.</param>
    /// <param name="num">The maximum number of historical change records to return.</param>
    /// <returns>A task that represents the asynchronous operation, containing a collection of <see cref="HistoricalConfigChanges"/> for the specified type.</returns>
    Task<ICollection<HistoricalConfigChanges>> GetByType(DisplayConfigEnums.ConfigTypes type, int num);

    /// <summary>
    /// Retrieves a collection of historical configuration changes associated with the specified user.
    /// Results can be filtered by configuration type and limited in count; when the configuration type is not provided, all types are considered.
    /// </summary>
    /// <param name="user">The identifier of the user whose historical configuration changes should be retrieved.</param>
    /// <param name="configTypes">The optional configuration type used to filter the results; if null, changes for all configuration types are returned.</param>
    /// <param name="num">The maximum number of historical configuration change records to return.</param>
    /// <returns>A task that represents the asynchronous operation, containing the collection of historical configuration changes matching the specified criteria.</returns>
    Task<ICollection<HistoricalConfigChanges>> GetByUser(string user, DisplayConfigEnums.ConfigTypes? configTypes,
            int num);

    /// <summary>
    /// Asynchronously retrieves the most recent historical configuration changes for the specified configuration type.
    /// Returns null if no historical changes are found for the given type.
    /// </summary>
    /// <param name="configTypes">The configuration type used to look up the most recent historical changes.</param>
    /// <returns>A task that represents the asynchronous operation. The task result contains the last <see cref="HistoricalConfigChanges"/> for the specified type, or null if no changes are available.</returns>
    Task<HistoricalConfigChanges?> FindLastConfigChanges(DisplayConfigEnums.ConfigTypes configTypes);


    /// <summary>
    /// Inserts a single historical configuration change record into the data store.
    /// Returns the inserted record, or null if the insert could not be performed.
    /// </summary>
    /// <param name="historicalConfigChanges">The historical configuration change entity to be inserted.</param>
    /// <returns>A task that represents the asynchronous operation, containing the inserted <see cref="HistoricalConfigChanges"/> entity, or null if the insertion did not produce a result.</returns>
    Task<HistoricalConfigChanges?> InsertOne(HistoricalConfigChanges historicalConfigChanges);
    /// <summary>
    /// Updates an existing historical configuration change record with the provided data and returns the updated entity.
    /// </summary>
    /// <param name="historicalConfigChanges">The historical configuration change entity containing the updated values to be persisted.</param>
    /// <returns>A task that resolves to the updated <see cref="HistoricalConfigChanges"/>, or <c>null</c> if the record was not found.</returns>
    Task<HistoricalConfigChanges?> UpdateHistoricalConfigChange(HistoricalConfigChanges historicalConfigChanges);

    /// <summary>
    /// Deletes a historical configuration change identified by the specified identifier.
    /// </summary>
    /// <param name="id">The identifier of the historical configuration change to delete.</param>
    Task DeleteHistoricalConfigChange(ObjectId id);

    /// <summary>
    /// Logs a configuration change event, recording the user who made the change, the type of configuration affected, and the old and new configuration values.
    /// </summary>
    /// <param name="user">The identifier of the user who made the configuration change.</param>
    /// <param name="configType">The type of configuration that was changed.</param>
    /// <param name="newConfig">The new configuration value after the change.</param>
    /// <param name="oldConfig">The previous configuration value before the change.</param>
    Task LogConfigChanged(string user, DisplayConfigEnums.ConfigTypes configType, string newConfig, string oldConfig);
}