namespace PkmnLib.Plugin.Gen7.Scripts.Weather;

[Script(ScriptCategory.Weather, "hail")]
public class Hail : Script, ILimitedTurnsScript, IScriptOnEndTurn, IAIInfoScriptExpectedEndOfTurnDamage
{
    private int? _duration;

    /// <inheritdoc />
    public int TurnsRemaining => _duration ?? 0;

    /// <inheritdoc />
    public void SetTurns(int turns)
    {
        _duration = turns;
    }

    /// <inheritdoc />
    public void OnEndTurn(IScriptSource owner, IBattle battle)
    {
        if (!battle.Library.StaticLibrary.Types.TryGetTypeIdentifier("ice", out var iceType))
        {
            iceType = new TypeIdentifier(255, "non_existent");
        }
        foreach (var side in battle.Sides)
        {
            foreach (var pokemon in side.Pokemon.WhereNotNull())
            {
                if (!pokemon.IsUsable)
                    continue;
                if (pokemon.Types.Contains(iceType))
                    continue;
                var args = new CustomTriggers.IgnoreHailArgs(pokemon);
                pokemon.RunScriptHook<IScriptCustomTrigger>(x => x.CustomTrigger(CustomTriggers.IgnoreHail, args));
                if (args.Ignore)
                    continue;

                var maxHealth = pokemon.BoostedStats.Hp;
                var damage = maxHealth / 16;
                pokemon.Damage(damage, DamageSource.Weather, new EventBatchId());
            }
        }

        _duration--;
        if (_duration <= 0)
        {
            battle.SetWeather(null, 0);
        }
    }

    /// <inheritdoc />
    public void ExpectedEndOfTurnDamage(IPokemon pokemon, ref int damage)
    {
        if (pokemon.Types.Any(x => x.Name == "ice"))
            return; // Ice types are immune to Hail damage.
        if (_duration.HasValue)
        {
            damage += (int)(pokemon.MaxHealth / 16f);
        }
    }
}