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

public class Enemy : MonoBehaviour
{
    // ============================================================
    [Header("Stats")]
    // ============================================================

    [SerializeField]
    private float _health = 100f;

    [SerializeField]
    private float _walkSpeed = 1f;  // Max movement speed

    [SerializeField]
    private float _turnSpeed = 1f;  // radians per second

    [SerializeField]
    private float _moanTime = 7f;

    // ============================================================
    [Header("Refs")]
    // ============================================================

    public Player player;

    [SerializeField]
    private GameManager _gameManager;

    [SerializeField]
    private GameObject _model;

    [SerializeField]
    private AudioClip[] _moans;

    Rigidbody _rb;
    Animator _anim;
    BoxCollider _collider;
    bool _isWalking = false;
    bool _dead = false;
    float _animSpeed = 1f;
    float _moanTimer = 0f;

    private void Start() {
        _anim = _model.GetComponent<Animator>();
        _anim.speed = _animSpeed;
        _rb = GetComponent<Rigidbody>();
        _collider = GetComponent<BoxCollider>();
        if (_gameManager == null) {
            _gameManager = GameObject.Find("Game Manager").GetComponent<GameManager>();
        }
        _moanTimer += Random.Range(0, _moanTime / 2);
    }

    private void Update() {
        if (_dead) return;
        if (!_isWalking && IsGrounded()) {
            _anim.SetTrigger("start");
            _isWalking = true;
        }
        TurnTowardsPlayerAndWalk();
        MaybeMoan();
    }

    private void MaybeMoan() {
        if (_moanTimer > _moanTime) {
            Debug.Log("moaning");
            _moanTimer -= _moanTime;
            AudioSource.PlayClipAtPoint(_moans[Random.Range(0, _moans.Length)], transform.position);
        }
        _moanTimer += Time.deltaTime;
    }

    private void TurnTowardsPlayerAndWalk() {
        // enemies always walk towards the player
        Vector3 moveDir = player.transform.position - transform.position;
        Vector3 moveDirIn2D = Vector3.Normalize(new Vector3(moveDir.x, 0, moveDir.z));
        // Try to rotate towards the player
        float step = _turnSpeed * Time.deltaTime;
        Vector3 newFacing = Vector3.RotateTowards(transform.forward, moveDirIn2D, step, 0.0f).normalized;
        Debug.DrawRay(transform.position, newFacing, Color.red);


        // If we're walking right towards the player put our hands up to grabbem.
        RaycastHit hit;
        if (Physics.Raycast(transform.position, newFacing, out hit)) {
            _anim.SetBool("playerInSights",
                (hit.transform == player.transform)
                );
        }


        transform.rotation = Quaternion.LookRotation(newFacing);

        _rb.velocity = new Vector3(
            newFacing.x * _walkSpeed,
            _rb.velocity.y,
            newFacing.z * _walkSpeed
        );
    }

    public void TakeDamage(float damage) {
        if (_dead) return;
        _health -= damage;
        if (_health <= 0) {
            Die();
        }
    }

    bool IsGrounded() {
        float distanceToGround = _collider.bounds.extents.y;
        return Physics.CheckCapsule(
            _collider.bounds.center,
            new Vector3(
                _collider.bounds.center.x,
                _collider.bounds.min.y - 0.1f,
                _collider.bounds.center.z
            ),
            0.18f,
            LayerMask.GetMask("Terrain")
        );
    }

    private void Die() {
        _dead = true;
        _anim.SetBool("die", true);
        // Remove constraints and allow rb to fall over
        _rb.constraints = RigidbodyConstraints.None;
        _gameManager.IncrementKillCounter();

        Destroy(gameObject, 2f);
    }

    public void DoubleSpeed() {
        _walkSpeed *= 2;
        _animSpeed *= 2;
    }
}
