using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Authorization; using PlotLine.Services; using PlotLine.ViewModels; namespace PlotLine.Controllers; [Authorize] public sealed class CharactersController(ICharacterService characters) : Controller { public async Task Index(int projectId) { var model = await characters.GetCharactersAsync(projectId); return model is null ? NotFound() : View(model); } public async Task Create(int projectId) { var model = await characters.GetCreateCharacterAsync(projectId); return model is null ? NotFound() : View("Edit", model); } public async Task Edit(int id) { var model = await characters.GetEditCharacterAsync(id); return model is null ? NotFound() : View(model); } public async Task Details(int id) { var model = await characters.GetCharacterDetailAsync(id); return model is null ? NotFound() : View(model); } [HttpPost] [ValidateAntiForgeryToken] public async Task Save(CharacterEditViewModel model) { if (!ModelState.IsValid) { return View("Edit", model); } int characterId; try { characterId = await characters.SaveCharacterAsync(model); } catch (SubscriptionLimitException ex) when (model.CharacterID == 0) { ModelState.AddModelError(string.Empty, ex.Message); var createModel = await characters.GetCreateCharacterAsync(model.ProjectID); if (createModel is null) { return NotFound(); } createModel.CharacterName = model.CharacterName; createModel.ShortName = model.ShortName; createModel.Sex = model.Sex; createModel.BirthDate = model.BirthDate; createModel.AgeAtSeriesStart = model.AgeAtSeriesStart; createModel.Height = model.Height; createModel.EyeColour = model.EyeColour; createModel.CharacterImportance = model.CharacterImportance; createModel.ShowInQuickAddBar = model.ShowInQuickAddBar; createModel.DefaultDescription = model.DefaultDescription; return View("Edit", createModel); } return RedirectToAction(nameof(Details), new { id = characterId }); } [HttpPost] [ValidateAntiForgeryToken] public async Task Archive(int id, int projectId) { await characters.ArchiveCharacterAsync(id); TempData["ArchiveMessage"] = "Character archived. You can restore it from Archived Items."; return RedirectToAction(nameof(Index), new { projectId }); } [HttpPost] [ValidateAntiForgeryToken] public async Task SaveInitialRelationship(InitialRelationshipEditViewModel model) { await characters.SaveInitialRelationshipAsync(model); TempData["RelationshipMessage"] = model.CharacterRelationshipID == 0 ? "Initial relationship added." : "Initial relationship updated."; return RedirectToAction(nameof(Details), new { id = model.ReturnCharacterID ?? model.CharacterID }); } [HttpPost] [ValidateAntiForgeryToken] public async Task ArchiveRelationship(int id, int characterId) { await characters.ArchiveRelationshipAsync(id); TempData["ArchiveMessage"] = "Relationship archived. You can restore it from Archived Items."; return RedirectToAction(nameof(Details), new { id = characterId }); } }