using Microsoft.EntityFrameworkCore; using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using Haoliang.Models.DataCollection; using Haoliang.Data.Repositories; namespace Haoliang.Data.Repositories { public interface ICollectionResultRepository : IRepository { Task> GetByDeviceAsync(int deviceId); Task> GetByDateRangeAsync(int deviceId, DateTime startDate, DateTime endDate); Task GetStatisticsAsync(DateTime date); Task GetHealthAsync(); Task ArchiveResultsAsync(int daysToKeep = 30); Task> GetSuccessfulResultsAsync(int deviceId, DateTime date); Task> GetFailedResultsAsync(int deviceId, DateTime date); Task GetAverageResponseTimeAsync(int deviceId, DateTime date); Task GetSuccessRateAsync(int deviceId, DateTime date); } public class CollectionResultRepository : Repository, ICollectionResultRepository { private readonly CNCDbContext _context; public CollectionResultRepository(CNCDbContext context) : base(context) { _context = context; } public async Task> GetByDeviceAsync(int deviceId) { return await _context.CollectionResults .Where(r => r.DeviceId == deviceId) .OrderByDescending(r => r.CollectionTime) .ToListAsync(); } public async Task> GetByDateRangeAsync(int deviceId, DateTime startDate, DateTime endDate) { return await _context.CollectionResults .Where(r => r.DeviceId == deviceId && r.CollectionTime >= startDate && r.CollectionTime <= endDate) .OrderByDescending(r => r.CollectionTime) .ToListAsync(); } public async Task GetStatisticsAsync(DateTime date) { var startOfDay = date.Date; var endOfDay = startOfDay.AddDays(1); var results = await _context.CollectionResults .Where(r => r.CollectionTime >= startOfDay && r.CollectionTime <= endOfDay) .ToListAsync(); var stats = new CollectionStatistics { Date = date, TotalAttempts = results.Count(), SuccessCount = results.Count(r => r.IsSuccess), FailedCount = results.Count(r => !r.IsSuccess), SuccessRate = results.Any() ? (decimal)results.Count(r => r.IsSuccess) / results.Count() * 100 : 0, DeviceCount = results.Select(r => r.DeviceId).Distinct().Count(), OnlineDeviceCount = await _context.Devices.CountAsync(d => d.IsOnline), TotalDataSize = results.Sum(r => r.DataSize ?? 0) }; if (stats.SuccessCount > 0) { var successfulResults = results.Where(r => r.IsSuccess).ToList(); stats.AverageResponseTime = TimeSpan.FromTicks( (long)successfulResults.Average(r => r.ResponseTime ?? 0)); } return stats; } public async Task GetHealthAsync() { var stats = await GetStatisticsAsync(DateTime.Now); var onlineDeviceCount = await _context.Devices.CountAsync(d => d.IsOnline); var availableDeviceCount = await _context.Devices.CountAsync(d => d.IsAvailable); var activeTasks = await _context.CollectionTasks .CountAsync(t => t.Status == "Running"); var failedTasks = await _context.CollectionTasks .CountAsync(t => t.Status == "Failed"); var lastSuccessful = await _context.CollectionResults .Where(r => r.IsSuccess) .OrderByDescending(r => r.CollectionTime) .FirstOrDefault(); var lastFailed = await _context.CollectionResults .Where(r => !r.IsSuccess) .OrderByDescending(r => r.CollectionTime) .FirstOrDefault(); return new CollectionHealth { CheckTime = DateTime.Now, TotalDevices = onlineDeviceCount, OnlineDevices = availableDeviceCount, ActiveCollectionTasks = activeTasks, FailedTasks = failedTasks, SuccessRate = stats.SuccessRate, AverageResponseTime = stats.AverageResponseTime, TotalCollectedData = stats.TotalDataSize, LastSuccessfulCollection = lastSuccessful?.CollectionTime ?? DateTime.MinValue, LastFailedCollection = lastFailed?.CollectionTime ?? DateTime.MinValue }; } public async Task ArchiveResultsAsync(int daysToKeep = 30) { var cutoffDate = DateTime.Now.AddDays(-daysToKeep); var resultsToArchive = await _context.CollectionResults .Where(r => r.CollectionTime < cutoffDate) .ToListAsync(); if (resultsToArchive.Any()) { // In a real implementation, you would move these to an archive table _context.CollectionResults.RemoveRange(resultsToArchive); await SaveAsync(); } } public async Task> GetSuccessfulResultsAsync(int deviceId, DateTime date) { var startOfDay = date.Date; var endOfDay = startOfDay.AddDays(1); return await _context.CollectionResults .Where(r => r.DeviceId == deviceId && r.CollectionTime >= startOfDay && r.CollectionTime <= endOfDay && r.IsSuccess) .OrderByDescending(r => r.CollectionTime) .ToListAsync(); } public async Task> GetFailedResultsAsync(int deviceId, DateTime date) { var startOfDay = date.Date; var endOfDay = startOfDay.AddDays(1); return await _context.CollectionResults .Where(r => r.DeviceId == deviceId && r.CollectionTime >= startOfDay && r.CollectionTime <= endOfDay && !r.IsSuccess) .OrderByDescending(r => r.CollectionTime) .ToListAsync(); } public async Task GetAverageResponseTimeAsync(int deviceId, DateTime date) { var startOfDay = date.Date; var endOfDay = startOfDay.AddDays(1); var successfulResults = await _context.CollectionResults .Where(r => r.DeviceId == deviceId && r.CollectionTime >= startOfDay && r.CollectionTime <= endOfDay && r.IsSuccess) .ToListAsync(); if (successfulResults.Any()) { var averageTicks = (long)successfulResults.Average(r => r.ResponseTime ?? 0); return new AverageResponseTime { DeviceId = deviceId, Date = date, AverageTime = TimeSpan.FromTicks(averageTicks), SampleCount = successfulResults.Count }; } return new AverageResponseTime { DeviceId = deviceId, Date = date, AverageTime = TimeSpan.Zero, SampleCount = 0 }; } public async Task GetSuccessRateAsync(int deviceId, DateTime date) { var startOfDay = date.Date; var endOfDay = startOfDay.AddDays(1); var results = await _context.CollectionResults .Where(r => r.DeviceId == deviceId && r.CollectionTime >= startOfDay && r.CollectionTime <= endOfDay) .ToListAsync(); if (results.Any()) { var successCount = results.Count(r => r.IsSuccess); return (int)(decimal)successCount / results.Count() * 100; } return 0; } } }