using PARR.Domain.Entities;

namespace PARR.EsppSync
{
    /// <summary>
    /// Делегат парсинга из строки в модель EsppObject
    /// </summary>
    /// <typeparam name="EsppObject"></typeparam>
    /// <param name="str"></param>
    /// <returns></returns>
    public delegate EsppObject? ParseStringToEsppObject<EsppObject>(string str) where EsppObject : class, IEsppObject;

    /// <summary>
    /// Конвертирует Template в модель для сравнения
    /// </summary>
    /// <typeparam name="EsppObject"></typeparam>
    /// <param name="templateName"></param>
    /// <returns></returns>
    public delegate EsppObject ConvertDbToEsppObject<EsppObject>(Template template) where EsppObject : class, IEsppObject;

    /// <summary>
    /// Дополнительная проверка полей, если проверка прошла, то true
    /// </summary>
    /// <typeparam name="EsppObject"></typeparam>
    /// <param name="esppObject"></param>
    /// <param name="dbObject"></param>
    /// <param name="templateId"></param>
    /// <returns>true - проверка пройдена, false - проверка не пройдена</returns>
    public delegate Task<bool> CustomComparisionCheckAsync<EsppObject>(EsppObject esppObject, EsppObject dbObject, Guid templateId) where EsppObject : class, IEsppObject;


    /// <summary>
    /// Выполнить произвольную логику после парсинга строки в объект ЕСПП
    /// </summary>
    /// <typeparam name="EsppObject"></typeparam>
    /// <param name="esppObject"></param>
    /// <returns></returns>
    public delegate Task AfterParseStringToEsppObjectAsync<EsppObject>(EsppObject esppObject) where EsppObject : class, IEsppObject;


    public interface ISyncService<EsppObject> where EsppObject : class, IEsppObject
    {
        /// <summary>
        /// Синхронизировать объекты
        /// </summary>
        /// <param name="str">Строка из RabbitMQ</param>
        /// <param name="parseStringToEsppObject">Делегат парсинга из строки в модель EsppObject</param>
        /// <param name="converterDbToEsppObject"> Конвертирует BD Template в модель для сравнения</param>
        /// <param name="customComparisionAsync">Кастомное сравнение полей</param>
        /// <param name="afterParseStringToEsppObjectAsync">Выполнить произвольный метод после парсинга строки в модель EsppObject</param>
        /// <returns></returns>
        Task SyncEsppObjectAsync(string str,
            ParseStringToEsppObject<EsppObject> parseStringToEsppObject,
            ConvertDbToEsppObject<EsppObject> converterDbToEsppObject,
            CustomComparisionCheckAsync<EsppObject>? customComparisionAsync = null,
            AfterParseStringToEsppObjectAsync<EsppObject>? afterParseStringToEsppObjectAsync = null
            );
    }
}