using AyCode.Core.Consts;
using AyCode.Core.Helpers;
using AyCode.Core.Loggers;
using AyCode.Core.Server.Loggers;
using AyCode.Database.DbContexts;
using AyCode.Interfaces.Entities;

namespace AyCode.Database.Extensions;

public static class AcDbSessionExtension
{
    public static Task<TResultType> SessionAsync<TDbContext, TResultType>(this TDbContext ctx, Func<TDbContext, TResultType> callback) where TDbContext : AcDbContextBase
        => TaskHelper.ToThreadPoolTask(() => ctx.Session(callback));

    public static TResultType Session<TDbContext, TResultType>(this TDbContext ctx, Func<TDbContext, TResultType> callback) where TDbContext : AcDbContextBase
    {
        TResultType result;

        try
        {
            result = callback(ctx);
        }
        catch (Exception ex)
        {
            var errorText = $"Session({ctx}) callback error...{AcEnv.NL}";
            GlobalLogger.Error($"{errorText}", ex);

            throw new Exception($"{errorText}{ex}");
        }

        return result;
    }


    public static IEnumerable<TEntity> Session<TDbContext, TEntity>(this TDbContext ctx, Func<TDbContext, IQueryable<TEntity>> callback)
        where TEntity : IEntity
        where TDbContext : AcDbContextBase
    {
        foreach (var entity in callback(ctx))
            yield return entity;
    }
}