#nullable enable
using UnityEngine;

public class Monster : AIEntity {
	[HideInInspector] public bool thrownFromSafeZone;
	[HideInInspector] public Vector3 thrownTargetPosition;
	
    // Start is called before the first frame update
    override protected void Start()
    {
        base.Start();
        base.entityType = EntityFlag.Monster;
        base.enemies = EntityFlag.Gladiator;
    }

    protected override BaseState CreateInitialState()
	    => thrownFromSafeZone
		? (BaseStateAI)new NonPhysicThrownState(this, thrownTargetPosition)
		: new ThrownState(this);
    
    protected override bool IsTargetable(Entity other) => other.IsAlive() && other is Gladiator;

    //Basically a copy of JumpingMovementState
    protected class NonPhysicThrownState : BaseStateAI {
	    readonly Vector3 target;

	    Vector3 startPosition;
	    float duration;
	    float startTime;

	    public NonPhysicThrownState(AIEntity entity, Vector3 target) : base(entity) {
		    this.target = target;
	    }

	    public override void EnterState() {
		    base.EnterState();
		    
		    duration = entity.AIStats.ThrownDurationPerMeter * Vector3.Distance(entity.transform.position, target);
		    startPosition = entity.transform.position;
		    startTime = Time.time;
		    entity.rb.SetEnabled(false);
	    }

	    public override void LeaveState() {
		    base.LeaveState();
		    entity.rb.SetEnabled(true);
	    }

	    public override BaseState? FixedUpdateState() {
		    float currentTime = Time.time - startTime;
		    if (currentTime >= duration)
			    return new FindTargetState(entity);

		    entity.rb.MovePosition(Vector3.Lerp(
			    startPosition,
			    target,
			    entity.AIStats.ThrownCurve.Evaluate(currentTime / duration)
		    ));

		    return null;
	    }
    }
    
    protected class ThrownState : BaseStateAI {
	    public ThrownState(AIEntity entity) : base(entity) {}

	    public override void EnterState() {
		    base.EnterState();
		    
		    entity.rb.velocity = entity.direction * entity.AIStats.throwForce;
	    }

	    public override BaseState? FixedUpdateState() {
		    return entity.rb.velocity.magnitude < entity.AIStats.MinVelocityWhenThrown
			    ? new FindTargetState(entity)
			    : null;
	    }
    }
}
