using MediatR;
using ColaFlow.Modules.ProjectManagement.Application.DTOs;
using ColaFlow.Modules.ProjectManagement.Domain.Repositories;
using ColaFlow.Modules.ProjectManagement.Domain.ValueObjects;
using ColaFlow.Modules.ProjectManagement.Domain.Exceptions;

namespace ColaFlow.Modules.ProjectManagement.Application.Queries.GetStoriesByEpicId;

/// <summary>
/// Handler for GetStoriesByEpicIdQuery
/// </summary>
public sealed class GetStoriesByEpicIdQueryHandler(IProjectRepository projectRepository)
    : IRequestHandler<GetStoriesByEpicIdQuery, List<StoryDto>>
{
    private readonly IProjectRepository _projectRepository = projectRepository ?? throw new ArgumentNullException(nameof(projectRepository));

    public async Task<List<StoryDto>> Handle(GetStoriesByEpicIdQuery request, CancellationToken cancellationToken)
    {
        // Get the project with epic
        var epicId = EpicId.From(request.EpicId);
        var project = await _projectRepository.GetProjectWithEpicAsync(epicId, cancellationToken);

        if (project == null)
            throw new NotFoundException("Epic", request.EpicId);

        // Find the epic
        var epic = project.Epics.FirstOrDefault(e => e.Id.Value == request.EpicId);
        if (epic == null)
            throw new NotFoundException("Epic", request.EpicId);

        // Map stories to DTOs
        return epic.Stories.Select(story => new StoryDto
        {
            Id = story.Id.Value,
            Title = story.Title,
            Description = story.Description,
            EpicId = story.EpicId.Value,
            Status = story.Status.Name,
            Priority = story.Priority.Name,
            AssigneeId = story.AssigneeId?.Value,
            EstimatedHours = story.EstimatedHours,
            ActualHours = story.ActualHours,
            CreatedBy = story.CreatedBy.Value,
            CreatedAt = story.CreatedAt,
            UpdatedAt = story.UpdatedAt,
            Tasks = story.Tasks.Select(t => new TaskDto
            {
                Id = t.Id.Value,
                Title = t.Title,
                Description = t.Description,
                StoryId = t.StoryId.Value,
                Status = t.Status.Name,
                Priority = t.Priority.Name,
                AssigneeId = t.AssigneeId?.Value,
                EstimatedHours = t.EstimatedHours,
                ActualHours = t.ActualHours,
                CreatedBy = t.CreatedBy.Value,
                CreatedAt = t.CreatedAt,
                UpdatedAt = t.UpdatedAt
            }).ToList()
        }).ToList();
    }
}
