using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Authorization; using PlotLine.Services; using PlotLine.ViewModels; namespace PlotLine.Controllers; [Authorize] public sealed class ProjectMetricsController(ISceneMetricTypeService metrics) : Controller { public async Task Index(int projectId) { var model = await metrics.GetAsync(projectId); return model is null ? NotFound() : View(model); } public async Task Edit(int projectId, int id) { var model = await metrics.GetEditAsync(projectId, id); return model is null ? NotFound() : View(model); } [HttpPost] [ValidateAntiForgeryToken] public async Task Save(SceneMetricTypeEditViewModel model) { if (model.MinValue >= model.MaxValue) { ModelState.AddModelError(nameof(model.MaxValue), "Maximum value must be greater than minimum value."); } if (model.DefaultValue < model.MinValue || model.DefaultValue > model.MaxValue) { ModelState.AddModelError(nameof(model.DefaultValue), "Default value must sit inside the metric range."); } if (!ModelState.IsValid) { return model.MetricTypeID == 0 ? RedirectToAction(nameof(Index), new { projectId = model.ProjectID }) : View("Edit", model); } await metrics.SaveAsync(model); TempData["ProjectMetricMessage"] = model.MetricTypeID == 0 ? "Scene metric added." : "Scene metric updated."; return RedirectToAction(nameof(Index), new { projectId = model.ProjectID }); } [HttpPost] [ValidateAntiForgeryToken] public async Task AddMissingDefaults(int projectId) { await metrics.AddMissingDefaultsAsync(projectId); TempData["ProjectMetricMessage"] = "Missing default scene metrics added."; return RedirectToAction(nameof(Index), new { projectId }); } [HttpPost] [ValidateAntiForgeryToken] public async Task SetActive(int projectId, int id, bool isActive) { var updated = await metrics.SetActiveAsync(projectId, id, isActive); TempData["ProjectMetricMessage"] = updated ? (isActive ? "Metric reactivated." : "Metric deactivated.") : (isActive ? "Metric could not be reactivated." : "Metric could not be deactivated."); return RedirectToAction(nameof(Index), new { projectId }); } [HttpPost] [ValidateAntiForgeryToken] public async Task Move(int projectId, int id, string direction) { direction = string.Equals(direction, "Up", StringComparison.OrdinalIgnoreCase) ? "Up" : "Down"; var moved = await metrics.MoveAsync(projectId, id, direction); TempData["ProjectMetricMessage"] = moved ? $"Metric moved {direction.ToLowerInvariant()}." : $"Metric could not be moved {direction.ToLowerInvariant()} because it is already at the edge of its group."; return RedirectToAction(nameof(Index), new { projectId }); } [HttpPost] [ValidateAntiForgeryToken] public async Task Remove(int projectId, int id) { var removed = await metrics.RemoveUnusedAsync(projectId, id); TempData["ProjectMetricMessage"] = removed ? "Unused metric removed." : "Metric cannot be removed because scene values exist or the metric is still active."; return RedirectToAction(nameof(Index), new { projectId }); } }