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.DeleteIssue;

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

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

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

        issue.Delete();

        // Publish delete event before actual deletion
        foreach (var domainEvent in issue.DomainEvents)
        {
            await _publisher.Publish(domainEvent, cancellationToken);
        }
        issue.ClearDomainEvents();

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

        return Unit.Value;
    }
}
