using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Identity; using Microsoft.AspNetCore.Mvc; using Microsoft.EntityFrameworkCore; using System.Threading.Tasks; using vita_asistente.Models; namespace vita_asistente.Controllers { [Authorize(Roles = "Admin")] public class RolesController : Controller { private readonly RoleManager _roleManager; public RolesController(RoleManager roleManager) { _roleManager = roleManager; } // GET: Roles public async Task Index() { var roles = await _roleManager.Roles.ToListAsync(); return View(roles); } // GET: Roles/Create public IActionResult Create() { return View(); } // POST: Roles/Create [HttpPost] [ValidateAntiForgeryToken] public async Task Create(string roleName) { if (string.IsNullOrEmpty(roleName)) { ModelState.AddModelError("", "El nombre del rol no puede estar vacío."); return View(); } var roleExists = await _roleManager.RoleExistsAsync(roleName); if (!roleExists) { var result = await _roleManager.CreateAsync(new IdentityRole(roleName)); if (result.Succeeded) { return RedirectToAction(nameof(Index)); } foreach (var error in result.Errors) { ModelState.AddModelError("", error.Description); } } else { ModelState.AddModelError("", "El rol ya existe."); } return View(); } // GET: Roles/Edit/5 public async Task Edit(string id) { if (id == null) return NotFound(); var role = await _roleManager.FindByIdAsync(id); if (role == null) return NotFound(); ViewBag.RoleName = role.Name; return View(role); } // POST: Roles/Edit/5 [HttpPost] [ValidateAntiForgeryToken] public async Task Edit(string id, IdentityRole roleActualizado) { if (id != roleActualizado.Id) return NotFound(); var roleExistente = await _roleManager.FindByIdAsync(id); if (roleExistente == null) return NotFound(); // Actualizar solo el nombre roleExistente.Name = roleActualizado.Name; var result = await _roleManager.UpdateAsync(roleExistente); if (result.Succeeded) { return RedirectToAction(nameof(Index)); } foreach (var error in result.Errors) { ModelState.AddModelError("", error.Description); } return View(roleActualizado); } // GET: Roles/Disable/5 public async Task Disable(string id) { if (id == null) return NotFound(); var role = await _roleManager.FindByIdAsync(id); if (role == null) return NotFound(); return View(role); } // POST: Roles/Disable/5 [HttpPost] [ValidateAntiForgeryToken] public async Task DisableConfirmed(string id) { var role = await _roleManager.FindByIdAsync(id); if (role != null) { // En Identity, "deshabilitar" un rol implica eliminarlo // Pero primero verificamos si tiene usuarios asignados using var scope = HttpContext.RequestServices.CreateScope(); var userManager = scope.ServiceProvider.GetRequiredService>(); var usersInRole = await userManager.GetUsersInRoleAsync(role.Name ?? string.Empty); if (usersInRole.Any()) { ModelState.AddModelError("", "No se puede deshabilitar un rol que tiene usuarios asignados."); return View("Disable", role); } await _roleManager.DeleteAsync(role); } return RedirectToAction(nameof(Index)); } // GET: Roles/Delete/5 public async Task Delete(string id) { if (id == null) return NotFound(); var role = await _roleManager.FindByIdAsync(id); if (role == null) return NotFound(); return View(role); } // POST: Roles/Delete/5 [HttpPost, ActionName("Delete")] [ValidateAntiForgeryToken] public async Task DeleteConfirmed(string id) { var role = await _roleManager.FindByIdAsync(id); if (role != null) { // Verificar que no sea el rol "Admin" (o cualquier otro rol esencial) if (role.Name == "Admin" || role.Name == "Administrador") { ModelState.AddModelError("", "No se puede eliminar el rol Admin/Administrador."); return View(role); } // Verificar que no tenga usuarios asignados using var scope = HttpContext.RequestServices.CreateScope(); var userManager = scope.ServiceProvider.GetRequiredService>(); var usersInRole = await userManager.GetUsersInRoleAsync(role.Name ?? string.Empty); if (usersInRole.Any()) { ModelState.AddModelError("", "No se puede eliminar un rol que tiene usuarios asignados."); return View(role); } await _roleManager.DeleteAsync(role); } return RedirectToAction(nameof(Index)); } } }