using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class FollowingPatrollingEnemy : Enemy
{
    public Transform[] path;
    public int currentPoint;
    public Transform currentGoal;

    public AStarPathfindingAgent agent;
    
    public Transform target;
    public float chaseRadius;
    public float attackRadius;
    public Transform homePosition;

    public float roundingDistance = 0.2f;
    private Rigidbody2D myRigidbody;
    public Animator anim;
    public GameObject other;

    public bool inRange = false;
    public bool hit = false;
    public GameObject player;
    private bool firstAttack = false;

    private float timerDmg = 0f;
    private float waitTime = 1.0f;

    private float timerHit = 0f;
    private float hitWaitTime = 0.55f;

    public float thrust;
    public float knockTime;

    //isKilled = 0 - mob ALIVE
    //isKilled = 1 - mob DEAD

    public int isKilled2;

    public float expValue;


    void Awake()
    {
        //agent = GetComponent<AStarPathfindingAgent>();
    }
    
    // Start is called before the first frame update
    void Start()
    {
        if (OnMapAppearanceMethod.IsNewGame())
        {
            isKilled = 0;
        }

        if (health <= 0)
            isKilled = 1;
        else
            isKilled = PlayerPrefs.GetInt(enemyName + "-S");

        if (isKilled == 1)
        {
            gameObject.SetActive(false);
            health = 0;
        }
        myRigidbody = GetComponent<Rigidbody2D>();
        anim = GetComponent<Animator>();
        target = GameObject.FindWithTag("Player").transform;
        other = GameObject.FindWithTag("Player");

        roundingDistance = 1.3f;
    }

    // Update is called once per frame
    void Update()
    {
        CheckDistance();
        //StartCoroutine(Timer());

        //Code below is for dealing damage to player

        if (inRange == true)
        {
            if (firstAttack == false)
            {
                if (timerDmg >= 0.15f)
                {
                    firstAttack = true;
                    other.GetComponent<Player>().TakeDamage(baseAttack);
                    timerDmg = 0f;
                }
            }
            if (timerDmg >= waitTime)
            {
                timerDmg = 0f;
                other.GetComponent<Player>().TakeDamage(baseAttack);
            }
            timerDmg += Time.deltaTime;
        }

        timerHit += Time.deltaTime;
        if (hit == true)
        {
            if (timerHit >= hitWaitTime)
            {
                TakeDamage(PlayerPrefs.GetFloat("attackValue"));
                hit = false;
                timerHit = 0f;
                TakeKnockback();
            }
        }
        if (gameObject.active == false)
        {
            isKilled = 1;
            PlayerPrefs.SetInt(enemyName, isKilled);
        }
    }


    void CheckDistance()
    {
        StopAllCoroutines();
        if (Vector2.Distance(target.position, transform.position) <= chaseRadius && Vector2.Distance(target.position, transform.position) > attackRadius)
        {
            
            //Debug.Log(agent);
            agent.FindPath();
            //transform.position = Vector2.MoveTowards(transform.position, target.position, moveSpeed * Time.deltaTime);
            StartCoroutine(agent.FollowPath());
        }
        else if (Vector2.Distance(target.position, transform.position) > chaseRadius)
        {

            //Debug.Log(Vector2.Distance(transform.position, path[currentPoint].position));

            if (Vector2.Distance(transform.position, path[currentPoint].position) > roundingDistance)
            {
                //transform.position = Vector2.MoveTowards(transform.position, path[currentPoint].position, moveSpeed * Time.deltaTime);
                agent.point = path[currentPoint].position;

                agent.FindPoint();
                StartCoroutine(agent.FollowPath());
            }
            else
            {
                changeGoal();
            }
        }
        if (gameObject.active == false)
        {
            isKilled = 1;
            PlayerPrefs.SetInt(enemyName, isKilled);
        }
    }


    void OnTriggerEnter2D(Collider2D collision)
    {
        ///For attacking player
        if (collision.tag == "PlayerHitbox")
        {
            inRange = true;
            firstAttack = false;
        }

        if (collision.tag == "AttackHitbox" || collision.tag == "PickaxeHitbox") 
        {
            hit = true;
        }
    }

    void OnTriggerStay2D(Collider2D collision)
    {
        ///For attacking player
        if (collision.tag == "PlayerHitbox")
        {
            inRange = true;
        }
    }

    void OnTriggerExit2D(Collider2D collision)
    {
        ///For attacking player
        inRange = false;
        timerDmg = 0f;
        hit = false;
    }

    public void TakeDamage(float damage)
    {
        health = health - damage;
        if (health <= 0)
        {
            gameObject.SetActive(false);
            isKilled = 1;
            other.GetComponent<Player>().GetExp(expValue);

            // pass info about killing assigned enemy to mission manager listener
            // pass enemy name from script NOT object name (thats allow to have many different objects variantsa with this same aggregate key (private name - not preffab name) )
            ConditionManager.Instance.UpdateKillCondition(gameObject.GetComponent<Enemy>().MinionName);

            gameObject.GetComponent<EnemyDrop>().Drop();
        }
    }

    public void TakeKnockback()
    {
        Rigidbody2D enemy = gameObject.GetComponent<Rigidbody2D>();
        Rigidbody2D player = other.GetComponent<Rigidbody2D>();
        if (enemy != null && gameObject.active)
        {
            enemy.isKinematic = false;
            Vector2 difference = enemy.transform.position - player.transform.position;
            difference = difference.normalized * thrust;
            enemy.AddForce(difference, ForceMode2D.Impulse);
            StartCoroutine(KnockCo(enemy));
        }
    }

    private IEnumerator KnockCo(Rigidbody2D enemy)
    {
        if (enemy != null)
        {
            yield return new WaitForSeconds(knockTime);
            enemy.velocity = Vector2.zero;
            enemy.isKinematic = true;
        }
    }

    private void changeGoal()
    {
        if (currentPoint == path.Length - 1)
        {
            currentPoint = 0;
            currentGoal = path[0];
        }
        else
        {
            currentPoint++;
            currentGoal = path[currentPoint];
        }
    }
}