using AyCode.Database;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.ChangeTracking;
using TIAM.Database.DbContexts;
using TIAM.Database.DbContexts.ServiceProviders;
using TIAM.Database.DbSets.Users;
using TIAM.Entities.Permissions;
using TIAM.Entities.Products;

namespace TIAM.Database.DbSets.Permissions;

public static class PermissionsDbSetExtensions
{
    //public static IQueryable<PermissionGroup> GetPermissionGroupByContextMapping(this IPermissionsDbSetContext ctx, PermissionContextMapping permissionContextMapping)
    //{
    //    if (permissionContextMapping.SubjectType == PermissionContextMappingSubjectType.Group)
    //        return ctx.PermissionGroups.Where(x => x.Id == permissionContextMapping.SubjectId);
    //    else if (permissionContextMapping.SubjectType == PermissionContextMappingSubjectType.User)
    //        return ctx.PermissionGroups.Where(x => x.Id == permissionContextMapping.SubjectId);
    //}

    //public static IQueryable<PermissionContextMapping> GetPermissionContextMappingByAssignedUserId(this IPermissionsDbSetContext ctx, Guid assignedUserId)
    //{
    //    var subjectIds = ctx.GetAssignedUsersByContextId(assignedUserId).Select(x => x.Id).
    //        Concat(ctx.PermissionGroupUserMappings.Where(x => x.AssignedUserId == assignedUserId).Select(x => x.)).ToHashSet();

    //    return ctx.GetPermissionContextMappingsBySubjectIds(subjectIds);
    //}

    public static IQueryable<PermissionContextMapping> GetPermissionContextsViewBySubjectId(this IPermissionContextMappingDbSet ctx, Guid subjectId)
        => ctx.PermissionContextMappings.FromSqlRaw(PermissionSqls.PermissionViewSql).Where(x => x.SubjectId == subjectId);

    public static IQueryable<PermissionContextMapping> GetPermissionContextsViewByContextId(this IPermissionContextMappingDbSet ctx, Guid contextId)
        => ctx.PermissionContextMappings.FromSqlRaw(PermissionSqls.PermissionViewSql).Where(x => x.ContextId == contextId);

    public static IQueryable<PermissionContextMapping> GetPermissionContextsView(this IPermissionContextMappingDbSet ctx, Guid subjectId, Guid contextId)
        => ctx.PermissionContextMappings.FromSqlRaw(PermissionSqls.PermissionViewSql).Where(x => x.SubjectId == subjectId && x.ContextId == contextId);


    public static IQueryable<PermissionContextMapping> GetPermissionContextMappingsBySubjectIds(this IPermissionsDbSetContext ctx, IEnumerable<Guid> subjectIds)
        => ctx.PermissionContextMappings.Where(x => subjectIds.Contains(x.SubjectId));

    public static PermissionContextMapping? GetPermissionContextMappingBySubjectId(this IPermissionsDbSetContext ctx, Guid subjectId)
        => ctx.PermissionContextMappings.FirstOrDefault(x => x.SubjectId == subjectId);

    public static void RemoveContextMappingBySubjectId(this IPermissionsDbSetContext ctx, Guid subjectId)
    {
        var contextMapping = ctx.GetPermissionContextMappingBySubjectId(subjectId);

        if (contextMapping == null) return;

        ctx.PermissionContextMappings.Remove(contextMapping);
    }

    public static IQueryable<PermissionGroupUserMapping> GetAllPermissionGroupsByAssignedUserId(this IPermissionsDbSetContext ctx, Guid assignedUserId)
        => ctx.PermissionGroupUserMappings.Where(x => x.SubjectId == assignedUserId);

    public static void RemoveAssingedUserFromPermissionGroups(this IPermissionsDbSetContext ctx, Guid assignedUserId)
        => ctx.PermissionGroupUserMappings.RemoveRange(ctx.GetAllPermissionGroupsByAssignedUserId(assignedUserId));
}