using FlatRender.IdentitySvc.Application.Services.Interfaces;
using FlatRender.IdentitySvc.Models.Requests;
using FlatRender.IdentitySvc.Models.Responses;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;

namespace FlatRender.IdentitySvc.Controllers;

[ApiController]
[Route("v1/users")]
[Authorize]
public class UsersController(IUserService userService) : ControllerBase
{
    [HttpGet("me")]
    [ProducesResponseType(typeof(UserResponse), 200)]
    public async Task<IActionResult> GetMe()
        => Ok(await userService.GetMeAsync(GetUserId()));

    [HttpPatch("me")]
    [ProducesResponseType(typeof(UserResponse), 200)]
    public async Task<IActionResult> UpdateMe([FromBody] UpdateUserRequest request)
        => Ok(await userService.UpdateMeAsync(GetUserId(), request));

    [HttpGet("me/balance")]
    [ProducesResponseType(typeof(BalanceResponse), 200)]
    public async Task<IActionResult> GetBalance()
        => Ok(await userService.GetBalanceAsync(GetUserId()));

    [HttpPost("me/avatar")]
    public async Task<IActionResult> SetAvatar([FromBody] SetAvatarRequest request)
    {
        await userService.UpdateAvatarAsync(GetUserId(), request.AvatarId, request.AvatarUrl);
        return Ok();
    }

    [HttpGet("{userId:guid}")]
    [ProducesResponseType(typeof(UserResponse), 200)]
    [ProducesResponseType(404)]
    public async Task<IActionResult> GetById(Guid userId)
        => Ok(await userService.GetByIdAsync(userId));

    [HttpGet]
    [Authorize(Roles = "Admin")]
    [ProducesResponseType(typeof(PagedResponse<UserResponse>), 200)]
    public async Task<IActionResult> Search(
        [FromQuery] string? q,
        [FromQuery] Guid? tenantId,
        [FromQuery] int page = 1,
        [FromQuery] int pageSize = 20)
        => Ok(await userService.SearchAsync(q, tenantId, page, pageSize));

    [HttpPost("{userId:guid}/ban")]
    [Authorize(Roles = "Admin")]
    [ProducesResponseType(204)]
    public async Task<IActionResult> Ban(Guid userId, [FromBody] BanUserRequest request)
    {
        await userService.BanAsync(userId, request.Reason, request.UnblockDate);
        return NoContent();
    }

    private Guid GetUserId() => Guid.Parse(User.FindFirst(System.Security.Claims.ClaimTypes.NameIdentifier)?.Value
        ?? User.FindFirst("sub")?.Value ?? throw new UnauthorizedAccessException());
}
