using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; using PlotLine.Models; using PlotLine.Services; namespace PlotLine.Controllers; [ApiController] [Authorize] [Route("api/word-companion")] public sealed class WordCompanionController(IWordCompanionService wordCompanion) : ControllerBase { [HttpGet("projects")] public Task GetProjects() => wordCompanion.ListProjectsAsync(); [HttpGet("projects/{projectId:int}/books")] public async Task GetBooks(int projectId) { var response = await wordCompanion.ListBooksAsync(projectId); return response is null ? BadRequest() : Ok(response); } [HttpPost("projects/{projectId:int}/books")] public async Task CreateBook(int projectId, WordCompanionCreateBookRequest request) { var response = await wordCompanion.CreateBookAsync(projectId, request); return response is null ? BadRequest() : Ok(response); } [HttpGet("books/{bookId:int}/structure")] public async Task GetBookStructure(int bookId) { var response = await wordCompanion.GetBookStructureAsync(bookId); return response is null ? NotFound() : Ok(response); } [HttpGet("books/{bookId:int}/chapters")] public async Task GetChapters(int bookId) { var response = await wordCompanion.ListChaptersAsync(bookId); return response is null ? BadRequest() : Ok(response); } [HttpPost("books/{bookId:int}/resolve-scene")] public async Task ResolveScene(int bookId, WordCompanionResolveSceneRequest request) { var response = await wordCompanion.ResolveSceneAsync(bookId, request); if (response is null) { return BadRequest(); } return response.BookAccessible ? Ok(response) : NotFound(response); } [HttpGet("scenes/{sceneId:int}/companion")] public async Task GetSceneCompanion(int sceneId) { var response = await wordCompanion.GetSceneCompanionAsync(sceneId); return response is null ? NotFound() : Ok(response); } [HttpPost("books/{bookId:int}/chapters")] public async Task CreateChapter(int bookId, WordCompanionCreateChapterRequest request) { var response = await wordCompanion.CreateChapterAsync(bookId, request); return response is null ? BadRequest() : Ok(response); } [HttpPost("books/{bookId:int}/chapters/{chapterId:int}/scenes")] public async Task CreateScene(int bookId, int chapterId, WordCompanionCreateSceneRequest request) { var response = await wordCompanion.CreateSceneAsync(bookId, chapterId, request); return response is null ? BadRequest() : Ok(response); } [HttpPost("books/{bookId:int}/sync-scene")] public async Task SyncScene(int bookId, WordCompanionSyncSceneRequest request) { var response = await wordCompanion.SyncSceneAsync(bookId, request); return response is null ? BadRequest() : Ok(response); } [HttpPost("books/{bookId:int}/sync-manuscript")] public async Task SyncManuscript(int bookId, WordCompanionSyncManuscriptRequest request) { var response = await wordCompanion.SyncManuscriptAsync(bookId, request); return response is null ? BadRequest() : Ok(response); } [HttpPut("scenes/{sceneId:int}/links")] public async Task UpdateSceneLinks(int sceneId, WordCompanionUpdateSceneLinksRequest request) { var response = await wordCompanion.UpdateSceneLinksAsync(sceneId, request); return response is null ? BadRequest() : Ok(response); } [HttpPatch("scenes/{sceneId:int}/word-count")] public async Task UpdateWordCount(int sceneId, WordCompanionUpdateWordCountRequest request) { var response = await wordCompanion.UpdateWordCountAsync(sceneId, request); return response is null ? BadRequest() : Ok(response); } [HttpGet("runtime/book/{bookId:int}")] public async Task GetRuntimeBook(int bookId, [FromQuery] Guid documentGuid) { var response = await wordCompanion.GetRuntimeBookAsync(bookId, documentGuid); return response is null ? NotFound() : Ok(response); } [HttpPost("runtime/scene-word-count")] public async Task UpdateRuntimeSceneWordCount(WordCompanionRuntimeSceneWordCountRequest request) { var response = await wordCompanion.UpdateRuntimeSceneWordCountAsync(request); return response is null ? BadRequest() : Ok(response); } [HttpGet("manuscript/book/{bookId:int}")] public async Task GetManuscriptForBook(int bookId) { var response = await wordCompanion.GetManuscriptForBookAsync(bookId); return response is null ? NotFound() : Ok(response); } [HttpPost("manuscript/link")] public async Task LinkManuscript(WordCompanionManuscriptLinkRequest request) { var response = await wordCompanion.LinkManuscriptAsync(request); return response is null ? BadRequest() : Ok(response); } [HttpPost("manuscript/analyse")] public async Task AnalyseManuscript(WordCompanionManuscriptAnalyseRequest request) { var response = await wordCompanion.AnalyseManuscriptAsync(request); return response is null ? BadRequest() : Ok(response); } [HttpPost("manuscript/import")] public async Task ImportManuscript(WordCompanionManuscriptImportRequest request) { var response = await wordCompanion.ImportManuscriptAsync(request); return response is null ? BadRequest() : Ok(response); } [HttpPost("manuscript/discover-characters")] public async Task DiscoverCharacters(WordCompanionDiscoverCharactersRequest request) { var response = await wordCompanion.DiscoverCharacterCandidatesAsync(request); return response is null ? BadRequest() : Ok(response); } [HttpPost("manuscript/create-discovered-characters")] public async Task CreateDiscoveredCharacters(WordCompanionCreateDiscoveredCharactersRequest request) { var response = await wordCompanion.CreateDiscoveredCharactersAsync(request); return response is null ? BadRequest() : Ok(response); } }