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

public class FanController : MonoBehaviour {

    private bool isGrounded = false;
    [HideInInspector]
    public Transform fanFollowing;
    private float pushBack = 8f;
    private enum action { Idle, Walk, HitNormal, HitBack, Follow, Run, Charge};
    private action fanState;
    private float timerToGo;
    private Vector3 moveDir;
    public float walkspeed = 6.0f;
    public float runspeed = 9.0f;
    private float speed = 0;
    private Vector2 faceDir;
    [HideInInspector]
    public bool isCharge = false;
    private float chargeSpeed = 0.0f;
    private GameObject[] Idols;
    private float temperDown;

    public string fanType = "Normal";
    private Vector2[] directions = new Vector2[] { new Vector2(0f, -1f), new Vector2(-1f, 0f), new Vector2(1f, 0f), new Vector2(0f, 1f), new Vector2(1f, 1f), new Vector2(-1f, -1f) };

    private Animator animator;
    //animation states - the values in the animator conditions
    private const int STATE_IDLE = 0;
    private const int STATE_WALK = 1;
    private const int STATE_INLOVE_WALK1 = 2;
    private const int STATE_INLOVE_WALK2 = 3;
    private const int STATE_HIT = 4;
    private const int STATE_AVOID = 5;
    private const int STATE_CHARGE = 6;
    private int _currentAnimationState = STATE_IDLE;
    private SpriteRenderer spriteRender;
    private int health = 1;

    void Start () {
        string[] choiceType = new string[] { "Normal", "Tsun", "Agressive" };
        string choice = choiceType[Random.Range(0, 2)];
        fanType = choice;
        setRandomSkin();
        fanState = action.Idle;
        Idols = GameObject.FindGameObjectsWithTag("Idol");
        temperDown = Random.Range(30f, 300f);
        if(fanType == "Tsun")
        {
            health = 2;
        }
        if (fanType == "Agressive")
        {
            health = 3;
        }
    }

    private void FixedUpdate()
    {
        if (fanState != action.Follow)
        {
            GetComponent<Rigidbody>().MovePosition(GetComponent<Rigidbody>().position + transform.TransformDirection(moveDir) * speed * Time.deltaTime);
        }
        switch (fanState)
        {
            case action.Idle:
                idle();
                break;
            case action.Walk:
                walk();
                break;
            case action.HitNormal:
                hit();
                break;
            case action.HitBack:
                hitBackToNormal();
                break;
            case action.Follow:
                followIdol();
                break;
            case action.Run:
                run();
                break;
            case action.Charge:
                onCharge();
                break;
        }
    }

    void idle()
    {
        changeAnimationState(STATE_WALK);
        moveDir = new Vector3(0, 0, 0);
        timerToGo -= 1f;
        if (timerToGo <= 0)
        {
            fanState = action.Walk;
            timerToGo = Random.Range(30f, 250f);
            changeDirection();
        }
        lookOut();
        findToCharge();
    }

    void walk()
    {
        changeAnimationState(STATE_WALK);
        speed = walkspeed;
        timerToGo -= 1f;
        if (timerToGo <= 0)
        {
            fanState = action.Idle;
            timerToGo = Random.Range(30f, 250f);
        }
        flipDir();
        lookOut();
        findToCharge();
    }

    void hit()
    {
        changeAnimationState(STATE_HIT);
        if (isGrounded)
        {
            health--;
            if (health <= 0) {
                fanState = action.Follow;
            }
        }
        flipDir();
    }

    void hitBackToNormal()
    {
        changeAnimationState(STATE_HIT);
        if (isGrounded)
        {
            fanState = action.Idle;
        }
        flipDir();
    }

    void followIdol()
    {
        if(fanFollowing.name == "Idol1")
        {
            changeAnimationState(STATE_INLOVE_WALK1);
        } else
        {
            changeAnimationState(STATE_INLOVE_WALK2);
        }
        var dir = fanFollowing.transform.position - transform.position;

        if (dir.magnitude > 3.0f)
        {
            transform.position = Vector3.MoveTowards(transform.position, fanFollowing.transform.position, .15f);
        }
    }

    void flipDir()
    {
        if (moveDir.x < 0)
        {
            spriteRender.flipX = false;
        }
        if (moveDir.x > 0)
        {
            spriteRender.flipX = true;
        }
    }

    public void returnToNormal()
    {
        fanFollowing = null;
        fanState = action.HitBack;
        Vector2 selectDirection = directions[Random.Range(0, directions.Length)];
        GetComponent<Rigidbody>().velocity = new Vector3(selectDirection.x * pushBack, 10f, selectDirection.y * pushBack);
    }

    void run()
    {
        changeAnimationState(STATE_AVOID);
        speed = runspeed;

        foreach (GameObject idol in Idols)
        {
            if (Vector3.Distance(idol.transform.position, transform.position) > 10f)
            {
                fanState = action.Idle;
            }
        }
        flipDir();
    }

    void findToCharge()
    {
        if (fanType == "Aggressive")
        {
            if (temperDown <= 0f)
            {
                if (!isCharge)
                {
                    foreach (GameObject idol in Idols)
                    {
                        if (Vector3.Distance(idol.transform.position, transform.position) < 6f)
                        {
                            isCharge = true;
                            setTargetDirection(idol.transform);
                            fanState = action.Charge;
                            chargeSpeed = 45.0f;
                        } else
                        {
                            temperDown = Random.Range(30f, 300f);
                        }
                    }
                }
            }
            else
            {
                temperDown -= 1f;
            }
        }
    }

    void onCharge()
    {
        changeAnimationState(STATE_CHARGE);
        chargeSpeed -= 1f;
         speed = chargeSpeed;
         if (chargeSpeed <= 0f)
         {
            isCharge = false;
            temperDown = Random.Range(30f, 300f);
            fanState = action.Idle;
        }
    }

    void setTargetDirection(Transform target)
    {
        Vector3 targetDirection = (target.position - transform.position);
        faceDir.x = targetDirection.magnitude;
        faceDir.y = targetDirection.magnitude;
        moveDir = new Vector3(faceDir.x, 0, faceDir.y).normalized;
    }

    void setRunDirection(Transform target)
    {
        Vector3 targetDirection = (transform.position - target.position);
        faceDir.x = targetDirection.magnitude;
        faceDir.y = targetDirection.magnitude;
        moveDir = new Vector3(faceDir.x, 0, faceDir.y).normalized;
    }

    void lookOut()
    {
        if(fanType == "Tsun") { 
          foreach (GameObject idol in Idols)
          {
              if (Vector3.Distance(idol.transform.position, transform.position) < 5f)
              {
                  fanState = action.Run;
                  setRunDirection(idol.transform);
              }
          }
        }
    }

    void changeDirection()
    {
        Vector2 selectDirection = directions[Random.Range(0, directions.Length)];
        faceDir.x = selectDirection.x;
        faceDir.y = selectDirection.y;
        moveDir = new Vector3(faceDir.x, 0, faceDir.y).normalized;
    }

    private void OnCollisionEnter(Collision collision)
    {
        if (collision.gameObject.tag == "Untagged")
            return;
        if (collision.gameObject.tag == "Idol" && collision.gameObject.GetComponent<IdolController>().isGrab)
        {
            fanFollowing = collision.transform;
            fanState = action.HitNormal;
            isGrounded = false;
            isCharge = false;
            Vector3 direction = (transform.position - collision.transform.position).normalized;
            GetComponent<Rigidbody>().velocity = new Vector3(direction.x * pushBack, 2.5f, direction.z * pushBack);
        }
        if(collision.gameObject.tag == "WallH")
        {
            if (fanState == action.HitNormal)
            {
                Vector3 direction = (transform.position - collision.transform.position).normalized;
                GetComponent<Rigidbody>().velocity = new Vector3(direction.x * (pushBack / 2), 0f, direction.z * (pushBack / 2));
            } else
            {
                moveDir = new Vector3(faceDir.x * -1f, 0, faceDir.y).normalized;
            }
        }
        if (collision.gameObject.tag == "WallV")
        {
            if (fanState == action.HitNormal)
            {
                Vector3 direction = (transform.position - collision.transform.position).normalized;
                GetComponent<Rigidbody>().velocity = new Vector3(direction.x * (pushBack / 2), 0f, direction.z * (pushBack / 2));
            }
            else
            {
                moveDir = new Vector3(faceDir.x, 0, faceDir.y * -1f).normalized;
            }
        }
        if (collision.gameObject.tag == "Ground")
        {
            isGrounded = true;
        }
    }

    void setRandomSkin()
    {
        spriteRender = GetComponent<SpriteRenderer>();
        animator = this.GetComponent<Animator>();
        float choice = Random.Range(1, 4);
        switch (fanType)
        {
            case "Normal":
                if (choice == 1)
                {
                    animator.runtimeAnimatorController = Resources.Load("Sprites/Normal1Controller") as RuntimeAnimatorController;
                    spriteRender.sprite = Resources.Load<Sprite>("Sprites/Normal-Character-1");
                }
                if(choice == 2)
                {
                    animator.runtimeAnimatorController = Resources.Load("Sprites/Normal2Controller") as RuntimeAnimatorController;
                    spriteRender.sprite = Resources.Load<Sprite>("Sprites/Normal-Character-2");
                }
                if (choice == 3)
                {
                    animator.runtimeAnimatorController = Resources.Load("Sprites/Normal3Controller") as RuntimeAnimatorController;
                    spriteRender.sprite = Resources.Load<Sprite>("Sprites/Normal-Character-3");
                }
                if (choice == 4)
                {
                    animator.runtimeAnimatorController = Resources.Load("Sprites/Normal4Controller") as RuntimeAnimatorController;
                    spriteRender.sprite = Resources.Load<Sprite>("Sprites/Normal-Character-4");
                }
                break;
            case "Tsun":
                if (choice == 1)
                {
                    animator.runtimeAnimatorController = Resources.Load("Sprites/Tsun1Controller") as RuntimeAnimatorController;
                    spriteRender.sprite = Resources.Load<Sprite>("Sprites/Tsundere-Character-1");
                }
                if (choice == 2)
                {
                    animator.runtimeAnimatorController = Resources.Load("Sprites/Tsun2Controller") as RuntimeAnimatorController;
                    spriteRender.sprite = Resources.Load<Sprite>("Sprites/Tsundere-Character-2");
                }
                if (choice == 3)
                {
                    animator.runtimeAnimatorController = Resources.Load("Sprites/Tsun3Controller") as RuntimeAnimatorController;
                    spriteRender.sprite = Resources.Load<Sprite>("Sprites/Tsundere-Character-3");
                }
                if (choice == 4)
                {
                    animator.runtimeAnimatorController = Resources.Load("Sprites/Tsun4Controller") as RuntimeAnimatorController;
                    spriteRender.sprite = Resources.Load<Sprite>("Sprites/Tsundere-Character-4");
                }
                break;
            case "Aggressive":
                if (choice == 1)
                {
                    animator.runtimeAnimatorController = Resources.Load("Sprites/Agressive1Controller") as RuntimeAnimatorController;
                    spriteRender.sprite = Resources.Load<Sprite>("Sprites/Agressive-Character-1");
                }
                if (choice == 2)
                {
                    animator.runtimeAnimatorController = Resources.Load("Sprites/Agressive2Controller") as RuntimeAnimatorController;
                    spriteRender.sprite = Resources.Load<Sprite>("Sprites/Agressive-Character-2");
                }
                if (choice == 3)
                {
                    animator.runtimeAnimatorController = Resources.Load("Sprites/Agressive3Controller") as RuntimeAnimatorController;
                    spriteRender.sprite = Resources.Load<Sprite>("Sprites/Agressive-Character-3");
                }
                if (choice == 4)
                {
                    animator.runtimeAnimatorController = Resources.Load("Sprites/Agressive4Controller") as RuntimeAnimatorController;
                    spriteRender.sprite = Resources.Load<Sprite>("Sprites/Agressive-Character-4");
                }
                break;
        }
    }

    void changeAnimationState(int state)
    {

        if (_currentAnimationState == state)
            return;

        switch (state)
        {

            case STATE_WALK:
                animator.SetInteger("state", STATE_WALK);
                break;

            case STATE_INLOVE_WALK1:
                animator.SetInteger("state", STATE_INLOVE_WALK1);
                break;

            case STATE_INLOVE_WALK2:
                animator.SetInteger("state", STATE_INLOVE_WALK2);
                break;

            case STATE_HIT:
                animator.SetInteger("state", STATE_HIT);
                break;

            case STATE_IDLE:
                animator.SetInteger("state", STATE_IDLE);
                break;
            case STATE_AVOID:
                animator.SetInteger("state", STATE_AVOID);
                break;
            case STATE_CHARGE:
                animator.SetInteger("state", STATE_CHARGE);
                break;

        }

        _currentAnimationState = state;
    }
}
