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.Commands.UpdateProject;

/// <summary>
/// Handler for UpdateProjectCommand
/// </summary>
public sealed class UpdateProjectCommandHandler(
    IProjectRepository projectRepository,
    IUnitOfWork unitOfWork)
    : IRequestHandler<UpdateProjectCommand, ProjectDto>
{
    private readonly IProjectRepository _projectRepository = projectRepository ?? throw new ArgumentNullException(nameof(projectRepository));
    private readonly IUnitOfWork _unitOfWork = unitOfWork ?? throw new ArgumentNullException(nameof(unitOfWork));

    public async Task<ProjectDto> Handle(UpdateProjectCommand request, CancellationToken cancellationToken)
    {
        // Get project (will be filtered by tenant automatically)
        var project = await _projectRepository.GetByIdAsync(ProjectId.From(request.ProjectId), cancellationToken);
        if (project == null)
        {
            throw new NotFoundException($"Project with ID '{request.ProjectId}' not found");
        }

        // Update project details
        project.UpdateDetails(request.Name, request.Description);

        // Save changes
        _projectRepository.Update(project);
        await _unitOfWork.SaveChangesAsync(cancellationToken);

        // Return DTO
        return new ProjectDto
        {
            Id = project.Id.Value,
            Name = project.Name,
            Description = project.Description,
            Key = project.Key.Value,
            Status = project.Status.Name,
            OwnerId = project.OwnerId.Value,
            CreatedAt = project.CreatedAt,
            UpdatedAt = project.UpdatedAt,
            Epics = new List<EpicDto>()
        };
    }
}
