using TakeoutSaaS.Domain.Tenants.Entities;
using TakeoutSaaS.Domain.Tenants.Enums;

namespace TakeoutSaaS.Domain.Tenants.Repositories;

/// <summary>
/// 租户账单仓储。
/// </summary>
public interface ITenantBillingRepository
{
    /// <summary>
    /// 查询账单列表，按状态与时间范围筛选。
    /// </summary>
    /// <param name="tenantId">租户 ID。</param>
    /// <param name="status">账单状态。</param>
    /// <param name="from">开始时间（UTC）。</param>
    /// <param name="to">结束时间（UTC）。</param>
    /// <param name="cancellationToken">取消标记。</param>
    /// <returns>账单集合。</returns>
    Task<IReadOnlyList<TenantBillingStatement>> SearchAsync(
        long tenantId,
        TenantBillingStatus? status,
        DateTime? from,
        DateTime? to,
        CancellationToken cancellationToken = default);

    /// <summary>
    /// 按 ID 获取账单。
    /// </summary>
    /// <param name="tenantId">租户 ID。</param>
    /// <param name="billingId">账单 ID。</param>
    /// <param name="cancellationToken">取消标记。</param>
    /// <returns>账单实体或 null。</returns>
    Task<TenantBillingStatement?> FindByIdAsync(long tenantId, long billingId, CancellationToken cancellationToken = default);

    /// <summary>
    /// 按账单编号获取账单。
    /// </summary>
    /// <param name="tenantId">租户 ID。</param>
    /// <param name="statementNo">账单编号。</param>
    /// <param name="cancellationToken">取消标记。</param>
    /// <returns>账单实体或 null。</returns>
    Task<TenantBillingStatement?> FindByStatementNoAsync(long tenantId, string statementNo, CancellationToken cancellationToken = default);

    /// <summary>
    /// 新增账单。
    /// </summary>
    /// <param name="bill">账单实体。</param>
    /// <param name="cancellationToken">取消标记。</param>
    /// <returns>异步任务。</returns>
    Task AddAsync(TenantBillingStatement bill, CancellationToken cancellationToken = default);

    /// <summary>
    /// 更新账单。
    /// </summary>
    /// <param name="bill">账单实体。</param>
    /// <param name="cancellationToken">取消标记。</param>
    /// <returns>异步任务。</returns>
    Task UpdateAsync(TenantBillingStatement bill, CancellationToken cancellationToken = default);

    /// <summary>
    /// 保存变更。
    /// </summary>
    /// <param name="cancellationToken">取消标记。</param>
    /// <returns>异步任务。</returns>
    Task SaveChangesAsync(CancellationToken cancellationToken = default);
}
