using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Authorization; using PlotLine.Services; using PlotLine.ViewModels; namespace PlotLine.Controllers; [Authorize] public sealed class WriterController( IWriterWorkspaceService writerWorkspace, IWritingScheduleService writingSchedule) : Controller { public async Task Index(int? projectId) { var model = await writerWorkspace.GetDashboardAsync(projectId); return View(model); } public async Task Chapter(int id) { var model = await writerWorkspace.GetChapterWorkflowAsync(id); return model is null ? NotFound() : View(model); } public async Task SchedulePreview(int? writingPlanId) { var model = await writingSchedule.GetSchedulePreviewAsync(writingPlanId); return View(model); } [HttpPost] [ValidateAntiForgeryToken] public async Task GenerateSchedule(int writingPlanId) { try { var items = await writingSchedule.GenerateSchedule(writingPlanId); TempData["SchedulePreviewMessage"] = $"{items.Count} item{(items.Count == 1 ? "" : "s")} generated."; } catch (InvalidOperationException ex) { TempData["SchedulePreviewError"] = ex.Message; } return RedirectToAction(nameof(SchedulePreview), new { writingPlanId }); } [HttpPost] [ValidateAntiForgeryToken] public async Task DeleteGeneratedSchedule(int writingPlanId) { await writingSchedule.DeleteScheduleAsync(writingPlanId); TempData["SchedulePreviewMessage"] = "Generated schedule deleted."; return RedirectToAction(nameof(SchedulePreview), new { writingPlanId }); } [HttpPost] [ValidateAntiForgeryToken] public async Task SaveChapterGoal(ChapterGoalEditViewModel model) { await writerWorkspace.SaveChapterGoalAsync(model); return RedirectToAction(nameof(Chapter), new { id = model.ChapterID }); } }