using ColaFlow.Modules.Identity.Domain.Aggregates.Invitations;
using ColaFlow.Modules.Identity.Domain.Aggregates.Tenants;
using ColaFlow.Modules.Identity.Domain.Repositories;
using MediatR;
using Microsoft.Extensions.Logging;

namespace ColaFlow.Modules.Identity.Application.Commands.CancelInvitation;

public class CancelInvitationCommandHandler : IRequestHandler<CancelInvitationCommand, Unit>
{
    private readonly IInvitationRepository _invitationRepository;
    private readonly ILogger<CancelInvitationCommandHandler> _logger;

    public CancelInvitationCommandHandler(
        IInvitationRepository invitationRepository,
        ILogger<CancelInvitationCommandHandler> logger)
    {
        _invitationRepository = invitationRepository;
        _logger = logger;
    }

    public async Task<Unit> Handle(CancelInvitationCommand request, CancellationToken cancellationToken)
    {
        var invitationId = InvitationId.Create(request.InvitationId);
        var tenantId = TenantId.Create(request.TenantId);

        // Get the invitation
        var invitation = await _invitationRepository.GetByIdAsync(invitationId, cancellationToken);
        if (invitation == null)
            throw new InvalidOperationException($"Invitation {request.InvitationId} not found");

        // Verify invitation belongs to the tenant (security check)
        if (invitation.TenantId != tenantId)
            throw new InvalidOperationException("Invitation does not belong to this tenant");

        // Cancel the invitation
        invitation.Cancel();
        await _invitationRepository.UpdateAsync(invitation, cancellationToken);

        _logger.LogInformation(
            "Invitation {InvitationId} cancelled by user {CancelledBy} in tenant {TenantId}",
            request.InvitationId,
            request.CancelledBy,
            request.TenantId);

        return Unit.Value;
    }
}
