namespace Meezi.Core.Interfaces; public record KavenegarAccountInfo(long RemainCredit, string AccountType); public record BulkSendResult(int SentCount, int FailedCount); public interface ISmsService { /// Send a one-time password via Kavenegar Verify/Lookup template. Task SendOtpAsync(string phone, string otp, CancellationToken cancellationToken = default); /// Send a plain-text message to a single recipient. Task SendMessageAsync(string phone, string message, CancellationToken cancellationToken = default); /// /// Send the same message to many recipients in batches of up to 200. /// Never throws — failures per batch are counted and returned. /// Task SendBulkAsync(IReadOnlyList phones, string message, CancellationToken cancellationToken = default); /// Returns credit balance from the Kavenegar account, or null if not configured. Task GetAccountInfoAsync(CancellationToken cancellationToken = default); /// /// Bulk send using the CALLER's own provider credentials — marketing SMS is /// bring-your-own-provider (each café configures its own API key + sender line). /// Never throws — failures per batch are counted and returned. /// Task SendBulkWithCredentialsAsync( string apiKey, string senderNumber, IReadOnlyList phones, string message, CancellationToken cancellationToken = default); /// Credit balance for an EXPLICIT API key (a café's own account), or null on failure. Task GetAccountInfoAsync(string apiKey, CancellationToken cancellationToken = default); }