using UnityEngine;
using ScrambleKit.Hits;

public enum AIState
{
    Walking,
    ChargeUp,
    Attack,
    Stunned
}


public class AIPattern : MonoBehaviour
{
    public float AttackInterval;
    public float ChargeUpDuration;
    public float AttackDuration;

    private AIState state;
    private EnemyMovementController move;

    private float nextAttackAt;
    private float stunnedUntil;
    private float chargingUntil;
    private float attackingUntil;

    void Start()
    {
        move = GetComponent<EnemyMovementController>();
        nextAttackAt = Time.time + AttackInterval * Random.Range(1.15f, 1.85f);
    }

    void Update()
    {
        switch (state)
        {
            case AIState.Walking:
                if (TimeToAttack())
                    EnterState(AIState.ChargeUp);
                else if (ArrivedAtTarget())
                    EnterState(AIState.Walking);
                break;
            case AIState.ChargeUp:
                if (ChargeUpDone())
                {
                    EnterState(AIState.Attack);
                }
                break;
            case AIState.Attack:
                if (AttackDone())
                {
                    nextAttackAt = Time.time + AttackInterval * Random.Range(0.8f, 1.2f);
                    EnterState(AIState.Walking);
                }
                break;
            case AIState.Stunned:
                if (StunIsOver())
                {
                    nextAttackAt = Time.time + AttackInterval * Random.Range(0.6f, 1f);
                    EnterState(AIState.Walking);
                }
                break;
        }
    }

    void EnterState(AIState s)
    {
        // AIState oldstate = state;
        state = s;
        switch (state)
        {
            case AIState.Walking:
                transform.BroadcastMessage("ChangeAnimationState", EnemyState.Idle);
                transform.SendMessage("ChooseNewSpot", move);
                break;
            case AIState.ChargeUp:
                transform.BroadcastMessage("ChangeAnimationState", EnemyState.Telegraph);
                move.TargetPos = transform.position;
                chargingUntil = Time.time + ChargeUpDuration;
                break;
            case AIState.Attack:
                transform.BroadcastMessage("ChangeAnimationState", EnemyState.Attack);
                transform.BroadcastMessage("PerformAttack");
                attackingUntil = Time.time + AttackDuration;
                break;
            case AIState.Stunned:
                transform.BroadcastMessage("ChangeAnimationState", EnemyState.Hurt);
                break;
        }
    }

    private bool ArrivedAtTarget()
    {
        Vector2 dist = move.TargetPos - (Vector2)transform.position;
        return dist.magnitude < 0.1f;
    }

    private bool TimeToAttack()
    {
        if (AttackInterval == -1)
            return false;
        else
            return Time.time > nextAttackAt;
    }

    private bool ChargeUpDone()
    {
        return Time.time > chargingUntil;
    }

    private bool AttackDone()
    {
        return Time.time > attackingUntil;
    }

    private bool StunIsOver()
    {
        return Time.time > stunnedUntil;
    }

    void TakeHit(HitInfo hit)
    {
        if (hit.StunTime > 0)
        {
            stunnedUntil = Time.time + hit.StunTime;
            EnterState(AIState.Stunned);
        }
    }

    public void OnCollisionEnter2D(Collision2D col)
    {
        if (state == AIState.Walking)
        {
            transform.SendMessage("ChooseNewSpot", move);
        }
    }
}
