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

namespace TakeoutSaaS.Domain.Tenants.Repositories;

/// <summary>
/// 租户发票仓储契约。
/// </summary>
public interface ITenantInvoiceRepository
{
    /// <summary>
    /// 查询租户发票设置。
    /// </summary>
    Task<TenantInvoiceSetting?> GetSettingAsync(long tenantId, CancellationToken cancellationToken = default);

    /// <summary>
    /// 新增发票设置。
    /// </summary>
    Task AddSettingAsync(TenantInvoiceSetting entity, CancellationToken cancellationToken = default);

    /// <summary>
    /// 更新发票设置。
    /// </summary>
    Task UpdateSettingAsync(TenantInvoiceSetting entity, CancellationToken cancellationToken = default);

    /// <summary>
    /// 分页查询发票记录。
    /// </summary>
    Task<(IReadOnlyList<TenantInvoiceRecord> Items, int TotalCount)> SearchRecordsAsync(
        long tenantId,
        DateTime? startUtc,
        DateTime? endUtc,
        TenantInvoiceStatus? status,
        TenantInvoiceType? invoiceType,
        string? keyword,
        int page,
        int pageSize,
        CancellationToken cancellationToken = default);

    /// <summary>
    /// 获取发票页统计。
    /// </summary>
    Task<TenantInvoiceRecordStatsSnapshot> GetStatsAsync(
        long tenantId,
        DateTime nowUtc,
        CancellationToken cancellationToken = default);

    /// <summary>
    /// 根据标识查询发票记录。
    /// </summary>
    Task<TenantInvoiceRecord?> FindRecordByIdAsync(
        long tenantId,
        long recordId,
        CancellationToken cancellationToken = default);

    /// <summary>
    /// 判断租户下发票号码是否已存在。
    /// </summary>
    Task<bool> ExistsInvoiceNoAsync(
        long tenantId,
        string invoiceNo,
        CancellationToken cancellationToken = default);

    /// <summary>
    /// 新增发票记录。
    /// </summary>
    Task AddRecordAsync(TenantInvoiceRecord entity, CancellationToken cancellationToken = default);

    /// <summary>
    /// 更新发票记录。
    /// </summary>
    Task UpdateRecordAsync(TenantInvoiceRecord entity, CancellationToken cancellationToken = default);

    /// <summary>
    /// 持久化变更。
    /// </summary>
    Task SaveChangesAsync(CancellationToken cancellationToken = default);
}

/// <summary>
/// 发票页面统计快照。
/// </summary>
public sealed record TenantInvoiceRecordStatsSnapshot
{
    /// <summary>
    /// 本月已开票金额。
    /// </summary>
    public decimal CurrentMonthIssuedAmount { get; init; }

    /// <summary>
    /// 本月已开票张数。
    /// </summary>
    public int CurrentMonthIssuedCount { get; init; }

    /// <summary>
    /// 待开票张数。
    /// </summary>
    public int PendingCount { get; init; }

    /// <summary>
    /// 已作废张数。
    /// </summary>
    public int VoidedCount { get; init; }
}
