using FJPSite.Data;
using FJPSite.Enums;
using FJPSite.Interfaces;
using FJPSite.Models;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Caching.Memory;

namespace FJPSite.Services;

public class PermissionService : IPermissionService
{
    private readonly ApplicationDbContext _context;
    private readonly IMemoryCache _cache;
    public PermissionService(
     ApplicationDbContext context,
     IMemoryCache cache)
    {
        _context = context;
        _cache = cache;
    }
    public async Task<bool> UserHasPermissionAsync(string userId, FeatureEnum feature, ActionEnum action)
    {
        // First check cache
        var cacheKey = $"permissions_{userId}";
        if (!_cache.TryGetValue(cacheKey, out List<PermissionModel> permissions))
        {
            // Get user roles
            var userRoles = await _context.UserRoles.Where(ur => ur.UserId == userId).Select(ur => ur.RoleId).ToListAsync();
            // Get all permissions for these roles
            var rolePermissions = await _context.RolePermissions
            .Where(rp => userRoles.Contains(rp.RoleId))
            .Include(rp => rp.FeatureAction)
            .ThenInclude(fa => fa.Feature)
            .Include(rp => rp.FeatureAction)
            .ThenInclude(fa => fa.Action)
            .ToListAsync();
            // Map to PermissionDto
            permissions = rolePermissions.Select(rp => new PermissionModel
            {
                Feature = Enum.Parse<FeatureEnum>(rp.FeatureAction.Feature.Name),
                Action = Enum.Parse<ActionEnum>(rp.FeatureAction.Action.Name)
            }).ToList();
            // Cache for 10 minutes
            var cacheEntryOptions = new MemoryCacheEntryOptions()
            .SetAbsoluteExpiration(TimeSpan.FromMinutes(10));
            _cache.Set(cacheKey, permissions, cacheEntryOptions);
        }
        return permissions.Any(p =>
         p.Feature == feature &&
         p.Action == action);
    }

    public async Task<List<PermissionStructureModel>> GetPermissionStructureAsync(int moduleId)
    {
        // First check cache
        var cacheKey = $"permission_structure_{moduleId}";
        if (!_cache.TryGetValue(cacheKey, out List<PermissionStructureModel> permissionStructure))
        {
            permissionStructure = _context.Modules.Include(i => i.Features).ThenInclude(i => i.Feature).ThenInclude(i => i.Actions).ThenInclude(i => i.Action).Where(w => w.Id == moduleId && w.IsActive == true).Select(s => new PermissionStructureModel
            {
                ModuleId = s.Id,
                ModuleName = s.Name,
                Features = s.Features.Select(b => new FeaturePermissionModel
                {
                    FeatureId = b.FeatureId,
                    FeatureName = b.Feature.Name,
                    Actions = b.Feature.Actions.Select(c => new ActionPermissionModel
                    {
                        ActionId = c.Id,
                        ActionName = c.Action.Name,
                        IsDisabled = false,
                        IsSelected = false
                    }).ToList()
                }).ToList()
            }).ToList();
            
            //_context.Features.Include(i => i.Modules).Include(i => i.Actions).Where(w => w.Modules. == moduleId);
        }
        return permissionStructure;
    }
}