using UnityEngine;
using UnityEngine.AI;

public class EnemyAI : MonoBehaviour
{
    public NavMeshAgent agent;
    public Transform player;
    public LayerMask whatIsGround, whatIsPlayer;
    public Transform projectilepoint;

    //Patroling
    public Vector3 walkPoint;
    bool walkPointSet;
    public float walkPointRange;

    //Attacking
    public float timeBetweenAttacks;
    bool alreadyAttacked;
    public bool ranged;
    public GameObject projectile;
    public float projectileSpeed;
    public float projectileUpForce;
    public float attackDamage;
    public Animator animator;

    //States
    public float sightRange, attackRange;
    public bool playerInSightRange, playerInAttackRange;

    public CameraShake shaker;

    private void Awake()
    {
        player = GameObject.Find("PlayerObj").transform;
        agent = GetComponent<NavMeshAgent>();
        shaker = GameObject.Find("Boomshakalaka").GetComponent<CameraShake>();
        animator = GetComponentInChildren<Animator>();
    }

    private void Update()
    {
        playerInSightRange = Physics.CheckSphere(transform.position, sightRange, whatIsPlayer);
        playerInAttackRange = Physics.CheckSphere(transform.position, attackRange, whatIsPlayer);

        if (!playerInSightRange && !playerInAttackRange) Patroling();
        if (playerInSightRange && !playerInAttackRange) ChasePlayer();
        if (playerInSightRange && playerInAttackRange) AttackPlayer();

    }

    private void Patroling()
    {
        if (!walkPointSet) SearchWalkPoint();

        if (walkPointSet)
        {
            animator.SetBool("Walking", true);
            agent.SetDestination(walkPoint);
        }
        Vector3 distanceToWalkPoint = transform.position - walkPoint;
        if(distanceToWalkPoint.magnitude < 1f)
        {
            animator.SetBool("Walking", false);
            walkPointSet = false;
        }
    }

    private void SearchWalkPoint()
    {
        float randomZ = Random.Range(-walkPointRange, walkPointRange);
        float randomX = Random.Range(-walkPointRange, walkPointRange);

        walkPoint = new Vector3(transform.position.x + randomX, transform.position.y, transform.position.z + randomZ);

        if(Physics.Raycast(walkPoint, -transform.up, 2f, whatIsGround)){
            walkPointSet = true;
        }
    }

    private void ChasePlayer()
    {
        animator.SetBool("Walking", true);
        agent.SetDestination(player.position);
    }

    private void AttackPlayer()
    {
        animator.SetBool("Walking", false);
        agent.SetDestination(transform.position);

        if (!alreadyAttacked)
        {
            //Atk code here!!
            animator.SetTrigger("Attack");
            if (ranged)
            {
                transform.LookAt(player);
                Rigidbody rb = Instantiate(projectile, projectilepoint.position, Quaternion.identity).GetComponent<Rigidbody>();
                rb.AddForce(transform.forward * projectileSpeed, ForceMode.Impulse);
                rb.AddForce(transform.up * projectileUpForce, ForceMode.Impulse);
            }
            if (!ranged)
            {
                player.gameObject.GetComponentInParent<Blood>().DrainBlood(attackDamage);
                StartCoroutine(shaker.Shake(.15f, .15f));
            }

            alreadyAttacked = true;
            Invoke(nameof(ResetAttack), timeBetweenAttacks);
        }
    }

    private void ResetAttack()
    {
        alreadyAttacked = false;
    }

    private void OnDrawGizmosSelected()
    {
        Gizmos.color = Color.red;
        Gizmos.DrawWireSphere(transform.position, attackRange);
        Gizmos.color = Color.yellow;
        Gizmos.DrawWireSphere(transform.position, sightRange);
    }

}