namespace PkmnLib.Plugin.Gen7.Scripts.Abilities;

/// <summary>
/// SpeedModifierInWeather is a generic ability that modifies the user's speed in a specific weather condition.
/// This ability is used by abilities like Swift Swim, Chlorophyll, and Sand Rush.
///
/// <see href="https://bulbapedia.bulbagarden.net/wiki/Swift_Swim_(Ability)">Bulbapedia - Swift Swim</see>
/// <see href="https://bulbapedia.bulbagarden.net/wiki/Chlorophyll_(Ability)">Bulbapedia - Chlorophyll</see>
/// <see href="https://bulbapedia.bulbagarden.net/wiki/Sand_Rush_(Ability)">Bulbapedia - Sand Rush</see>
/// </summary>
[Script(ScriptCategory.Ability, "speed_modifier_in_weather")]
public class SpeedModifierInWeather : Script, IScriptOnInitialize, IScriptChangeSpeed
{
    private StringKey _weather;
    private float _modifier;

    /// <inheritdoc />
    public void OnInitialize(IReadOnlyDictionary<StringKey, object?>? parameters)
    {
        if (parameters is null)
            throw new ArgumentNullException(nameof(parameters));

        if (!parameters.TryGetValue("weather", out var weatherObj) || weatherObj is not string weatherStr)
            throw new ArgumentException("Parameter 'weather' is required and must be a string.", nameof(parameters));
        if (!parameters.TryGetValue("modifier", out var modifierObj))
            throw new ArgumentException("Parameter 'modifier' is required", nameof(parameters));
        if (modifierObj is not float && modifierObj is not int)
            throw new ArgumentException("Parameter 'modifier' must be a float or int.", nameof(parameters));
        var weatherModifier = modifierObj is float modFloat ? modFloat : (int)modifierObj;

        _weather = weatherStr;
        _modifier = weatherModifier;
    }

    /// <inheritdoc />
    public void ChangeSpeed(ITurnChoice choice, ref uint speed)
    {
        var battle = choice.User.BattleData?.Battle;
        if (battle is null)
            return;
        var weather = battle.WeatherName;
        if (weather == _weather)
        {
            speed = speed.MultiplyOrMax(_modifier);
        }
    }
}