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

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

/// <summary>
/// Handler for GetEpicsByProjectIdQuery
/// </summary>
public sealed class GetEpicsByProjectIdQueryHandler(
    IProjectRepository projectRepository,
    ITenantContext tenantContext)
    : IRequestHandler<GetEpicsByProjectIdQuery, List<EpicDto>>
{
    private readonly IProjectRepository _projectRepository = projectRepository ?? throw new ArgumentNullException(nameof(projectRepository));
    private readonly ITenantContext _tenantContext = tenantContext ?? throw new ArgumentNullException(nameof(tenantContext));

    public async Task<List<EpicDto>> Handle(GetEpicsByProjectIdQuery request, CancellationToken cancellationToken)
    {
        // Get current tenant ID (Defense in Depth - Layer 2)
        var currentTenantId = _tenantContext.GetCurrentTenantId();

        // CRITICAL SECURITY: Verify Project belongs to current tenant before querying epics
        var projectId = ProjectId.From(request.ProjectId);
        var project = await _projectRepository.GetByIdAsync(projectId, cancellationToken);

        if (project == null)
            throw new NotFoundException("Project", request.ProjectId);

        // Explicit TenantId validation (Defense in Depth)
        if (project.TenantId.Value != currentTenantId)
            throw new NotFoundException("Project", request.ProjectId);

        // Now fetch epics (already filtered by EF Core, but we verified project ownership)
        var epics = await _projectRepository.GetEpicsByProjectIdAsync(projectId, cancellationToken);

        return epics.Select(epic => new EpicDto
        {
            Id = epic.Id.Value,
            Name = epic.Name,
            Description = epic.Description,
            ProjectId = epic.ProjectId.Value,
            Status = epic.Status.Name,
            Priority = epic.Priority.Name,
            CreatedBy = epic.CreatedBy.Value,
            CreatedAt = epic.CreatedAt,
            UpdatedAt = epic.UpdatedAt,
            Stories = new List<StoryDto>() // Don't include stories in list view
        }).ToList();
    }
}
