using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; using Nuuru.Server.DTOs.Boints; using Nuuru.Server.Extensions; using Nuuru.Server.Services; namespace Nuuru.Server.Controllers { [ApiController] [Route("api/boints")] public class BointsController : ControllerBase { private readonly IBointsService _bointsService; private readonly ILogger _logger; public BointsController(IBointsService bointsService, ILogger logger) { _bointsService = bointsService; _logger = logger; } [HttpGet("status")] [AllowAnonymous] public async Task GetStatus() { var enabled = await _bointsService.IsEnabledAsync(); var mode = enabled ? await _bointsService.GetModeAsync() : "normal"; var clansEnabled = enabled && await _bointsService.IsClansEnabledAsync(); return Ok(new { enabled, mode, clansEnabled }); } [HttpGet("balance")] [Authorize] public async Task GetBalance() { if (!await _bointsService.IsEnabledAsync()) return Ok(new { balance = 0 }); var userId = User.GetUserId(); if (userId == null) return Unauthorized(); var balance = await _bointsService.GetBalanceAsync(userId.Value); return Ok(new { balance }); } [HttpGet("ledger")] [Authorize] public async Task GetLedger([FromQuery] int page = 1, [FromQuery] int pageSize = 50) { var userId = User.GetUserId(); if (userId == null) return Unauthorized(); pageSize = Math.Clamp(pageSize, 1, 100); var (items, totalCount) = await _bointsService.GetLedgerAsync(userId.Value, page, pageSize); return Ok(new { items, totalCount, page, pageSize }); } [HttpGet("user/{username}")] [AllowAnonymous] public async Task GetUserBalance(string username) { if (!await _bointsService.IsEnabledAsync()) return Ok(new { balance = 0 }); var balance = await _bointsService.GetBalanceByUsernameAsync(username); return Ok(new { balance }); } [HttpGet("shop")] [Authorize] public async Task GetShop() { var items = await _bointsService.GetShopItemsAsync(); return Ok(items); } [HttpGet("inventory")] [Authorize] public async Task GetInventory() { var userId = User.GetUserId(); if (userId == null) return Unauthorized(); var items = await _bointsService.GetInventoryAsync(userId.Value); return Ok(items); } [HttpPost("inventory/use")] [Authorize] public async Task UseItem([FromBody] UseItemRequest request) { var userId = User.GetUserId(); if (userId == null) return Unauthorized(); var result = await _bointsService.UseInventoryItemAsync( userId.Value, request.ItemId, request.TargetUserId, request.TargetPostId, request.Content); if (!result.Success) return BadRequest(new { error = result.Error }); return Ok(new { message = "Item used.", data = result.Data }); } [HttpPost("purchase")] [Authorize] public async Task Purchase([FromBody] PurchaseRequest request) { var userId = User.GetUserId(); if (userId == null) return Unauthorized(); var result = await _bointsService.PurchaseItemAsync(userId.Value, request.ItemId, request.TargetUserId, request.TargetPostId, request.Content); if (!result.Success) return BadRequest(new { error = result.Error }); return Ok(new { message = "Purchase successful.", data = result.Data }); } [HttpGet("effects")] [AllowAnonymous] public async Task GetActiveEffects() { var effects = await _bointsService.GetActiveEffectsAsync(); return Ok(effects); } [HttpPost("transfer")] [Authorize] public async Task Transfer([FromBody] TransferBointsRequest request) { var userId = User.GetUserId(); if (userId == null) return Unauthorized(); var result = await _bointsService.TransferAsync(userId.Value, request.ToUserId, request.Amount); if (!result.Success) return BadRequest(new { error = result.Error }); return Ok(new { message = $"Transferred {request.Amount} boints." }); } [HttpPost("admin/adjust")] [Authorize(Policy = Auth.Permissions.Admin.ManageUsers)] public async Task AdminAdjust([FromBody] AdminBointsRequest request) { var adminId = User.GetUserId(); if (adminId == null) return Unauthorized(); var success = await _bointsService.AdminAdjustAsync(request.UserId, request.Amount, adminId.Value); if (!success) return BadRequest(new { error = "Failed to adjust boints." }); return Ok(new { message = $"Adjusted by {request.Amount} boints." }); } } }