using AyCode.Interfaces.Entities;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using TIAM.Core.Interfaces;
using TIAM.Database.DbContexts.Admins;
using TIAM.Database.DbContexts.ServiceProviders;
using TIAM.Database.DbSets.Permissions;
using TIAM.Database.DbSets.Products;
using TIAM.Database.DbSets.Users;
using TIAM.Entities.Permissions;
using TIAM.Entities.Products;
using TIAM.Entities.ServiceProviders;
using TIAM.Entities.Users;

namespace TIAM.Database.DataLayers.Admins
{
    public static class AdminDalDbContextExtension
    {
        public static IQueryable<UserProductMapping> GetUserProductMappingsByPermissionGroupId(this IAdminDbContext ctx, Guid permissionGroupId)
        {
            return ctx.UserProductMappings
                .Where(user => ctx.PermissionGroupUserMappings
                    .Where(x => x.PermissionGroupId == permissionGroupId)
                    .Select(x => x.SubjectId)
                    .Contains(user.Id));
        }

        public static void CleanUpAndRemoveUserProductMappings(this IAdminDbContext ctx, IEnumerable<UserProductMapping> userProductMappings)
        {
            foreach (var userProductMapping in userProductMappings)
            {
                ctx.CleanUpAndRemoveAssignedUser(userProductMapping);
            }
        }

        public static void CleanUpAndRemoveAssignedUser(this IAdminDbContext ctx, UserProductMapping userProductMapping)
        {
            ctx.RemoveContextMappingBySubjectId(userProductMapping.Id);
            ctx.RemoveAssingedUserFromPermissionGroups(userProductMapping.Id);

            ctx.UserProductMappings.Remove(userProductMapping);
        }

        public static bool CleanUpAndRemoveUserProductMappings(this IAdminDbContext ctx, Guid userProductMappingId)
        {
            var userProductMapping = ctx.GetUserProductMappingById(userProductMappingId);

            if (userProductMapping == null) return false;

            ctx.CleanUpAndRemoveAssignedUser(userProductMapping);

            return true;
        }

        public static void DeleteProductById(this IAdminDbContext ctx, Guid productId)
        {
            var product = ctx.Products.FirstOrDefault(u => u.Id == productId);
            if (product == null) return;

            ctx.CleanUpAndRemoveUserProductMappings(ctx.GetUserProductMappingsByProductId(productId));
            ctx.Products.Remove(product);
        }

        public static bool CreatePermissionGroup(this IAdminDbContext ctx, PermissionGroup permissionGroup)
        {
            if (permissionGroup == null) return false;

            ctx.PermissionGroups.Add(permissionGroup);

            return true;
        }

        public static bool CreatePermissionContextMapping(this IAdminDbContext ctx, PermissionContextMapping permissionContextMapping)
        {
            if (permissionContextMapping == null) return false;

            ctx.PermissionContextMappings.Add(permissionContextMapping);

            return true;
        }

        public static bool CreatePermissionGroupUserMapping(this IAdminDbContext ctx, PermissionGroupUserMapping permissionGroupUserMapping)
        {
            if (permissionGroupUserMapping == null) return false;

            ctx.PermissionGroupUserMappings.Add(permissionGroupUserMapping);

            return true;
        }

        public static bool CreatePermissionsType(this IAdminDbContext ctx, PermissionsType permissionType)
        {
            if (permissionType == null) return false;

            ctx.PermissionsTypes.Add(permissionType);

            return true;
        }

        public static bool CreateProduct(this IAdminDbContext ctx, Product myproduct)
        {
            if (myproduct == null) return false;
            //Automatically add assigneduser for owner
            TiamServiceProvider? productOwner = ctx.ServiceProviders.FirstOrDefault(x => x.Id == myproduct.ServiceProviderId);
            if (productOwner == null) return false;
            var userProductMapping = new UserProductMapping(myproduct.Id, productOwner.OwnerId);
            ctx.CreateAssignedUser(userProductMapping);
            ctx.AddProduct(myproduct);

            return true;
        }

        public static bool CreateAssignedUser(this IAdminDbContext ctx, UserProductMapping userProductMapping)
        {
            if (userProductMapping == null) return false;

            ctx.UserProductMappings.Add(userProductMapping);

            return true;
        }

        public static TiamServiceProvider CreateServiceProvider(this IAdminDbContext ctx, TiamServiceProvider serviceProvider)
        {
            if (serviceProvider == null) return null;

            ctx.ServiceProviders.Add(serviceProvider);
            var userProductMapping = new UserProductMapping(serviceProvider.Id, serviceProvider.OwnerId);
            ctx.CreateAssignedUser(userProductMapping);
            return serviceProvider;
        }

        public static TiamServiceProvider UpdateServiceProvider(this IAdminDbContext ctx, TiamServiceProvider serviceProvider)
        {
            if (serviceProvider == null) return null;

            var existingServiceProvider = ctx.ServiceProviders.FirstOrDefault(u => u.Id == serviceProvider.Id);
            if (existingServiceProvider == null) return null;

            existingServiceProvider.Name = serviceProvider.Name;
            existingServiceProvider.OwnerId = serviceProvider.OwnerId;
            return existingServiceProvider;
        }
    }
}
