using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; using PlotLine.Services; using PlotLine.ViewModels; namespace PlotLine.Controllers; [Authorize] public sealed class ContinuityExplorerController(IStoryStateService storyState) : Controller { public async Task Index( [FromQuery] ContinuityFilter filter, [FromQuery] string? mode, [FromQuery] int? characterId, [FromQuery] int? assetId, [FromQuery] int? locationId, [FromQuery] int? sceneId) { ApplyDeepLinkAliases(filter, mode, characterId, assetId, locationId, sceneId); if (filter.ProjectID == 0) { return BadRequest("ProjectID is required."); } var model = await storyState.GetContinuityExplorerAsync(filter); return model is null ? NotFound() : View(model); } [HttpPost] [ValidateAntiForgeryToken] public IActionResult ApplyFilters(ContinuityFilter filter) { return RedirectToAction(nameof(Index), filter); } private static void ApplyDeepLinkAliases(ContinuityFilter filter, string? mode, int? characterId, int? assetId, int? locationId, int? sceneId) { if (!string.IsNullOrWhiteSpace(mode)) { filter.DisplayMode = mode; } var hasFriendlyEntityFilter = characterId.HasValue || assetId.HasValue || locationId.HasValue; if (hasFriendlyEntityFilter) { filter.EntityTypes = []; if (characterId.HasValue) { filter.EntityTypes.Add("Characters"); } if (assetId.HasValue) { filter.EntityTypes.Add("Assets"); } if (locationId.HasValue || string.Equals(filter.DisplayMode, "LocationActivity", StringComparison.OrdinalIgnoreCase)) { filter.EntityTypes.Add("Locations"); } } if (characterId.HasValue && !filter.CharacterIDs.Contains(characterId.Value)) { filter.CharacterIDs.Add(characterId.Value); } if (assetId.HasValue && !filter.AssetIDs.Contains(assetId.Value)) { filter.AssetIDs.Add(assetId.Value); } if (locationId.HasValue && !filter.LocationIDs.Contains(locationId.Value)) { filter.LocationIDs.Add(locationId.Value); } if (sceneId.HasValue && !filter.StartSceneID.HasValue && !filter.EndSceneID.HasValue && !filter.SelectedSceneID.HasValue) { filter.SceneRangeMode = "Custom"; filter.StartSceneID = sceneId.Value; filter.EndSceneID = sceneId.Value; filter.SelectedSceneID = sceneId.Value; } } }