namespace PkmnLib.Plugin.Gen7.Scripts.Weather;

/// <summary>
/// HarshSunlight is a weather condition that intensifies the effects of sunlight.
///
/// <see href="https://bulbapedia.bulbagarden.net/wiki/Harsh_sunlight">Bulbapedia - Harsh Sunlight</see>
/// </summary>
[Script(ScriptCategory.Weather, "harsh_sunlight")]
public class HarshSunlight : Script, ILimitedTurnsScript, IScriptChangeBasePower, IScriptOnEndTurn,
    IScriptPreventStatusChange, IScriptCustomTrigger, IScriptChangeAccuracy
{
    private int? _duration;

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

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

    /// <inheritdoc />
    public virtual void OnEndTurn(IScriptSource owner, IBattle battle)
    {
        _duration--;
        if (_duration <= 0)
        {
            battle.SetWeather(null, 0);
        }
    }

    /// <inheritdoc />
    public void ChangeBasePower(IExecutingMove move, IPokemon target, byte hit, ref ushort basePower)
    {
        var hitType = move.GetHitData(target, hit).Type;
        if (hitType?.Name == "fire" || move.UseMove.Name == "hydro_steam")
        {
            // Increase Fire-type move power by 50% in harsh sunlight
            basePower = (ushort)(basePower * 1.5);
        }
        else if (hitType?.Name == "water")
        {
            basePower = (ushort)(basePower * 0.5);
        }
    }

    /// <inheritdoc />
    public void CustomTrigger(StringKey eventName, ICustomTriggerArgs args)
    {
        if (eventName != CustomTriggers.BypassChargeMove)
            return;
        if (args is not CustomTriggers.BypassChargeMoveArgs bypassArgs)
            return;
        if (bypassArgs.Move.UseMove.Name == "solar_beam" || bypassArgs.Move.UseMove.Name == "solar_blade")
        {
            bypassArgs.Bypass = true;
        }
    }

    /// <inheritdoc />
    public void PreventStatusChange(IPokemon pokemon, StringKey status, bool selfInflicted, ref bool preventStatus)
    {
        if (status == ScriptUtils.ResolveName<Status.Frozen>())
        {
            preventStatus = true;
        }
    }

    /// <inheritdoc />
    public void ChangeAccuracy(IExecutingMove executingMove, IPokemon target, byte hitIndex, ref int modifiedAccuracy)
    {
        if (executingMove.UseMove.Name == "thunder" || executingMove.UseMove.Name == "hurricane")
        {
            modifiedAccuracy = (int)(modifiedAccuracy * 0.5);
        }
    }
}