using LinqToDB; using Azaion.Missions.Database; using Azaion.Missions.Database.Entities; using Azaion.Missions.DTOs; namespace Azaion.Missions.Services; public class MissionService(AppDataConnection db) { public async Task CreateMission(CreateMissionRequest request) { var vehicleExists = await db.Vehicles.AnyAsync(v => v.Id == request.VehicleId); if (!vehicleExists) throw new ArgumentException($"Vehicle {request.VehicleId} not found"); var mission = new Mission { Id = Guid.NewGuid(), CreatedDate = request.CreatedDate ?? DateTime.UtcNow, Name = request.Name, VehicleId = request.VehicleId }; await db.InsertAsync(mission); return mission; } public async Task UpdateMission(Guid id, UpdateMissionRequest request) { var mission = await db.Missions.FirstOrDefaultAsync(m => m.Id == id) ?? throw new KeyNotFoundException($"Mission {id} not found"); if (request.Name != null) mission.Name = request.Name; if (request.VehicleId.HasValue) { var vehicleExists = await db.Vehicles.AnyAsync(v => v.Id == request.VehicleId.Value); if (!vehicleExists) throw new ArgumentException($"Vehicle {request.VehicleId} not found"); mission.VehicleId = request.VehicleId.Value; } await db.UpdateAsync(mission); return mission; } public async Task GetMission(Guid id) { var mission = await db.Missions.FirstOrDefaultAsync(m => m.Id == id) ?? throw new KeyNotFoundException($"Mission {id} not found"); return mission; } public async Task> GetMissions(GetMissionsQuery query) { var q = db.Missions.AsQueryable(); if (!string.IsNullOrEmpty(query.Name)) q = q.Where(m => m.Name.ToLower().Contains(query.Name.ToLower())); if (query.FromDate.HasValue) q = q.Where(m => m.CreatedDate >= query.FromDate.Value); if (query.ToDate.HasValue) q = q.Where(m => m.CreatedDate <= query.ToDate.Value); var totalCount = await q.CountAsync(); var items = await q .OrderByDescending(m => m.CreatedDate) .Skip((query.Page - 1) * query.PageSize) .Take(query.PageSize) .ToListAsync(); return new PaginatedResponse { Items = items, TotalCount = totalCount, Page = query.Page, PageSize = query.PageSize }; } public async Task DeleteMission(Guid id) { var mission = await db.Missions.FirstOrDefaultAsync(m => m.Id == id) ?? throw new KeyNotFoundException($"Mission {id} not found"); await db.MapObjects.DeleteAsync(o => o.MissionId == id); var waypointIds = await db.Waypoints.Where(w => w.MissionId == id).Select(w => w.Id).ToListAsync(); if (waypointIds.Count > 0) { var mediaIds = await db.Media.Where(m => m.WaypointId != null && waypointIds.Contains(m.WaypointId!.Value)) .Select(m => m.Id).ToListAsync(); if (mediaIds.Count > 0) { var annotationIds = await db.Annotations.Where(a => mediaIds.Contains(a.MediaId)) .Select(a => a.Id).ToListAsync(); if (annotationIds.Count > 0) await db.Detections.DeleteAsync(d => annotationIds.Contains(d.AnnotationId)); await db.Annotations.DeleteAsync(a => mediaIds.Contains(a.MediaId)); } await db.Media.DeleteAsync(m => m.WaypointId != null && waypointIds.Contains(m.WaypointId!.Value)); } await db.Waypoints.DeleteAsync(w => w.MissionId == id); await db.Missions.DeleteAsync(m => m.Id == id); } }