using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; using Nuuru.Server.Services.Search.Forum; namespace Nuuru.Server.Controllers { [ApiController] [Route("api/forum/search")] [AllowAnonymous] public class ForumSearchController : ControllerBase { private readonly IForumSearchService _searchService; private readonly ILogger _logger; public ForumSearchController( IForumSearchService searchService, ILogger logger) { _searchService = searchService; _logger = logger; } [HttpGet] public async Task Search( [FromQuery] string? q, [FromQuery] int page = 1, [FromQuery] int pageSize = 20, [FromQuery] string mode = "posts") { try { if (string.IsNullOrWhiteSpace(q) || q.Length < 1 || q.Length > 500) { return BadRequest(new { error = "Query must be between 1 and 500 characters" }); } if (page < 1) { return BadRequest(new { error = "Page must be greater than 0" }); } if (pageSize < 1 || pageSize > 100) { return BadRequest(new { error = "Page size must be between 1 and 100" }); } if (mode == "threads") { var result = await _searchService.SearchThreadsAsync(q, page, pageSize); return Ok(new { mode = "threads", items = result.Threads.Items, totalCount = result.Threads.TotalCount, page = result.Threads.Page, pageSize = result.Threads.PageSize, totalPages = result.Threads.TotalPages, meta = new { queryTimeMs = result.Metadata.QueryTimeMs, warnings = result.Metadata.Warnings } }); } else { var result = await _searchService.SearchPostsAsync(q, page, pageSize); return Ok(new { mode = "posts", items = result.Posts.Items, totalCount = result.Posts.TotalCount, page = result.Posts.Page, pageSize = result.Posts.PageSize, totalPages = result.Posts.TotalPages, meta = new { queryTimeMs = result.Metadata.QueryTimeMs, warnings = result.Metadata.Warnings } }); } } catch (Exception ex) { _logger.LogError(ex, "Error searching forum with query '{Query}' mode '{Mode}'", q, mode); return StatusCode(500, new { error = "Failed to search" }); } } } }