using SVSim.Database.Models;
namespace SVSim.Database.Services.BattleXp;
///
/// Amounts returned to callers after a class-XP grant. and
/// are POST-grant, POST-level-up (matching the wire shape's
/// class_experience + class_level post-state semantics).
/// is true iff at least one level threshold was
/// crossed during this grant — callers gate class_level_up mission emits
/// on this flag rather than caching pre-state themselves.
///
public sealed record BattleXpGrantResult(int GetXp, int TotalXp, int Level, bool LeveledUp);
public interface IBattleXpService
{
///
/// Grants class XP for a battle finish. Caller supplies a viewer loaded via
///
/// (or equivalent, with .Include(v => v.Classes).ThenInclude(c => c.Class)).
/// Caller SaveChangesAsync after this returns.
///
/// Amount resolution: mode-specific config override if non-null, else global
/// XpPerWin/XpPerLoss. Story ignores (always
/// treated as a clear).
///
///
/// Level-up: loops on ClassExpEntry curve; row.Exp stores level-relative
/// XP and carries overflow after each level-up. Saturates at curve max level (excess
/// piles in Exp).
///
///
/// Guardrail: viewer has no row for
/// → returns (0, 0, 1), no mutation, logs Warning.
///
///
Task GrantAsync(
Viewer viewer, int classId, bool isWin, BattleXpMode mode, CancellationToken ct = default);
}