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

namespace Baya.Application.Features.Addresses.Queries.ListMyAddresses;

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

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

        var (page, pageSize) = Pagination.Normalize(request.Page, request.PageSize);

        var customerId = await unitOfWork.CustomerProfileRepository.GetProfileIdByUserIdAsync(userId, cancellationToken);
        if (customerId is not { } cid)
            return OperationResult<PagedResult<CustomerAddressDto>>.SuccessResult(
                new PagedResult<CustomerAddressDto>([], 0, page, pageSize));

        var result = await unitOfWork.CustomerAddressRepository.ListAsync(cid, page, pageSize, cancellationToken);
        return OperationResult<PagedResult<CustomerAddressDto>>.SuccessResult(result);
    }
}
