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

public enum EnemyState { Running, Watching, Cleaned, GrabbingCandy, Evil}
public class Enemy : MonoBehaviour
{
    public EnemyState currentState;
    public float watchDistance, moveSpeed;
    public float veerMax = 15.0f;
    public float veerTimeMin = 1.0f, veerTimeMax = 3.0f;
    public float randomWalkTimeMin = 10.0f, randomWalkTimeMax = 15.0f;

    [Header("GameObjects")]
    public Transform targetHole;
    public ParticleSystem cleanTrail, cleanBurst, digOut;
    public AudioSource twinkleAS, wawaAS, evilAS, teethCrackAS;
    Transform candyTarget;

    PlayerMovement player;
    Rigidbody rb;
    float evilTimer = 0.0f, veerTimer = 0.0f, randomWalkTimer = 99.0f;
    float veerTimerTarget, randomWalkTimerTarget;
    bool veering = false;
    int evilTargetHole;
    float walkingHeight; //fuck this

    // Start is called before the first frame update
    void Start()
    {
        rb = GetComponent<Rigidbody>();
        player = PlayerMovement.Instance;
        walkingHeight = transform.position.y;
        watchDistance += Random.Range(0, 2.5f);
        randomWalkTimerTarget = Random.Range(randomWalkTimeMin, randomWalkTimeMax);
    }

    // Update is called once per frame
    void Update()
    {
        if (currentState == EnemyState.Running || currentState == EnemyState.Watching)
        {
            if (Vector3.Distance(player.transform.position, transform.position) < watchDistance)
            {            
                currentState = EnemyState.Running;
                randomWalkTimer = randomWalkTimerTarget + 1;
            }
            else
            {
                currentState = EnemyState.Watching;
                veerTimer = 0.0f;
            }
        }

        Quaternion rotTarget;
        switch (currentState)
        {
            case EnemyState.Running:
                if (!veering)
                {
                    rotTarget = Quaternion.LookRotation(transform.position - player.transform.position);
                    rb.rotation = Quaternion.Euler(0, rotTarget.eulerAngles.y, 0);

                    veerTimer += Time.deltaTime;
                    if(veerTimer > veerTimerTarget)
                    {
                        veerTimer = 0.0f; veerTimerTarget = Random.Range(veerTimeMin, veerTimeMax);
                        veering = true;
                    }
                }
                else
                {
                    if(veerTimer == 0.0f) 
                    { 
                        rotTarget = Quaternion.LookRotation(transform.position - player.transform.position);
                        rb.rotation = Quaternion.Euler(0, rotTarget.eulerAngles.y + Random.Range(-veerMax, veerMax), 0);
                    }
                    veerTimer += Time.deltaTime;
                    if (veerTimer > veerTimerTarget)
                    {
                        veerTimer = 0.0f; veerTimerTarget = Random.Range(veerTimeMin * 2, veerTimeMax * 2);
                        veering = false;
                    }
                }
                rb.velocity = transform.forward * moveSpeed;
                break;

            case EnemyState.GrabbingCandy:
                if(candyTarget == null) { currentState = EnemyState.Watching; break; }
                rotTarget = Quaternion.LookRotation(candyTarget.position - transform.position);
                rb.rotation = Quaternion.Euler(0, rotTarget.eulerAngles.y, 0);
                rb.velocity = transform.forward * moveSpeed;                
                break;

            case EnemyState.Evil:
                Vector3 tarPos = GameManager.Instance.holes[evilTargetHole].position;

                if (Vector3.Distance(Vector3.Scale(tarPos + new Vector3(0, 0, 0.75f), new Vector3(1,0,1)), 
                    Vector3.Scale(transform.position, new Vector3(1, 0, 1))) > 0.1f)
                {
                    rotTarget = Quaternion.LookRotation((tarPos + new Vector3(0, 0, 0.75f)) - transform.position);
                    rb.rotation = Quaternion.Euler(0, rotTarget.eulerAngles.y, 0);
                    rb.velocity = transform.forward * 1.5f * moveSpeed;
                    evilTimer = 0.0f;

                }
                else
                {
                    if(evilTimer == 0.0f && GameManager.Instance.holes[evilTargetHole].GetComponent<ToothHole>().isFilled) 
                    {
                        teethCrackAS.Play();
                        GameManager.Instance.holes[evilTargetHole].GetComponent<ToothHole>().assignedTooth.digOut.Play();
                    }
                    evilTimer += Time.deltaTime;
                    if (!GameManager.Instance.holes[evilTargetHole].GetComponent<ToothHole>().isFilled) { evilTimer += 5 * Time.deltaTime; }
                    
                    if (evilTimer < 2.0f)
                    {
                        rotTarget = Quaternion.LookRotation(tarPos - transform.position);
                        rb.rotation = Quaternion.Euler(0, rotTarget.eulerAngles.y, 0);
                        rb.velocity = Vector3.zero;
                    }
                    else
                    {
                        if(GameManager.Instance.holes[evilTargetHole].GetComponent<ToothHole>().isFilled)
                        {
                            GameManager.Instance.holes[evilTargetHole].GetComponent<ToothHole>().assignedTooth.GetFreedFromHole();
                            //Clean tooth in hole
                        }
                        evilTargetHole++; evilTargetHole %= GameManager.Instance.holes.Length;
                        evilTimer = 0.0f;
                    }
                }
                break;

            case EnemyState.Watching:

                randomWalkTimer += Time.deltaTime;
                if(randomWalkTimer > randomWalkTimerTarget)
                {
                    randomWalkTimerTarget = Random.Range(randomWalkTimeMin, randomWalkTimeMax);
                    rotTarget = Quaternion.LookRotation(new Vector3(1.7f,0,25.34f) - transform.position);

                    rb.rotation = Quaternion.Euler(0, rotTarget.eulerAngles.y + Random.Range(-110, 110), 0);
                    randomWalkTimer = 0.0f;
                }
                rb.velocity = transform.forward * 0.75f * moveSpeed;
                break;

            case EnemyState.Cleaned:
                if (Vector3.Distance(Vector3.Scale(targetHole.position, new Vector3(1,0,1)), Vector3.Scale(transform.position, new Vector3(1, 0, 1))) > 0.1f)
                {
                    if (moveSpeed > 0)
                    {
                        rotTarget = Quaternion.LookRotation(targetHole.position - transform.position);
                    }
                    else
                    {
                        rotTarget = Quaternion.LookRotation(player.transform.position - transform.position);
                    }
                    
                    rb.rotation = Quaternion.Euler(0, rotTarget.eulerAngles.y, 0);
                    rb.velocity = transform.forward * moveSpeed;
                }
                else
                {
                    targetHole.GetComponent<ToothHole>().isFilled = true;
                    cleanTrail.Stop();
                    GameManager.Instance.ToothReachedHole();
                    transform.rotation = targetHole.rotation;
                    transform.position = targetHole.position;
                    rb.velocity = Vector3.zero;
                    rb.isKinematic = true;
                    enabled = false;
                }
                break;
        }
    }

    private void OnTriggerEnter(Collider other)
    {
        if(currentState == EnemyState.Cleaned) { return; }
        if (other.CompareTag("Toothbrush")) 
        { 
            GetComponent<Animator>().SetTrigger("GetCleaned"); 
            StartCoroutine(CleanedDelayC());
            
            PlayerMovement.Instance.PlayToothbrushSound();
        }

        if(currentState == EnemyState.Evil) { return; }
        if(other.CompareTag("CandyFollow") )
        {
            candyTarget = other.GetComponentInParent<Candy>().transform;
            currentState = EnemyState.GrabbingCandy;
        }

        if(other.CompareTag("Candy"))
        {
            ParticleSystem particles = other.GetComponentInParent<Candy>().GetComponentInChildren<ParticleSystem>();
            particles.Stop(false, ParticleSystemStopBehavior.StopEmitting);
            particles.transform.parent = null;
            Destroy(particles.gameObject, 5.0f);

            Destroy(other.GetComponentInParent<Candy>().gameObject);
            currentState = EnemyState.Evil;
            GetComponent<Animator>().SetTrigger("BecomeEvil");
            wawaAS.Stop();
            evilAS.Play();
            evilTargetHole = Random.Range(0, GameManager.Instance.holes.Length);
        }
    }

    public void GetFreedFromHole()
    {
        enabled = true;
        rb.isKinematic = false;
        wawaAS.Play();
        evilAS.Stop();
        teethCrackAS.Stop();

        GetComponent<Animator>().SetTrigger("GetFreedFromHole");
        currentState = EnemyState.Watching;

        targetHole.GetComponent<ToothHole>().isFilled = false;
        GameManager.Instance.ToothFreedFromHole();
        transform.position = new Vector3(transform.position.x, walkingHeight, transform.position.z);
    }

    IEnumerator CleanedDelayC()
    {
        cleanBurst.gameObject.SetActive(true);
        cleanBurst.Play();
        twinkleAS.Play();
        wawaAS.Stop();

        currentState = EnemyState.Cleaned;
        float oldSpeed = moveSpeed;
        moveSpeed = 0;
        yield return new WaitForSeconds(1.0f);

        cleanBurst.Stop();
        cleanBurst.gameObject.SetActive(false);
        cleanTrail.gameObject.SetActive(true);
        cleanTrail.Play();

        moveSpeed = oldSpeed;

    }
}
