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

namespace TakeoutSaaS.Domain.Tenants.Repositories;

/// <summary>
/// 租户套餐仓储（AdminApi 使用）。
/// </summary>
public interface ITenantPackageRepository
{
    /// <summary>
    /// 根据 ID 获取租户套餐。
    /// </summary>
    /// <param name="tenantPackageId">套餐 ID。</param>
    /// <param name="cancellationToken">取消标记。</param>
    /// <returns>套餐实体，不存在则返回 null。</returns>
    Task<TenantPackage?> GetByIdAsync(long tenantPackageId, CancellationToken cancellationToken = default);

    /// <summary>
    /// 根据 ID 获取租户套餐（用于更新，带跟踪）。
    /// </summary>
    /// <param name="tenantPackageId">套餐 ID。</param>
    /// <param name="cancellationToken">取消标记。</param>
    /// <returns>套餐实体，不存在则返回 null。</returns>
    Task<TenantPackage?> GetByIdForUpdateAsync(long tenantPackageId, CancellationToken cancellationToken = default);

    /// <summary>
    /// 获取租户套餐列表（分页）。
    /// </summary>
    /// <param name="keyword">关键字（套餐名称）。</param>
    /// <param name="isActive">是否启用。</param>
    /// <param name="page">页码（从 1 开始）。</param>
    /// <param name="pageSize">每页条数。</param>
    /// <param name="cancellationToken">取消标记。</param>
    /// <returns>套餐列表和总数。</returns>
    Task<(IReadOnlyList<TenantPackage> Items, int TotalCount)> GetListAsync(
        string? keyword,
        bool? isActive,
        int page,
        int pageSize,
        CancellationToken cancellationToken = default);

    /// <summary>
    /// 获取套餐使用统计。
    /// </summary>
    /// <param name="tenantPackageIds">套餐 ID 列表。</param>
    /// <param name="cancellationToken">取消标记。</param>
    /// <returns>套餐使用统计列表。</returns>
    Task<IReadOnlyList<TenantPackageUsageResult>> GetUsagesAsync(
        IReadOnlyList<long> tenantPackageIds,
        CancellationToken cancellationToken = default);

    /// <summary>
    /// 新增租户套餐。
    /// </summary>
    /// <param name="package">套餐实体。</param>
    /// <param name="cancellationToken">取消标记。</param>
    /// <returns>异步操作任务。</returns>
    Task AddAsync(TenantPackage package, CancellationToken cancellationToken = default);

    /// <summary>
    /// 软删除租户套餐。
    /// </summary>
    /// <param name="package">套餐实体。</param>
    /// <param name="cancellationToken">取消标记。</param>
    /// <returns>异步操作任务。</returns>
    Task SoftDeleteAsync(TenantPackage package, CancellationToken cancellationToken = default);

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

    /// <summary>
    /// 获取套餐当前使用租户列表（按有效订阅口径）。
    /// </summary>
    /// <param name="tenantPackageId">套餐 ID。</param>
    /// <param name="keyword">关键字（租户名称或编码）。</param>
    /// <param name="expiringWithinDays">即将到期天数筛选。</param>
    /// <param name="page">页码（从 1 开始）。</param>
    /// <param name="pageSize">每页条数。</param>
    /// <param name="cancellationToken">取消标记。</param>
    /// <returns>租户列表和总数。</returns>
    Task<(IReadOnlyList<TenantPackageTenantResult> Items, int TotalCount)> GetTenantsAsync(
        long tenantPackageId,
        string? keyword,
        int? expiringWithinDays,
        int page,
        int pageSize,
        CancellationToken cancellationToken = default);
}

/// <summary>
/// 套餐使用统计结果。
/// </summary>
public sealed record TenantPackageUsageResult(
    long TenantPackageId,
    int ActiveSubscriptionCount,
    int ActiveTenantCount,
    int TotalSubscriptionCount,
    decimal Mrr,
    decimal Arr,
    int ExpiringTenantCount7Days,
    int ExpiringTenantCount15Days,
    int ExpiringTenantCount30Days);

/// <summary>
/// 套餐使用租户结果。
/// </summary>
public sealed record TenantPackageTenantResult(
    long TenantId,
    string Code,
    string Name,
    TenantStatus Status,
    string? ContactName,
    string? ContactPhone,
    DateTime SubscriptionEffectiveFrom,
    DateTime SubscriptionEffectiveTo);
