using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; using Nuuru.Server.Auth; using Nuuru.Server.DTOs.Booru; using Nuuru.Server.Extensions; using Nuuru.Server.Services; using Nuuru.Server.Services.Search; namespace Nuuru.Server.Controllers { [ApiController] [Route("api/booru/posts/{postId:int}/vote")] public class VoteController : ControllerBase { private readonly IVoteService _voteService; private readonly IDefaultQueryFilterService _defaultQueryFilterService; private readonly ILogger _logger; public VoteController( IVoteService voteService, IDefaultQueryFilterService defaultQueryFilterService, ILogger logger) { _voteService = voteService; _defaultQueryFilterService = defaultQueryFilterService; _logger = logger; } /// /// Get vote state for a post /// [HttpGet] [AllowAnonymous] public async Task GetVoteState(int postId) { try { if (!await _defaultQueryFilterService.IsPostVisibleAsync(postId)) { return NotFound(new { error = "Post not found" }); } var userId = User.GetUserId(); var state = await _voteService.GetVoteStateAsync(postId, userId); return Ok(state); } catch (Exception ex) { _logger.LogError(ex, "Error getting vote state for post {PostId}", postId); return StatusCode(500, new { error = "Failed to get vote state" }); } } /// /// Cast, update, or remove a vote on a post /// [HttpPost] [Authorize(Policy = Permissions.User.Vote)] public async Task Vote(int postId, [FromBody] VoteRequest request) { try { var userId = User.GetUserId(); if (userId == null) { return Unauthorized(new { error = "User ID not found in token" }); } if (!await _defaultQueryFilterService.IsPostVisibleAsync(postId)) { return NotFound(new { error = "Post not found" }); } var result = await _voteService.VoteAsync(postId, userId.Value, request.Value); if (result == null) { return BadRequest(new { error = "Invalid vote or post not found" }); } return Ok(result); } catch (Exception ex) { _logger.LogError(ex, "Error voting on post {PostId}", postId); return StatusCode(500, new { error = "Failed to process vote" }); } } } }