namespace PkmnLib.Plugin.Gen7.Scripts.Abilities;

/// <summary>
/// Dry Skin is an ability that makes the Pokémon take more damage from Fire-type moves,
/// heal from Water-type moves, heal in rain, and take damage in harsh sunlight.
/// This ability is commonly associated with Paras and Toxicroak.
///
/// <see href="https://bulbapedia.bulbagarden.net/wiki/Dry_Skin_(Ability)">Bulbapedia - Dry Skin</see>
/// </summary>
[Script(ScriptCategory.Ability, "dry_skin")]
public class DrySkin : Script, IScriptChangeDamageModifier, IScriptOnEndTurn, IAIInfoScriptExpectedEndOfTurnDamage
{
    private IPokemon? _owningPokemon;

    /// <inheritdoc />
    public override void OnAddedToParent(IScriptSource source)
    {
        if (source is not IPokemon pokemon)
        {
            throw new ArgumentException("DrySkin script must be added to a Pokemon.", nameof(source));
        }
        _owningPokemon = pokemon;
    }

    /// <inheritdoc />
    public void ChangeDamageModifier(IExecutingMove move, IPokemon target, byte hit, ref float modifier)
    {
        var hitType = move.GetHitData(target, hit).Type;
        if (hitType?.Name == "fire")
        {
            modifier *= 1.25f;
        }
        else if (hitType?.Name == "water")
        {
            modifier = 0;
            target.BattleData?.Battle.EventHook.Invoke(new AbilityTriggerEvent(target));
            target.Heal(target.MaxHealth / 4);
        }
    }

    /// <inheritdoc />
    public void OnEndTurn(IScriptSource owner, IBattle battle)
    {
        if (_owningPokemon == null)
            return;
        var weather = battle.WeatherName;
        if (weather == ScriptUtils.ResolveName<Weather.Rain>())
        {
            _owningPokemon.BattleData?.Battle.EventHook.Invoke(new AbilityTriggerEvent(_owningPokemon));
            _owningPokemon.Heal(_owningPokemon.MaxHealth / 8);
        }
        else if (weather == ScriptUtils.ResolveName<Weather.HarshSunlight>())
        {
            _owningPokemon.BattleData?.Battle.EventHook.Invoke(new AbilityTriggerEvent(_owningPokemon));
            _owningPokemon.Damage(_owningPokemon.MaxHealth / 8, DamageSource.Weather);
        }
    }

    /// <inheritdoc />
    public void ExpectedEndOfTurnDamage(IPokemon pokemon, ref int damage)
    {
        if (pokemon.BattleData?.Battle.WeatherName == ScriptUtils.ResolveName<Weather.HarshSunlight>())
        {
            damage += (int)(pokemon.MaxHealth / 8f);
        }
    }
}