using TakeoutSaaS.Domain.Membership.Entities;
using TakeoutSaaS.Domain.Membership.Enums;

namespace TakeoutSaaS.Domain.Membership.Repositories;

/// <summary>
/// 会员积分商城仓储契约。
/// </summary>
public interface IPointMallRepository
{
    /// <summary>
    /// 查询门店积分规则。
    /// </summary>
    Task<MemberPointMallRule?> GetRuleByStoreAsync(
        long tenantId,
        long storeId,
        CancellationToken cancellationToken = default);

    /// <summary>
    /// 新增积分规则。
    /// </summary>
    Task AddRuleAsync(MemberPointMallRule entity, CancellationToken cancellationToken = default);

    /// <summary>
    /// 更新积分规则。
    /// </summary>
    Task UpdateRuleAsync(MemberPointMallRule entity, CancellationToken cancellationToken = default);

    /// <summary>
    /// 查询兑换商品列表。
    /// </summary>
    Task<IReadOnlyList<MemberPointMallProduct>> SearchProductsAsync(
        long tenantId,
        long storeId,
        MemberPointMallProductStatus? status,
        string? keyword,
        CancellationToken cancellationToken = default);

    /// <summary>
    /// 按标识查询兑换商品（追踪）。
    /// </summary>
    Task<MemberPointMallProduct?> FindProductByIdAsync(
        long tenantId,
        long storeId,
        long productId,
        CancellationToken cancellationToken = default);

    /// <summary>
    /// 按标识查询兑换商品（只读）。
    /// </summary>
    Task<MemberPointMallProduct?> GetProductByIdAsync(
        long tenantId,
        long storeId,
        long productId,
        CancellationToken cancellationToken = default);

    /// <summary>
    /// 新增兑换商品。
    /// </summary>
    Task AddProductAsync(MemberPointMallProduct entity, CancellationToken cancellationToken = default);

    /// <summary>
    /// 更新兑换商品。
    /// </summary>
    Task UpdateProductAsync(MemberPointMallProduct entity, CancellationToken cancellationToken = default);

    /// <summary>
    /// 删除兑换商品。
    /// </summary>
    Task DeleteProductAsync(MemberPointMallProduct entity, CancellationToken cancellationToken = default);

    /// <summary>
    /// 查询商品是否已有兑换记录。
    /// </summary>
    Task<bool> HasRecordsByProductIdAsync(
        long tenantId,
        long storeId,
        long pointMallProductId,
        CancellationToken cancellationToken = default);

    /// <summary>
    /// 统计会员在某商品上的有效兑换次数（排除已取消）。
    /// </summary>
    Task<int> CountMemberRedeemsByProductAsync(
        long tenantId,
        long storeId,
        long pointMallProductId,
        long memberId,
        CancellationToken cancellationToken = default);

    /// <summary>
    /// 查询兑换记录分页。
    /// </summary>
    Task<(IReadOnlyList<MemberPointMallRecord> Items, int TotalCount)> SearchRecordsAsync(
        long tenantId,
        long storeId,
        MemberPointMallRedeemType? redeemType,
        MemberPointMallRecordStatus? status,
        DateTime? startUtc,
        DateTime? endUtc,
        string? keyword,
        int page,
        int pageSize,
        CancellationToken cancellationToken = default);

    /// <summary>
    /// 查询兑换记录详情。
    /// </summary>
    Task<MemberPointMallRecord?> GetRecordByIdAsync(
        long tenantId,
        long storeId,
        long recordId,
        CancellationToken cancellationToken = default);

    /// <summary>
    /// 查询兑换记录（追踪）。
    /// </summary>
    Task<MemberPointMallRecord?> FindRecordByIdAsync(
        long tenantId,
        long storeId,
        long recordId,
        CancellationToken cancellationToken = default);

    /// <summary>
    /// 查询兑换记录导出数据。
    /// </summary>
    Task<IReadOnlyList<MemberPointMallRecord>> ListRecordsForExportAsync(
        long tenantId,
        long storeId,
        MemberPointMallRedeemType? redeemType,
        MemberPointMallRecordStatus? status,
        DateTime? startUtc,
        DateTime? endUtc,
        string? keyword,
        CancellationToken cancellationToken = default);

    /// <summary>
    /// 新增兑换记录。
    /// </summary>
    Task AddRecordAsync(MemberPointMallRecord entity, CancellationToken cancellationToken = default);

    /// <summary>
    /// 更新兑换记录。
    /// </summary>
    Task UpdateRecordAsync(MemberPointMallRecord entity, CancellationToken cancellationToken = default);

    /// <summary>
    /// 新增积分流水。
    /// </summary>
    Task AddPointLedgerAsync(MemberPointLedger entity, CancellationToken cancellationToken = default);

    /// <summary>
    /// 查询规则页统计。
    /// </summary>
    Task<MemberPointMallRuleStatsSnapshot> GetRuleStatsAsync(
        long tenantId,
        long storeId,
        CancellationToken cancellationToken = default);

    /// <summary>
    /// 查询记录页统计。
    /// </summary>
    Task<MemberPointMallRecordStatsSnapshot> GetRecordStatsAsync(
        long tenantId,
        long storeId,
        DateTime nowUtc,
        CancellationToken cancellationToken = default);

    /// <summary>
    /// 查询商品聚合统计快照。
    /// </summary>
    Task<Dictionary<long, MemberPointMallProductAggregateSnapshot>> GetProductAggregatesAsync(
        long tenantId,
        long storeId,
        IReadOnlyCollection<long> pointMallProductIds,
        CancellationToken cancellationToken = default);

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

/// <summary>
/// 积分商城规则页统计快照。
/// </summary>
public sealed record MemberPointMallRuleStatsSnapshot
{
    /// <summary>
    /// 累计发放积分。
    /// </summary>
    public int TotalIssuedPoints { get; init; }

    /// <summary>
    /// 已兑换积分。
    /// </summary>
    public int RedeemedPoints { get; init; }

    /// <summary>
    /// 积分用户数。
    /// </summary>
    public int PointMembers { get; init; }

    /// <summary>
    /// 兑换率（0-100）。
    /// </summary>
    public decimal RedeemRate { get; init; }
}

/// <summary>
/// 积分商城记录页统计快照。
/// </summary>
public sealed record MemberPointMallRecordStatsSnapshot
{
    /// <summary>
    /// 今日兑换数量。
    /// </summary>
    public int TodayRedeemCount { get; init; }

    /// <summary>
    /// 待领取实物数量。
    /// </summary>
    public int PendingPhysicalCount { get; init; }

    /// <summary>
    /// 本月消耗积分。
    /// </summary>
    public int CurrentMonthUsedPoints { get; init; }
}

/// <summary>
/// 积分商城商品聚合快照。
/// </summary>
public sealed record MemberPointMallProductAggregateSnapshot
{
    /// <summary>
    /// 商品标识。
    /// </summary>
    public required long PointMallProductId { get; init; }

    /// <summary>
    /// 已兑换数量。
    /// </summary>
    public int RedeemedCount { get; init; }
}
