// EN: Command to approve/reject a leave request.
// VI: Command duyet/tu choi yeu cau nghi phep.

using MediatR;
using MerchantService.Domain.AggregatesModel.LeaveRequestAggregate;

namespace MerchantService.API.Application.Commands.LeaveRequests;

public record ApproveLeaveRequestCommand(Guid LeaveRequestId, Guid ApprovedBy) : IRequest<bool>;
public record RejectLeaveRequestCommand(Guid LeaveRequestId, Guid RejectedBy, string? Reason) : IRequest<bool>;

public class ApproveLeaveRequestCommandHandler : IRequestHandler<ApproveLeaveRequestCommand, bool>
{
    private readonly ILeaveRequestRepository _repo;

    public ApproveLeaveRequestCommandHandler(ILeaveRequestRepository repo) => _repo = repo;

    public async Task<bool> Handle(ApproveLeaveRequestCommand request, CancellationToken ct)
    {
        var leaveRequest = await _repo.GetByIdAsync(request.LeaveRequestId, ct);
        if (leaveRequest == null) return false;

        leaveRequest.Approve(request.ApprovedBy);
        _repo.Update(leaveRequest);
        await _repo.UnitOfWork.SaveEntitiesAsync(ct);
        return true;
    }
}

public class RejectLeaveRequestCommandHandler : IRequestHandler<RejectLeaveRequestCommand, bool>
{
    private readonly ILeaveRequestRepository _repo;

    public RejectLeaveRequestCommandHandler(ILeaveRequestRepository repo) => _repo = repo;

    public async Task<bool> Handle(RejectLeaveRequestCommand request, CancellationToken ct)
    {
        var leaveRequest = await _repo.GetByIdAsync(request.LeaveRequestId, ct);
        if (leaveRequest == null) return false;

        leaveRequest.Reject(request.RejectedBy, request.Reason);
        _repo.Update(leaveRequest);
        await _repo.UnitOfWork.SaveEntitiesAsync(ct);
        return true;
    }
}
