#nullable enable
using Baya.Application.Models.Addresses;
using Baya.Application.Models.Common;
using Baya.Domain.Entities.Identity;

namespace Baya.Application.Contracts.Persistence;

public interface ICustomerAddressRepository
{
    Task AddAsync(CustomerAddress address, CancellationToken cancellationToken);

    /// <summary>Tracked, tenancy-scoped lookup — returns the address only if it belongs to
    /// <paramref name="customerId"/>, else null.</summary>
    Task<CustomerAddress?> GetOwnedAsync(long id, long customerId, CancellationToken cancellationToken);

    /// <summary>Whether the customer already has at least one address (the first becomes primary).</summary>
    Task<bool> HasAnyAsync(long customerId, CancellationToken cancellationToken);

    /// <summary>Clears the current primary (if any) other than <paramref name="addressId"/> for the
    /// customer, in a single transaction, so the filtered <c>UNIQUE(customer_id) WHERE is_primary=1</c>
    /// index never trips. The caller has already verified tenancy and set the new primary.</summary>
    Task ClearOtherPrimaryAsync(long customerId, long addressId, CancellationToken cancellationToken);

    /// <summary>Atomically makes <paramref name="addressId"/> primary and clears the prior primary
    /// (clear-then-set order). The address must already be owned by the customer.</summary>
    Task SetPrimaryAsync(long customerId, long addressId, CancellationToken cancellationToken);

    /// <summary>No-tracking, paginated projection of the customer's own addresses (primary first), with the
    /// PII decrypted for the owner.</summary>
    Task<PagedResult<CustomerAddressDto>> ListAsync(long customerId, int page, int pageSize, CancellationToken cancellationToken);
}
