using System; using System.Linq; using System.Threading.Tasks; using System.CommandLine; using Spectre.Console; using Toak.Core; namespace Toak.Commands; public static class StatsCommand { public static async Task ExecuteAsync(bool verbose) { Logger.Verbose = verbose; var entries = HistoryManager.LoadEntries(); if (entries.Count == 0) { AnsiConsole.MarkupLine("[yellow]No history found. Cannot generate statistics.[/]"); return; } var totalCount = entries.Count; var totalDuration = TimeSpan.FromMilliseconds(entries.Sum(e => e.DurationMs)); var avgDuration = TimeSpan.FromMilliseconds(entries.Average(e => e.DurationMs)); var mostActiveDay = entries .GroupBy(e => e.Timestamp.Date) .OrderByDescending(g => g.Count()) .FirstOrDefault(); var topWords = entries .SelectMany(e => e.RefinedText.Split(new[] { ' ', '.', ',', '!', '?' }, StringSplitOptions.RemoveEmptyEntries)) .Where(w => w.Length > 3) // Exclude short common words .GroupBy(w => w.ToLowerInvariant()) .OrderByDescending(g => g.Count()) .Take(5) .Select(g => g.Key) .ToList(); AnsiConsole.MarkupLine("[bold blue]Toak Usage Statistics[/]"); AnsiConsole.MarkupLine($"[dim]Total recordings:[/] {totalCount}"); AnsiConsole.MarkupLine($"[dim]Total duration:[/] {totalDuration.TotalMinutes:F1}m"); AnsiConsole.MarkupLine($"[dim]Average processing latency:[/] {avgDuration.TotalSeconds:F2}s"); if (mostActiveDay != null) { AnsiConsole.MarkupLine($"[dim]Most active day:[/] {mostActiveDay.Key:yyyy-MM-dd} ({mostActiveDay.Count()} recordings)"); } if (topWords.Count > 0) { AnsiConsole.MarkupLine($"[dim]Top spoken words (>3 chars):[/] {string.Join(", ", topWords)}"); } } }