using Microsoft.EntityFrameworkCore;
using WorkManagementTool.Data;
using WorkManagementTool.Data.Entities;

namespace WorkManagementTool.Services
{
    public class ProjectTaskService
    {
        private readonly ApplicationDbContext _context;
        
        public ProjectTaskService(ApplicationDbContext context)
        {
            _context = context;
        }

        public async Task<List<ProjectTask>> GetAllTasksAsync(int projectId)
        {
            return await _context.ProjectTasks
                .Include(t => t.PreviousTasks)
                .Include(t => t.Project)
                .Where(w => w.Project.Id == projectId)
                .ToListAsync();
        }

        public async Task<ProjectTask?> GetTaskByIdAsync(int taskId)
        {
            return await _context.ProjectTasks
                .Include(t => t.PreviousTasks)
                .Include(t => t.Project)
                .FirstOrDefaultAsync(t => t.Id == taskId);
        }

        // Ajout : accepter une liste d'ids pour PreviousTasks afin d'éviter les conflits de tracking
        public async Task AddTaskAsync(ProjectTask task, IEnumerable<int>? previousIds = null)
        {
            if (previousIds != null && previousIds.Any())
            {
                var trackedPrev = await _context.ProjectTasks
                    .Where(t => previousIds.Contains(t.Id))
                    .ToListAsync();

                task.PreviousTasks = trackedPrev;
            }
            else
            {
                task.PreviousTasks = new List<ProjectTask>();
            }

            _context.ProjectTasks.Add(task);
            await _context.SaveChangesAsync();
        }

        // Mise à jour : charger l'entité existante et appliquer les modifications + dépendances
        public async Task UpdateTaskAsync(ProjectTask task, IEnumerable<int>? previousIds = null)
        {
            // Récupérer l'entité suivie par le contexte
            var existing = await _context.ProjectTasks
                .Include(t => t.PreviousTasks)
                .Include(t => t.Project)
                .FirstOrDefaultAsync(t => t.Id == task.Id);

            if (existing is null)
            {
                // si l'entité n'existe pas encore dans la BDD, fallback : attacher et mettre à jour
                if (previousIds != null && previousIds.Any())
                {
                    var trackedPrev = await _context.ProjectTasks
                        .Where(t => previousIds.Contains(t.Id))
                        .ToListAsync();
                    task.PreviousTasks = trackedPrev;
                }

                _context.ProjectTasks.Update(task);
                await _context.SaveChangesAsync();
                return;
            }

            // Mettre à jour les propriétés scalaires
            existing.Title = task.Title;
            existing.Description = task.Description;
            existing.DueDate = task.DueDate;
            existing.IsCompleted = task.IsCompleted;
            existing.CreatedAt = task.CreatedAt;

            // Mettre à jour la collection PreviousTasks selon les ids fournis
            if (previousIds != null)
            {
                if (previousIds.Any())
                {
                    var trackedPrev = await _context.ProjectTasks
                        .Where(t => previousIds.Contains(t.Id))
                        .ToListAsync();

                    // Remplacer la collection existante par les entités tracées
                    existing.PreviousTasks = trackedPrev;
                }
                else
                {
                    existing.PreviousTasks = new List<ProjectTask>();
                }
            }

            _context.ProjectTasks.Update(existing);
            await _context.SaveChangesAsync();
        }

        public async Task DeleteTaskAsync(int taskId)
        {
            var task = await _context.ProjectTasks.FindAsync(taskId);
            if (task != null)
            {
                _context.ProjectTasks.Remove(task);
                await _context.SaveChangesAsync();
            }
        }
    }
}
