using PkmnLib.Dynamic.ScriptHandling;
using PkmnLib.Static.Utils;

namespace PkmnLib.Dynamic.Models;

/// <summary>
/// Random number generator for battles.
/// </summary>
public interface IBattleRandom : IRandom, IDeepCloneable
{
    /// <summary>
    /// Gets whether or not a move triggers its secondary effect. This takes its chance as percent, and
    /// rolls whether it triggers. As a side effect this run scripts to allow modifying this random
    /// chance.
    /// </summary>
    bool EffectChance(float chance, IExecutingMove executingMove, IPokemon target, byte hitNumber);
}

/// <inheritdoc cref="IBattleRandom"/>
public class BattleRandomImpl : RandomImpl, IBattleRandom
{
    /// <inheritdoc cref="BattleRandomImpl"/>
    /// <remarks>
    /// This constructor is used to instantiate the class when no seed is provided. It uses a time-dependent default seed value.
    /// </remarks>
    public BattleRandomImpl()
    {
    }

    /// <inheritdoc cref="BattleRandomImpl"/>
    /// <remarks>
    /// This constructor is used to instantiate the class with a specific seed value.
    /// </remarks>
    public BattleRandomImpl(int seed) : base(seed)
    {
    }

    /// <inheritdoc />
    public bool EffectChance(float chance, IExecutingMove executingMove, IPokemon target, byte hitNumber)
    {
        executingMove.RunScriptHook<IScriptChangeEffectChance>(script =>
            script.ChangeEffectChance(executingMove, target, hitNumber, ref chance));
        target.RunScriptHook<IScriptChangeIncomingEffectChance>(script =>
            script.ChangeIncomingEffectChance(executingMove, target, hitNumber, ref chance));
        if (chance > 100.0)
            return true;
        if (chance < 0.0)
            return false;
        return GetFloat() * 100.0 < chance;
    }
}