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

public class FollowingEnemy : Enemy
{
    public Transform target;
    public float chaseRadius;
    public float attackRadius;
    public Transform homePosition;
    private Vector2 movement;
    public float speed;
    public bool shouldRotate;
    public Vector3 dir;
    public LayerMask whatisplayer;

    public float roundingDistance;
    private Rigidbody2D rb;
    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;

    public int isKilled;
    //isKilled = 0 - mob ALIVE
    //isKilled = 1 - mob DEAD

    public int isKilled2;

    public bool isPanelEnabled=true;

    public float expValue;


    // Start is called before the first frame update
    void Start()
    {
        //used for animation of sprites
        rb = GetComponent<Rigidbody2D>();
        anim = GetComponent<Animator>();
        
        // if new game set as alive
        if (OnMapAppearanceMethod.IsNewGame())
        {
            isKilled = 0;
        }

        // But if something pre-set healt as less than 0 then change status to "killed"
        if (health <= 0)
            isKilled = 1;
        else  // Else read saved value
            isKilled = PlayerPrefs.GetInt(enemyName + "-S");
        

        if (isKilled == 1)
        {
            gameObject.SetActive(false);
            health = 0;
        }
        //rb = GetComponent<Rigidbody2D>();
        //anim = GetComponent<Animator>();

        target = GameObject.FindWithTag("Player").transform;
        other = GameObject.FindWithTag("Player");
    }

    // Update is called once per frame
    void Update()
    {
        //animation of Sprites
        if (Vector2.Distance(target.position, transform.position) <= chaseRadius)
        {
            dir = target.position - transform.position;
            float angle = Mathf.Atan2(dir.y, dir.x) * Mathf.Rad2Deg;
            dir.Normalize();
            movement = dir;
            anim.SetBool("isRunning", movement != Vector2.zero);
            if (shouldRotate)
            {
                anim.SetFloat("Xinfo", dir.x);
                anim.SetFloat("Yinfo", dir.y);
            }
        }
        

        if (CheckDistance())
        {
            MoveCharacter();
        }
        //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, isPanelEnabled);
                    timerDmg = 0f;
                }
            }
            if (timerDmg >= waitTime)
            {
                timerDmg = 0f;
                other.GetComponent<Player>().TakeDamage(baseAttack, isPanelEnabled);
            }
            timerDmg += Time.deltaTime;
        }

        timerHit += Time.deltaTime;
        if(hit == true)
        {
            if(timerHit >= hitWaitTime)
            {
                TakeDamage(1.0f);
                hit = false;
                timerHit = 0f;
                TakeKnockback();
            }
        }
        if (gameObject.active == false)
        {
            isKilled = 1;
            PlayerPrefs.SetInt(enemyName, isKilled);
        }
    }
    
    private void FixedUpdate()
    {
        /*if (Physics2D.OverlapCircle(transform.position, chaseRadius, whatisplayer))
        {
            MoveCharacter();
        }
        if (Physics2D.OverlapCircle(transform.position, attackRadius, whatisplayer))
        {
            rb.velocity = Vector2.zero;
        }*/
    }

    public AStarPathfindingAgent agent;
    private void MoveCharacter()
    {
        StopAllCoroutines();
        //rb.MovePosition((Vector2)transform.position + (dir * moveSpeed * Time.deltaTime));
        agent.FindPath();
        StartCoroutine(agent.FollowPath());
    }
    bool CheckDistance()
    {
        if(Vector2.Distance(target.position, transform.position) <= chaseRadius && Vector2.Distance(target.position, transform.position) > attackRadius)
        {
            //transform.position = Vector2.MoveTowards(transform.position, target.position, moveSpeed * Time.deltaTime);
            return true;
        }
        return false;
    }


    private void OnDrawGizmos()
    {
        Gizmos.color = Color.magenta;
        Gizmos.DrawWireSphere(transform.position,chaseRadius);
    }

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

        if (collision.tag == "AttackHitbox")
        {
            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);
        }
    }

    public void TakeKnockback()
    {
        Rigidbody2D enemy = gameObject.GetComponent<Rigidbody2D>();
        Rigidbody2D player = other.GetComponent<Rigidbody2D>();
        if (enemy != null)
        {
            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;
        }
    }

    public void SaveCheckpoint()
    {
        PlayerPrefs.SetInt(enemyName + "-S", isKilled);
        PlayerPrefs.SetFloat(enemyName + "-S.health", health);
    }
}