using Wizard.BattleMgr;

namespace SVSim.BattleEngine.Rng
{
    // The headless authoritative single-battle mgr. Overrides the three BattleManagerBase RNG methods
    // (now virtual per the Task-4 DP5 patch) to delegate to an injected IRandomSource instead of the
    // IsForecast-gated System.Random fields. This is the F2 decoupling: VFX stays suppressed
    // (IsForecast == true) while RNG rolls real. The skill RNG path calls BattleManagerBase.GetIns()
    // .StableRandom*, and the base ctor registers `this` as the singleton, so constructing the battle as
    // HeadlessBattleMgr makes every roll dispatch (virtually) to these overrides.
    //
    // randomResult is set inside the overrides (it has a protected setter, reachable only from a
    // subclass — NOT from RandomSourceBridge); it is read by the Phase-2 NetworkSkill_cost_change emit
    // path, so the overrides keep it faithful. The arithmetic itself lives in RandomSourceBridge so it
    // stays unit-testable and reusable by a future NetworkBattleManagerBase-derived mgr.
    public sealed class HeadlessBattleMgr : SingleBattleMgr
    {
        private readonly IRandomSource _rng;

        public HeadlessBattleMgr(IBattleMgrContentsCreator contentsCreator, IRandomSource rng = null)
            : base(contentsCreator)
        {
            _rng = rng ?? new SeededRandomSource(contentsCreator.RandomSeed);
        }

        // KNOWN DIVERGENCE: the base StableRandom/StableRandomDouble also bump a private
        // `stableRandomCount` diagnostic field; these overrides cannot (it's private to the base) and do
        // not. The field is currently unread anywhere in the engine, so this is harmless; if a future
        // replay/audit path starts reading the count, promote it via a protected accessor (another DP5
        // patch) rather than leaving it silently zero.
        public override int StableRandom(int val)
        {
            double unit = _rng.NextUnit();
            randomResult = unit;
            return RandomSourceBridge.Range(val, unit);
        }

        public override double StableRandomDouble()
        {
            double unit = _rng.NextUnit();
            randomResult = unit;
            return unit;
        }

        public override int StableRandomOnlySelf(int val) => _rng.NextSelf(val);
    }
}
