using MediatR;
using ColaFlow.Modules.IssueManagement.Domain.Entities;
using ColaFlow.Modules.IssueManagement.Domain.Repositories;
using ColaFlow.Modules.IssueManagement.Domain.Exceptions;

namespace ColaFlow.Modules.IssueManagement.Application.Commands.UpdateIssue;

public sealed class UpdateIssueCommandHandler : IRequestHandler<UpdateIssueCommand, Unit>
{
    private readonly IIssueRepository _issueRepository;
    private readonly IUnitOfWork _unitOfWork;
    private readonly IPublisher _publisher;

    public UpdateIssueCommandHandler(
        IIssueRepository issueRepository,
        IUnitOfWork unitOfWork,
        IPublisher publisher)
    {
        _issueRepository = issueRepository;
        _unitOfWork = unitOfWork;
        _publisher = publisher;
    }

    public async Task<Unit> Handle(UpdateIssueCommand request, CancellationToken cancellationToken)
    {
        var issue = await _issueRepository.GetByIdAsync(request.IssueId, cancellationToken);
        if (issue == null)
            throw new NotFoundException(nameof(Issue), request.IssueId);

        issue.Update(request.Title, request.Description, request.Priority);

        await _issueRepository.UpdateAsync(issue, cancellationToken);
        await _unitOfWork.SaveChangesAsync(cancellationToken);

        foreach (var domainEvent in issue.DomainEvents)
        {
            await _publisher.Publish(domainEvent, cancellationToken);
        }
        issue.ClearDomainEvents();

        return Unit.Value;
    }
}
