using Microsoft.EntityFrameworkCore; using TaskTracker.Core.Entities; using TaskTracker.Core.Enums; using TaskTracker.Core.Interfaces; using TaskTracker.Infrastructure.Data; namespace TaskTracker.Infrastructure.Repositories; public class TaskRepository(TaskTrackerDbContext db) : ITaskRepository { public async Task> GetAllAsync(WorkTaskStatus? status = null, int? parentId = null, bool includeSubTasks = false) { var query = db.Tasks.Include(t => t.Notes).Include(t => t.SubTasks).AsQueryable(); if (status.HasValue) query = query.Where(t => t.Status == status.Value); if (parentId.HasValue) query = query.Where(t => t.ParentTaskId == parentId.Value); else if (!includeSubTasks) query = query.Where(t => t.ParentTaskId == null); return await query.OrderByDescending(t => t.CreatedAt).ToListAsync(); } public async Task GetByIdAsync(int id) { return await db.Tasks .Include(t => t.Notes.OrderByDescending(n => n.CreatedAt)) .Include(t => t.ContextEvents.OrderByDescending(c => c.Timestamp).Take(20)) .Include(t => t.SubTasks) .Include(t => t.ParentTask) .FirstOrDefaultAsync(t => t.Id == id); } public async Task GetActiveTaskAsync() { return await db.Tasks .Include(t => t.Notes.OrderByDescending(n => n.CreatedAt)) .Include(t => t.ContextEvents.OrderByDescending(c => c.Timestamp).Take(20)) .Include(t => t.SubTasks) .Include(t => t.ParentTask) .FirstOrDefaultAsync(t => t.Status == WorkTaskStatus.Active); } public async Task> GetSubTasksAsync(int parentId) { return await db.Tasks .Include(t => t.SubTasks) .Where(t => t.ParentTaskId == parentId) .OrderByDescending(t => t.CreatedAt) .ToListAsync(); } public async Task CreateAsync(WorkTask task) { task.CreatedAt = DateTime.UtcNow; db.Tasks.Add(task); await db.SaveChangesAsync(); return task; } public async Task UpdateAsync(WorkTask task) { db.Tasks.Update(task); await db.SaveChangesAsync(); } public async Task DeleteAsync(int id) { var task = await db.Tasks.Include(t => t.SubTasks).FirstOrDefaultAsync(t => t.Id == id); if (task is not null) { await AbandonDescendantsAsync(task); task.Status = WorkTaskStatus.Abandoned; await db.SaveChangesAsync(); } } private async System.Threading.Tasks.Task AbandonDescendantsAsync(WorkTask task) { var children = await db.Tasks.Include(t => t.SubTasks).Where(t => t.ParentTaskId == task.Id).ToListAsync(); foreach (var child in children) { await AbandonDescendantsAsync(child); child.Status = WorkTaskStatus.Abandoned; } } }