namespace Fengling.Console.Controllers;

/// <summary>
/// 角色管理控制器
/// 提供角色的增删改查以及用户角色关联管理功能
/// </summary>
[ApiController]
[Route("api/console/[controller]")]
[Authorize(AuthenticationSchemes = OpenIddictValidationAspNetCoreDefaults.AuthenticationScheme)]
public class RolesController : ControllerBase
{
    private readonly IRoleService _roleService;
    private readonly ILogger<RolesController> _logger;

    public RolesController(IRoleService roleService, ILogger<RolesController> logger)
    {
        _roleService = roleService;
        _logger = logger;
    }

    /// <summary>
    /// 获取角色列表
    /// </summary>
    /// <param name="query">分页查询参数，支持按名称和租户ID筛选</param>
    /// <returns>分页的角色列表，包含角色基本信息和关联统计</returns>
    /// <response code="200">成功返回角色分页列表</response>
    /// <response code="500">服务器内部错误</response>
    [HttpGet]
    [Produces("application/json")]
    [ProducesResponseType(typeof(PagedResultDto<RoleDto>), StatusCodes.Status200OK)]
    [ProducesResponseType(typeof(object), StatusCodes.Status500InternalServerError)]
    public async Task<ActionResult<PagedResultDto<RoleDto>>> GetRoles([FromQuery] RoleQueryDto query)
    {
        try
        {
            var (items, totalCount) = await _roleService.GetRolesAsync(query.Page, query.PageSize, query.Name, query.TenantId);
            var result = new PagedResultDto<RoleDto>
            {
                Items = items.ToList(),
                TotalCount = totalCount,
                Page = query.Page,
                PageSize = query.PageSize
            };
            return Ok(result);
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "Error getting roles");
            return StatusCode(500, new { message = ex.Message });
        }
    }

    /// <summary>
    /// 获取单个角色详情
    /// </summary>
    /// <param name="id">角色ID</param>
    /// <returns>角色的详细信息，包括权限配置等</returns>
    /// <response code="200">成功返回角色详情</response>
    /// <response code="404">角色不存在</response>
    /// <response code="500">服务器内部错误</response>
    [HttpGet("{id}")]
    [Produces("application/json")]
    [ProducesResponseType(typeof(RoleDto), StatusCodes.Status200OK)]
    [ProducesResponseType(typeof(object), StatusCodes.Status404NotFound)]
    [ProducesResponseType(typeof(object), StatusCodes.Status500InternalServerError)]
    public async Task<ActionResult<RoleDto>> GetRole(long id)
    {
        try
        {
            var role = await _roleService.GetRoleAsync(id);
            if (role == null)
            {
                return NotFound();
            }
            return Ok(role);
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "Error getting role {RoleId}", id);
            return StatusCode(500, new { message = ex.Message });
        }
    }

    /// <summary>
    /// 获取指定角色的用户列表
    /// </summary>
    /// <param name="id">角色ID</param>
    /// <returns>属于该角色的所有用户列表</returns>
    /// <response code="200">成功返回用户列表</response>
    /// <response code="404">角色不存在</response>
    /// <response code="500">服务器内部错误</response>
    [HttpGet("{id}/users")]
    [Produces("application/json")]
    [ProducesResponseType(typeof(IEnumerable<UserDto>), StatusCodes.Status200OK)]
    [ProducesResponseType(typeof(object), StatusCodes.Status404NotFound)]
    [ProducesResponseType(typeof(object), StatusCodes.Status500InternalServerError)]
    public async Task<ActionResult<IEnumerable<UserDto>>> GetRoleUsers(long id)
    {
        try
        {
            var users = await _roleService.GetRoleUsersAsync(id);
            return Ok(users);
        }
        catch (KeyNotFoundException ex)
        {
            _logger.LogWarning(ex, "Role not found: {RoleId}", id);
            return NotFound();
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "Error getting users for role {RoleId}", id);
            return StatusCode(500, new { message = ex.Message });
        }
    }

    /// <summary>
    /// 创建新角色
    /// </summary>
    /// <param name="dto">创建角色所需的配置信息</param>
    /// <returns>创建的角色详情</returns>
    /// <response code="201">成功创建角色</response>
    /// <response code="400">请求参数无效或角色名称已存在</response>
    /// <response code="500">服务器内部错误</response>
    [HttpPost]
    [Produces("application/json")]
    [ProducesResponseType(typeof(RoleDto), StatusCodes.Status201Created)]
    [ProducesResponseType(typeof(object), StatusCodes.Status400BadRequest)]
    [ProducesResponseType(typeof(object), StatusCodes.Status500InternalServerError)]
    public async Task<ActionResult<RoleDto>> CreateRole([FromBody] CreateRoleDto dto)
    {
        try
        {
            var role = await _roleService.CreateRoleAsync(dto);
            return CreatedAtAction(nameof(GetRole), new { id = role.Id }, role);
        }
        catch (InvalidOperationException ex)
        {
            _logger.LogWarning(ex, "Validation error creating role");
            return BadRequest(new { message = ex.Message });
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "Error creating role");
            return StatusCode(500, new { message = ex.Message });
        }
    }

    /// <summary>
    /// 更新角色信息
    /// </summary>
    /// <param name="id">角色ID</param>
    /// <param name="dto">需要更新的角色配置信息</param>
    /// <returns>无内容响应</returns>
    /// <response code="204">成功更新角色</response>
    /// <response code="404">角色不存在</response>
    /// <response code="400">请求参数无效</response>
    /// <response code="500">服务器内部错误</response>
    [HttpPut("{id}")]
    [ProducesResponseType(StatusCodes.Status204NoContent)]
    [ProducesResponseType(typeof(object), StatusCodes.Status404NotFound)]
    [ProducesResponseType(typeof(object), StatusCodes.Status400BadRequest)]
    [ProducesResponseType(typeof(object), StatusCodes.Status500InternalServerError)]
    public async Task<IActionResult> UpdateRole(long id, [FromBody] UpdateRoleDto dto)
    {
        try
        {
            await _roleService.UpdateRoleAsync(id, dto);
            return NoContent();
        }
        catch (KeyNotFoundException ex)
        {
            _logger.LogWarning(ex, "Role not found: {RoleId}", id);
            return NotFound();
        }
        catch (InvalidOperationException ex)
        {
            _logger.LogWarning(ex, "Validation error updating role {RoleId}", id);
            return BadRequest(new { message = ex.Message });
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "Error updating role {RoleId}", id);
            return StatusCode(500, new { message = ex.Message });
        }
    }

    /// <summary>
    /// 删除角色
    /// </summary>
    /// <param name="id">角色ID</param>
    /// <returns>无内容响应</returns>
    /// <response code="204">成功删除角色</response>
    /// <response code="404">角色不存在</response>
    /// <response code="400">请求参数无效（如角色下有关联用户）</response>
    /// <response code="500">服务器内部错误</response>
    [HttpDelete("{id}")]
    [ProducesResponseType(StatusCodes.Status204NoContent)]
    [ProducesResponseType(typeof(object), StatusCodes.Status404NotFound)]
    [ProducesResponseType(typeof(object), StatusCodes.Status400BadRequest)]
    [ProducesResponseType(typeof(object), StatusCodes.Status500InternalServerError)]
    public async Task<IActionResult> DeleteRole(long id)
    {
        try
        {
            await _roleService.DeleteRoleAsync(id);
            return NoContent();
        }
        catch (KeyNotFoundException ex)
        {
            _logger.LogWarning(ex, "Role not found: {RoleId}", id);
            return NotFound();
        }
        catch (InvalidOperationException ex)
        {
            _logger.LogWarning(ex, "Validation error deleting role {RoleId}", id);
            return BadRequest(new { message = ex.Message });
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "Error deleting role {RoleId}", id);
            return StatusCode(500, new { message = ex.Message });
        }
    }

    /// <summary>
    /// 将用户添加到角色
    /// </summary>
    /// <param name="id">角色ID</param>
    /// <param name="userId">用户ID</param>
    /// <returns>无内容响应</returns>
    /// <response code="204">成功添加用户到角色</response>
    /// <response code="404">角色或用户不存在</response>
    /// <response code="400">请求参数无效或用户已在角色中</response>
    /// <response code="500">服务器内部错误</response>
    [HttpPost("{id}/users/{userId}")]
    [ProducesResponseType(StatusCodes.Status204NoContent)]
    [ProducesResponseType(typeof(object), StatusCodes.Status404NotFound)]
    [ProducesResponseType(typeof(object), StatusCodes.Status400BadRequest)]
    [ProducesResponseType(typeof(object), StatusCodes.Status500InternalServerError)]
    public async Task<IActionResult> AddUserToRole(long id, long userId)
    {
        try
        {
            await _roleService.AddUserToRoleAsync(id, userId);
            return NoContent();
        }
        catch (KeyNotFoundException ex)
        {
            _logger.LogWarning(ex, "Role or user not found: RoleId={RoleId}, UserId={UserId}", id, userId);
            return NotFound();
        }
        catch (InvalidOperationException ex)
        {
            _logger.LogWarning(ex, "Validation error adding user {UserId} to role {RoleId}", userId, id);
            return BadRequest(new { message = ex.Message });
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "Error adding user {UserId} to role {RoleId}", userId, id);
            return StatusCode(500, new { message = ex.Message });
        }
    }

    /// <summary>
    /// 将用户从角色中移除
    /// </summary>
    /// <param name="id">角色ID</param>
    /// <param name="userId">用户ID</param>
    /// <returns>无内容响应</returns>
    /// <response code="204">成功从角色中移除用户</response>
    /// <response code="404">角色或用户不存在</response>
    /// <response code="400">请求参数无效</response>
    /// <response code="500">服务器内部错误</response>
    [HttpDelete("{id}/users/{userId}")]
    [ProducesResponseType(StatusCodes.Status204NoContent)]
    [ProducesResponseType(typeof(object), StatusCodes.Status404NotFound)]
    [ProducesResponseType(typeof(object), StatusCodes.Status400BadRequest)]
    [ProducesResponseType(typeof(object), StatusCodes.Status500InternalServerError)]
    public async Task<IActionResult> RemoveUserFromRole(long id, long userId)
    {
        try
        {
            await _roleService.RemoveUserFromRoleAsync(id, userId);
            return NoContent();
        }
        catch (KeyNotFoundException ex)
        {
            _logger.LogWarning(ex, "Role or user not found: RoleId={RoleId}, UserId={UserId}", id, userId);
            return NotFound();
        }
        catch (InvalidOperationException ex)
        {
            _logger.LogWarning(ex, "Validation error removing user {UserId} from role {RoleId}", userId, id);
            return BadRequest(new { message = ex.Message });
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "Error removing user {UserId} from role {RoleId}", userId, id);
            return StatusCode(500, new { message = ex.Message });
        }
    }
}
