AI/ActionSystem/BehaviorTree/Nodes/UseBuildingNode.cs
namespace HC3;

/// <summary>
/// A node that handles using a building for a guest.
/// </summary>
public class UseBuildingNode : Node
{
	private readonly Building _building;
	private readonly Guest _guest;
	private readonly NeedSystem _needs;

	private bool _started;
	private TimeUntil _timer;
	private float _duration;

	public UseBuildingNode( Building building, Guest guest, NeedSystem needs )
	{
		_building = building;
		_guest = guest;
		_needs = needs;
	}

	public override Status Tick()
	{
		if ( !_building.IsValid() || !_guest.IsValid() )
			return Status.Failure;

		if ( !_started )
		{
			if ( !_building.LoadIn( _guest ) )
				return Status.Failure;

			_duration = _building is BasicRide ride
				? ride.RideLength
				: Game.Random.Float( 2f, 6f );

			_timer = _duration;
			_started = true;

			if ( _building.GuestCost > 0 )
			{
				_guest.TakeMoney( _building.GuestCost );
				_needs.Happiness += 0.25f;

				ParkManager.Instance?.GiveMoney( _building.GuestCost, _building is BasicRide ? "Rides" : "Buildings" );

				var effectPos = _guest.WorldPosition + Vector3.Random * 10f + Vector3.Up * 50f;
				MoneyEffect.Broadcast( effectPos, $"${_building.GuestCost:N0}", Color.Green );
			}
		}

		if ( _timer && _building is not BasicRide )
		{
			_building.Unload( _guest );

			bool success = _building.OnUse( _guest );

			if ( success )
			{
				_guest.Thoughts.AddThought( $"Used {_building.Title}", _building.WorldPosition );
			}

			return success ? Status.Success : Status.Failure;
		}

		return Status.Running;
	}

	public override ActionDisplayInfo? GetDisplay()
	{
		if ( !_started )
			return new ActionDisplayInfo( "business", "Entering...", 0f );

		float progress = _duration > 0f
			? 1f - (_timer.Relative / _duration).Clamp( 0f, 1f )
			: 0f;

		return new ActionDisplayInfo( "business", _building.GetInUseDescription( _guest ), progress );
	}
}