using SVSim.Database.Enums;
using SVSim.Database.Models;
namespace SVSim.Database.Services;
///
/// The single read/ownership authority for what a viewer is *treated as* owning. Knows the
/// Freeplay flag; all freeplay read-side behavior lives here. See
/// docs/superpowers/specs/2026-05-29-freeplay-mode-design.md.
///
///
/// Include precondition: methods that inspect the viewer's collections require the
/// viewer to have been loaded with .Include(v => v.Cards).ThenInclude(c => c.Card)
/// and the cosmetic collections
/// (Sleeves, Emblems, Degrees, LeaderSkins, MyPageBackgrounds)
/// included. Without those includes the EF owned-collection nav refs are null or zero-filled
/// (see the EF owned-collection nav-include pitfall in MEMORY.md).
///
public interface IViewerEntitlements
{
/// True when the global Freeplay config section is enabled.
bool IsFreeplay { get; }
///
/// The balance the viewer is treated as having: the configured freeplay amount for
/// Crystal/Rupee/RedEther when freeplay is on, otherwise (and always for SpotPoint) the real
/// viewer.Currency field.
///
long EffectiveBalance(Viewer viewer, SpendCurrency currency);
bool OwnsCard(Viewer viewer, long cardId);
/// uses (Skin == leader skin).
bool OwnsCosmetic(Viewer viewer, CosmeticType type, int id);
/// The full owned-card projection for /load/index's user_card_list.
Task> EffectiveOwnedCardsAsync(Viewer viewer, CancellationToken ct = default);
/// The cosmetic id-lists + leader-skin catalog/owned-set for /load/index.
Task EffectiveCosmeticsAsync(Viewer viewer, CancellationToken ct = default);
}
///
/// Cosmetic projection bundle for /load/index. The four id-lists are "what the viewer owns"
/// (all of them in freeplay). Leader skins are always the full catalog with a per-skin owned flag;
/// is every skin id in freeplay.
///
public sealed record EffectiveCosmetics(
IReadOnlyList SleeveIds,
IReadOnlyList EmblemIds,
IReadOnlyList DegreeIds,
IReadOnlyList MyPageBackgroundIds,
IReadOnlyList AllLeaderSkins,
IReadOnlySet OwnedLeaderSkinIds);