#nullable enable
using Baya.Application.Common;
using Baya.Application.Contracts.Common;
using Baya.Application.Contracts.Persistence;
using Baya.Application.Models.Common;
using Mediator;

namespace Baya.Application.Features.Messaging.Commands.ReopenTicket;

/// <summary>Reopens a ticket (participant or staff). Idempotent — an already-open ticket is a no-op success.</summary>
internal sealed class ReopenTicketCommandHandler(
    ICurrentUser currentUser,
    IUnitOfWork unitOfWork)
    : IRequestHandler<ReopenTicketCommand, OperationResult<bool>>
{
    public async ValueTask<OperationResult<bool>> Handle(ReopenTicketCommand request, CancellationToken cancellationToken)
    {
        if (currentUser.UserId is not { } userId)
            return OperationResult<bool>.UnauthorizedResult("Not authenticated.");

        var ticket = await unitOfWork.TicketRepository.GetTrackedAsync(request.TicketId, cancellationToken);
        if (ticket is null)
            return OperationResult<bool>.NotFoundResult("Ticket not found.");

        if (!StaffRoles.IsStaff(currentUser.Roles) &&
            !await unitOfWork.TicketRepository.IsActiveParticipantAsync(request.TicketId, userId, cancellationToken))
            return OperationResult<bool>.ForbiddenResult("You are not a participant on this ticket.");

        if (!ticket.IsOpen)
        {
            ticket.Reopen();
            await unitOfWork.CommitAsync();
        }

        return OperationResult<bool>.SuccessResult(true);
    }
}
