using System.Diagnostics;
using AyCode.Core;
using AyCode.Database.DbContexts;
using AyCode.Database.DbContexts.Users;
using AyCode.Database.DbSets.Users;
using AyCode.Interfaces.Users;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection;

namespace AyCode.Database.DataLayers.Users
{
    public static class AcUserDalExtension
    {
        //public static bool DeleteUser(this IAcUserDbContextBase ctx, IAcUser user)
        //{
        //    if (user == null) return false;

        //    var players = ctx.Players.Where(x => x.OwnerId == user.Id).ToList();

        //    foreach (var player in players)
        //    {
        //        ctx.Profiles.RemoveRange(ctx.Profiles.Where(x => x.OwnerId == player.PlayerId || x.OwnerId == user.Id));
        //        ctx.Wallets.RemoveRange(ctx.Wallets.Where(x => x.OwnerId == player.PlayerId || x.OwnerId == user.Id));

        //        ctx.Sessions.RemoveRange(ctx.Sessions.Where(x => x.PlayerId == player.PlayerId));
        //        //ctx.SessionDetails.RemoveRange(ctx.SessionDetails.Where(x => x.PlayerId == player.PlayerId));

        //        ctx.PlayerPermissionTags.RemoveRange(player.PermissionTags);
        //    }

        //    ctx.Players.RemoveRange(players);
        //    ctx.UserTokens.RemoveRange(ctx.UserTokens.Where(x => x.UserId == user.Id));
        //    //ctx.PermissionCategory.RemoveRange(ctx.PermissionCategory.Where(x => x.ForeignKey == user.Id));

        //    ctx.SaveChanges(); //A Player constraint miatt kell, különben nem engedi törölni a User-t! - J.
        //    return ctx.Remove(user).State == EntityState.Deleted;
        //}

        //public static IEnumerable<UserToUserConsent> GetUserConsentsByUserId(this AcUserDbContextBase ctx, Guid userId)
        //    => ctx.UserToUserConsents.Where(u => u.UserId == userId);

        //public static bool IsUserConsentsAccepted(this AcUserDbContextBase ctx, Guid userId)
        //    => ctx.GetUserConsentsByUserId(userId).Count(x => x.IsAccepted) == AcConst.ConsentCount;

        //public static bool SetUserConsentsToAccepted(this AcUserDbContextBase ctx, Guid userId)
        //{
        //    var user = ctx.GetUserById(userId);
        //    return ctx.SetUserConsentsToAccepted(user);
        //}

        //public static bool SetUserConsentsToAccepted(this AcUserDbContextBase ctx, IAcUser? user)
        //{
        //    if (!user.EmailConfirmed) return false; //Ez nem kéne ide... - J.

        //    var hashSet = ctx.GetUserConsentsByUserId(user.Id).Select(x => x.UserConsentId).ToHashSet();
        //    var userConsents = ctx.UserConsents.Where(x => !hashSet.Contains(x.Id));

        //    ctx.AddRange(userConsents.Select(userConsent => new UserToUserConsent(user.Id, userConsent.Id, true)));

        //    var userToUserConsents = ctx.GetUserConsentsByUserId(user.Id).Where(x => !x.IsAccepted).ToList();
        //    foreach (var userToUserConsent in userToUserConsents)
        //    {
        //        userToUserConsent.IsAccepted = true;
        //    }

        //    ctx.UpdateRange(userToUserConsents);

        //    return true;
        //}




        ////public static void GetUserDetails(this IUserDal userDal, Guid userId, Action<AspNetUser> callback) 
        ////    => callback(userDal.Get<AspNetUser>(userId));

        //public static void UsernameAndEmailAvailable(this IUserDal userDal, string username, string email, Action<bool, AcErrorCode, AspNetUser> callback)
        //{
        //    IAcUser notConfirmedUser = null;

        //    var lowerEmail = email.ToLower();
        //    var lowerUserName = username.ToLower();

        //    var isAvailable = AcValidate.IsValidEmailFormat(lowerEmail, out var resultErrorCode) && AcValidate.IsValidUserNameFormat(lowerUserName, out resultErrorCode);

        //    if (isAvailable)
        //    {
        //        //userDal.RowCount<AspNetUser>(ctx => ctx.EmailConfirmed && (ctx.NormalizedUserName == lowerUserName || ctx.NormalizedEmail == lowerEmail)) == 0

        //        var users = userDal.Where<AspNetUser>(ctx => ctx.NormalizedUserName == lowerUserName || ctx.NormalizedEmail == lowerEmail).ToList();

        //        notConfirmedUser = users.FirstOrDefault(x => !x.EmailConfirmed && x.NormalizedEmail == lowerEmail);

        //        //isAvailable = (users.Count == 0 || (users.Count == 1 && notConfirmedUser != null));

        //        if (users.Count > 1) resultErrorCode = AcErrorCode.EmailInUse;
        //        else if (users.Count == 1 && notConfirmedUser == null)
        //        {
        //            resultErrorCode = users.Any(x => x.NormalizedEmail == lowerEmail) ? AcErrorCode.EmailInUse : AcErrorCode.UserNameInUse;
        //        }

        //        isAvailable = resultErrorCode == AcErrorCode.Unset;
        //    }

        //    callback(isAvailable, resultErrorCode, notConfirmedUser);
        //}


        //public static void AddNewUser(this IUserDal userDal, IAcUser newUser, Action<AspNetUser> callback)
        //{
        //    userDal.Add(newUser);
        //    callback(newUser);
        //}

        //public static void AddNewUser(this IUserDal userDal, Guid userId, string username, string email, string password, Action callback)
        //{
        //    var newUser = new AspNetUser(userId, username, email, password);
        //    userDal.Add(newUser);

        //    callback();
        //}

        ////public static void DeleteUser(this IUserDal userDal, string username, Action callback)
        ////{
        ////    userDal.Session(ctx =>
        ////    {
        ////        var user = ctx.Users.FirstOrDefault(u => u.NormalizedUserName == username.ToUpperInvariant());
        ////        if (user == null) return;

        ////        ctx.Set<AspNetUser>().Delete(user);
        ////        ctx.SaveChanges();
        ////    };
        ////}
    }
}
