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

namespace Baya.Application.Features.Addresses.Commands.SetPrimaryAddress;

internal sealed class SetPrimaryAddressCommandHandler(ICurrentUser currentUser, IUnitOfWork unitOfWork)
    : IRequestHandler<SetPrimaryAddressCommand, OperationResult<bool>>
{
    public async ValueTask<OperationResult<bool>> Handle(SetPrimaryAddressCommand request, CancellationToken cancellationToken)
    {
        if (currentUser.UserId is not { } userId)
            return OperationResult<bool>.UnauthorizedResult("Not authenticated.");

        if (currentUser.Roles?.Contains(RoleNames.Customer) != true)
            return OperationResult<bool>.ForbiddenResult("Only a customer can manage addresses.");

        var customerId = await unitOfWork.CustomerProfileRepository.GetProfileIdByUserIdAsync(userId, cancellationToken);
        if (customerId is not { } cid)
            return OperationResult<bool>.NotFoundResult("Address not found.");

        var address = await unitOfWork.CustomerAddressRepository.GetOwnedAsync(request.Id, cid, cancellationToken);
        if (address is null)
            return OperationResult<bool>.NotFoundResult("Address not found.");

        if (!address.IsPrimary)
            await unitOfWork.CustomerAddressRepository.SetPrimaryAsync(cid, request.Id, cancellationToken);

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