using Microsoft.AspNetCore.Mvc; using Server.WatchBody.Core.Dal.Src.Repository; using Server.WatchBody.Web.Services; namespace Server.WatchBody.Web.Controllers.Admin; /// Метрики (Ф-9.4) и сводка план/факт (Ф-9.5) — только /// чтение (spec 05 m08). public class AdminMetricsController( AdminAuthService auth, IWorkoutRepository workouts, IWorkoutMetricsRepository metrics, PlanSummaryService plan) : AdminControllerBase(auth) { public ActionResult Metrics(int athleteId, string? dateFrom, string? dateTo) { if (Denied()) return UnauthorizedJson(); DateOnly? from = dateFrom != null && DateOnly.TryParse(dateFrom, out var f) ? f : null; DateOnly? to = dateTo != null && DateOnly.TryParse(dateTo, out var t) ? t : null; var rows = metrics.Select(new WorkoutMetricsFilter { AthleteId = athleteId, DateFrom = from, DateTo = to, }).ToList(); var byDate = new Dictionary(); foreach (var workout in workouts.Select(new WorkoutFilter { AthleteId = athleteId, DateFrom = from, DateTo = to })) byDate[workout.Id] = workout.StartedAt; var workoutRows = rows .OrderByDescending(m => byDate.GetValueOrDefault(m.WorkoutId)) .Select(m => new { m.WorkoutId, date = byDate.TryGetValue(m.WorkoutId, out var started) ? DateOnly.FromDateTime(started).ToString("yyyy-MM-dd") : null, m.Adherence, m.Tonnage, tonnageByGroup = Json(m.TonnageByGroup), e1pmByExercise = Json(m.E1pmByExercise), redFlags = Json(m.RedFlags), }).ToList(); // weekly: ISO-неделя даты тренировки var weekly = workoutRows .Where(r => r.date != null) .GroupBy(r => MondayOf(DateOnly.Parse(r.date!))) .Select(g => new { week = g.Key.ToString("yyyy-MM-dd"), workouts = g.Count(), avgAdherence = Math.Round(g.Average(r => r.Adherence), 1, MidpointRounding.AwayFromZero), tonnage = Math.Round(g.Sum(r => r.Tonnage), 1, MidpointRounding.AwayFromZero), }).OrderBy(w => w.week).ToList(); return new JsonResult(new { workouts = workoutRows, weekly }); } public ActionResult Plan(int athleteId) { if (Denied()) return UnauthorizedJson(); return new JsonResult(plan.Summarize(athleteId)); } private static object? Json(string? source) { if (string.IsNullOrWhiteSpace(source)) return null; try { return System.Text.Json.JsonSerializer.Deserialize(source); } catch (System.Text.Json.JsonException) { return source; } } private static DateOnly MondayOf(DateOnly date) => date.AddDays(-(((int)date.DayOfWeek + 6) % 7)); }