using Common.Security;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders;
using Modules.User.Database.Database.Entities;

namespace Modules.User.Database.Database;

internal static class RolesAndPermissionSeedList
{
    private const int _pPermissionsViewDetails = 1;
    private const int _pPermissionsManage      = 2;
    private const int _pUsersViewPublicProfile = 3;
    private const int _pUsersViewProfileDetail = 4;
    private const int _pUsersViewList          = 5;
    private const int _pUsersManage            = 6;
    private const int _pUsersBan               = 7;
    private const int _pUsersUnban             = 8;
    private const int _pUsersManagePermissions = 9;
    private const int _pLibRead               = 10;
    private const int _pLibVote               = 11;
    private const int _pLibManage             = 12;
    private const int _pLibDictRead           = 13;
    private const int _pLibDictManage         = 14;
    private const int _pViewsReadCount        = 15;
    private const int _pViewsReadSelf         = 16;
    private const int _pViewsManageSelf       = 17;
    
    private const int _rAdmin      = 1;
    private const int _rVisitor    = 2;
    private const int _rModerator    = 3;
    private const int _rLibrarian  = 4;

    internal static void SeedPermissions(EntityTypeBuilder<Permission> builder)
    {
        builder.HasData(
            new Permission { Id = _pPermissionsViewDetails, Code = Constants.Permissions.ViewDetails,                 Name = "Просмотр разрешений" },
            new Permission { Id = _pPermissionsManage,      Code = Constants.Permissions.Manage,                      Name = "Управление разрешениями" },
            
            new Permission { Id = _pUsersViewPublicProfile, Code = Constants.Permissions.User.ViewProfilePublic,      Name = "Просмотр публичного профиля пользователя" },
            new Permission { Id = _pUsersViewProfileDetail, Code = Constants.Permissions.User.ViewProfileDetail,      Name = "Просмотр детального профиля пользователя" },
            new Permission { Id = _pUsersViewList,          Code = Constants.Permissions.User.ViewList,               Name = "Просмотр списка пользователей" },
            new Permission { Id = _pUsersManage,            Code = Constants.Permissions.User.Manage,                 Name = "Управление пользователями" },
            new Permission { Id = _pUsersBan,               Code = Constants.Permissions.User.Ban,                    Name = "Бан пользователей" },
            new Permission { Id = _pUsersUnban,             Code = Constants.Permissions.User.Unban,                  Name = "Разбан пользователей" },
            new Permission { Id = _pUsersManagePermissions, Code = Constants.Permissions.User.ManagePermissions,      Name = "Управление разрешениями пользователей" },
            
            new Permission { Id = _pLibRead,                Code = Constants.Permissions.Library.Read,                Name = "Чтение библиотеки" },
            new Permission { Id = _pLibVote,                Code = Constants.Permissions.Library.Vote,                Name = "Голосование" },
            new Permission { Id = _pLibManage,              Code = Constants.Permissions.Library.Manage,              Name = "Управление библиотекой" },
            new Permission { Id = _pLibDictRead,            Code = Constants.Permissions.Library.Dictionaries.Read,   Name = "Чтение словарей" },
            new Permission { Id = _pLibDictManage,          Code = Constants.Permissions.Library.Dictionaries.Manage, Name = "Управление словарями" },
            new Permission { Id = _pViewsReadCount,         Code = Constants.Permissions.Library.Views.ReadCount,     Name = "Чтение общего числа просмотров" },
            new Permission { Id = _pViewsReadSelf,          Code = Constants.Permissions.Library.Views.ReadSelf,      Name = "Чтение своих просмотров" },
            new Permission { Id = _pViewsManageSelf,        Code = Constants.Permissions.Library.Views.ManageSelf,    Name = "Управление своими просмотрами" }
        );
    }
    internal static void SeedRoles(EntityTypeBuilder<Role> roleBuilder, ModelBuilder builder)
    {
        var rolePermissions = new HashSet<(int RoleId, int PermissionId)>
        {
            // Visitor
            (_rVisitor, _pLibRead),
            (_rVisitor, _pLibVote),
            (_rVisitor, _pViewsReadCount),
            (_rVisitor, _pViewsReadSelf),
            (_rVisitor, _pViewsManageSelf),
            (_rVisitor, _pUsersViewPublicProfile),

            // Librarian
            (_rLibrarian, _pLibManage),
            (_rLibrarian, _pLibDictRead),
            (_rLibrarian, _pLibDictManage),

            // Moderator
            (_rModerator, _pUsersViewProfileDetail),
            (_rModerator, _pUsersViewList),
            (_rModerator, _pUsersBan),
            (_rModerator, _pUsersUnban),

            // Admin
            (_rAdmin, _pUsersManage),
            (_rAdmin, _pUsersManagePermissions),
            (_rAdmin, _pPermissionsViewDetails),
            (_rAdmin, _pPermissionsManage)
        };
        
        // Добавляем наследование прав от предыдущих ролей
        foreach (var inherited in rolePermissions.Where(x => x.RoleId == _rVisitor).ToList())
        {
            rolePermissions.Add((_rLibrarian, inherited.PermissionId));
            rolePermissions.Add((_rModerator, inherited.PermissionId));
            rolePermissions.Add((_rAdmin, inherited.PermissionId));
        }
        
        foreach (var inherited in rolePermissions.Where(x => x.RoleId == _rLibrarian).ToList())
        {
            rolePermissions.Add((_rAdmin, inherited.PermissionId));
        }

        foreach (var inherited in rolePermissions.Where(x => x.RoleId == _rModerator).ToList())
        {
            rolePermissions.Add((_rAdmin, inherited.PermissionId));
        }
        
        
        roleBuilder.HasData(
            new Role { Id = _rVisitor,   Name = "Посетитель",    Code = "visitor"   },
            new Role { Id = _rLibrarian, Name = "Библиотекарь",  Code = "librarian" },
            new Role { Id = _rModerator, Name = "Модератор",     Code = "moderator" },
            new Role { Id = _rAdmin,     Name = "Администратор", Code = "admin"   }
        );
        builder.Entity("RolePermissions").HasData(
            rolePermissions.Select(x => new { x.RoleId, x.PermissionId }).ToArray<object>()
        );
        /*
        builder.Entity("RolePermissions").HasData(
                // Visitor
                new { RoleId = rVisitor,   PermissionId = pLibRead },
                new { RoleId = rVisitor,   PermissionId = pLibVote },
                new { RoleId = rVisitor,   PermissionId = pViewsReadCount },
                new { RoleId = rVisitor,   PermissionId = pViewsReadSelf },
                new { RoleId = rVisitor,   PermissionId = pViewsManageSelf },
                new { RoleId = rVisitor, PermissionId = pUsersViewPublicProfile },

                // Librarian = Visitor + manage
                new { RoleId = rLibrarian, PermissionId = pLibRead },
                new { RoleId = rLibrarian, PermissionId = pLibVote },
                new { RoleId = rLibrarian, PermissionId = pViewsReadCount },
                new { RoleId = rLibrarian, PermissionId = pViewsReadSelf },
                new { RoleId = rLibrarian, PermissionId = pViewsManageSelf },
                new { RoleId = rLibrarian, PermissionId = pUsersViewPublicProfile },
                new { RoleId = rLibrarian, PermissionId = pLibManage },
                new { RoleId = rLibrarian, PermissionId = pLibDictRead },
                new { RoleId = rLibrarian, PermissionId = pLibDictManage },

                // Moderator = Visitor + ban/unban users
                new { RoleId = rModerator, PermissionId = pLibRead },
                new { RoleId = rModerator, PermissionId = pLibVote },
                new { RoleId = rModerator, PermissionId = pViewsReadCount },
                new { RoleId = rModerator, PermissionId = pViewsReadSelf },
                new { RoleId = rModerator, PermissionId = pViewsManageSelf },
                new { RoleId = rModerator, PermissionId = pUsersViewPublicProfile },
                new { RoleId = rModerator, PermissionId = pUsersViewProfileDetail },
                new { RoleId = rModerator, PermissionId = pUsersViewList },
                new { RoleId = rModerator, PermissionId = pUsersBan },
                new { RoleId = rModerator, PermissionId = pUsersUnban },

                // Admin = Librarian + users/roles manage
                new { RoleId = rAdmin,     PermissionId = pLibRead },
                new { RoleId = rAdmin,     PermissionId = pLibVote },
                new { RoleId = rAdmin,     PermissionId = pViewsReadCount },
                new { RoleId = rAdmin,     PermissionId = pViewsReadSelf },
                new { RoleId = rAdmin,     PermissionId = pViewsManageSelf },
                new { RoleId = rAdmin,     PermissionId = pLibManage },
                new { RoleId = rAdmin,     PermissionId = pLibDictRead },
                new { RoleId = rAdmin,     PermissionId = pLibDictManage },
                new { RoleId = rAdmin,     PermissionId = pUsersManage },
                new { RoleId = rAdmin,     PermissionId = pUsersManagePermissions },
                new { RoleId = rAdmin,     PermissionId = pUsersViewPublicProfile },
                new { RoleId = rAdmin,     PermissionId = pUsersViewProfileDetail },
                new { RoleId = rAdmin,     PermissionId = pUsersViewList },
                new { RoleId = rAdmin,     PermissionId = pUsersBan },
                new { RoleId = rAdmin,     PermissionId = pUsersUnban },
                new { RoleId = rAdmin,     PermissionId = pPermissionsViewDetails },
                new { RoleId = rAdmin,     PermissionId = pPermissionsManage }
            );
        */
    }
}