using Microsoft.AspNetCore.Mvc;
using PlanTempus.Application.Features.Localization.Services;

namespace PlanTempus.Application.Features.Employees.Components;

public class PermissionsMatrixViewComponent : ViewComponent
{
    private readonly ILocalizationService _localization;

    public PermissionsMatrixViewComponent(ILocalizationService localization)
    {
        _localization = localization;
    }

    public IViewComponentResult Invoke(string key)
    {
        var model = PermissionsMatrixCatalog.Get(key, _localization);
        return View(model);
    }
}

public class PermissionsMatrixViewModel
{
    public required string Key { get; init; }
    public required IReadOnlyList<RoleHeader> Roles { get; init; }
    public required IReadOnlyList<PermissionRow> Permissions { get; init; }
}

public class RoleHeader
{
    public required string Key { get; init; }
    public required string Name { get; init; }
}

public class PermissionRow
{
    public required string Key { get; init; }
    public required string Name { get; init; }
    public required string Icon { get; init; }
    public required IReadOnlyDictionary<string, bool> RoleAccess { get; init; }
}

internal class PermissionsMatrixData
{
    public required string Key { get; init; }
    public required IReadOnlyList<string> RoleKeys { get; init; }
    public required IReadOnlyList<PermissionData> Permissions { get; init; }
}

internal class PermissionData
{
    public required string Key { get; init; }
    public required string NameKey { get; init; }
    public required string Icon { get; init; }
    public required IReadOnlyDictionary<string, bool> RoleAccess { get; init; }
}

public static class PermissionsMatrixCatalog
{
    private static readonly Dictionary<string, string> RoleNameKeys = new()
    {
        ["owner"] = "employees.roles.owner",
        ["admin"] = "employees.roles.admin",
        ["leader"] = "employees.roles.leader",
        ["employee"] = "employees.roles.employee"
    };

    private static readonly Dictionary<string, PermissionsMatrixData> Matrices = new()
    {
        ["default"] = new PermissionsMatrixData
        {
            Key = "default",
            RoleKeys = ["owner", "admin", "leader", "employee"],
            Permissions =
            [
                new PermissionData
                {
                    Key = "calendar",
                    NameKey = "employees.permissions.calendar",
                    Icon = "ph-calendar",
                    RoleAccess = new Dictionary<string, bool>
                    {
                        ["owner"] = true,
                        ["admin"] = true,
                        ["leader"] = true,
                        ["employee"] = true
                    }
                },
                new PermissionData
                {
                    Key = "employees",
                    NameKey = "employees.permissions.employees",
                    Icon = "ph-users",
                    RoleAccess = new Dictionary<string, bool>
                    {
                        ["owner"] = true,
                        ["admin"] = true,
                        ["leader"] = true,
                        ["employee"] = false
                    }
                },
                new PermissionData
                {
                    Key = "customers",
                    NameKey = "employees.permissions.customers",
                    Icon = "ph-address-book",
                    RoleAccess = new Dictionary<string, bool>
                    {
                        ["owner"] = true,
                        ["admin"] = true,
                        ["leader"] = true,
                        ["employee"] = true
                    }
                },
                new PermissionData
                {
                    Key = "reports",
                    NameKey = "employees.permissions.reports",
                    Icon = "ph-chart-bar",
                    RoleAccess = new Dictionary<string, bool>
                    {
                        ["owner"] = true,
                        ["admin"] = true,
                        ["leader"] = false,
                        ["employee"] = false
                    }
                }
            ]
        }
    };

    public static PermissionsMatrixViewModel Get(string key, ILocalizationService localization)
    {
        if (!Matrices.TryGetValue(key, out var matrix))
            throw new KeyNotFoundException($"PermissionsMatrix with key '{key}' not found");

        var roles = matrix.RoleKeys.Select(roleKey => new RoleHeader
        {
            Key = roleKey,
            Name = localization.Get(RoleNameKeys[roleKey])
        }).ToList();

        var permissions = matrix.Permissions.Select(p => new PermissionRow
        {
            Key = p.Key,
            Name = localization.Get(p.NameKey),
            Icon = p.Icon,
            RoleAccess = p.RoleAccess
        }).ToList();

        return new PermissionsMatrixViewModel
        {
            Key = matrix.Key,
            Roles = roles,
            Permissions = permissions
        };
    }
}
