using UnityEngine;
using System.Collections;

public class EnemyAI : MonoBehaviour {

    public DecisionTree root;
    private Transform target;
    private Rigidbody2D Player;
    private Rigidbody2D Enemy;
    private Animator myAnimator;
    public float enemyHealth, original;
    public float playerHealth;
    public float playerHealthOriginal; // ***Maybe use playerstats maxhealth?
    private bool LookRight = false;
    public bool set;
    private float speed = 1;
    private float attackSpeed;
    private float randomSpeed;
    float spaceBarCounter = 0; //check for how aggresive the player is being 
    private float coolDown = 0;
    public bool actionDelay = false;
    public float searchDelay = 0.2f;
    public float searchCoolDown = 0;
    public static bool isEnemyKicking = false;
    public float kickCoolDown = 0;
    public float kickTimer;
    public float aggressiveTimer;
    public bool aggressiveCheck = false;
    public bool isAggressive = false;
    public bool isPlayerAttacking = false;
    public bool isPlayerBlocking = false;
    public bool isPlayerKicking = false;
    public float randomActionCoolDown = 0;
    public float randomAction;
    public float randomAcioionSpeed;

    void Start() {

        aggressiveTimer = 5;
        kickTimer = 5;
        randomSpeed = Random.Range(0, 1f);
        attackSpeed = randomSpeed;
        randomAcioionSpeed = Random.Range(0, 2f);
        randomAction = randomAcioionSpeed;
        enemyHealth = Random.Range(50, 500);
        original = enemyHealth;
        playerHealth = PlayerStats.getHealth();
        playerHealthOriginal = playerHealth;


        root = new DecisionTree();
        //  Debug.Log("start");
        target = GameObject.FindGameObjectWithTag("Player").transform; //look at the player
                                                                       // Player = GameObject.FindGameObjectWithTag("Player").GetComponent<Rigidbody2D>();
        myAnimator = GetComponent<Animator>(); //required for animation *******
        Enemy = GetComponent<Rigidbody2D>();
        BuildDecisionTree();

    }

    void Update() {
        AggressiveCoolDown();
        BlockCheck();
        AttackCheck();
        KickCheck();
        coolDown -= Time.deltaTime;
        kickCoolDown -= Time.deltaTime;
        randomActionCoolDown -= Time.deltaTime;
        if (actionDelay == true) {
            searchCoolDown -= Time.deltaTime;
            if (searchCoolDown <= 0) {
                searchCoolDown = searchDelay;
                root.search();
            }

        }
        else {
            root.search();
            actionDelay = false;
        }

    }

    public void AggressiveCoolDown() {
        if (Input.GetKeyDown(KeyCode.Space)) {
            spaceBarCounter++;
            // Debug.Log(spaceBarCounter);
            aggressiveCheck = true;
        }
        if (aggressiveCheck == true) {
            aggressiveTimer -= Time.deltaTime;
            // Debug.Log(agressiveTimer);
        }

        if (aggressiveTimer <= 0) {
            aggressiveCheck = false;
            spaceBarCounter = 0;
            aggressiveTimer = 5;
        }
    }

    public void BlockCheck() {
        isPlayerBlocking = ArenaCombatControl.block;
        Debug.Log(isPlayerBlocking + "Enemy");

        if (isPlayerBlocking == false) {
            myAnimator.SetBool("kick", false);
        }
    }

    public void AttackCheck() {
        isPlayerAttacking = ArenaCombatControl.attack;
    }

    public void KickCheck() {
        isPlayerKicking = ArenaCombatControl.kick;
    }

    public void HpCheck() {
        playerHealth = PlayerStats.curHealth;
    }



    public void ChangeHealthBare(int damage) {
        GameObject healthbar = GameObject.Find("healthbarFulle");
        float newsize = healthbar.transform.localScale.x - ((damage / original) * 0.3f);
        healthbar.transform.localScale = new Vector3(newsize, 0.3f, 1f);
        if (enemyHealth <= 0) {
            healthbar.GetComponent<SpriteRenderer>().enabled = false;
        }

    }
    public void ApplyDamageE(int damage) {
        enemyHealth -= damage;
        if (enemyHealth <= 0) {
            Destroy(gameObject);
        }
    }


    public bool d_isPlayerAttacking() {
        if (isPlayerAttacking == true) {
            return true;
        }
        Debug.Log("Player Not Attacking");
        return false;
    }

    public bool d_isPlayerKicking() {
        if (isPlayerKicking == true) {
            return true;
        }
        return false;
    }


    public bool d_inAttackRange() {
        isEnemyKicking = false;
        if (Vector3.Distance(transform.position, target.position) < 2f  && Vector3.Distance(transform.position, target.position) > 1f) {
            myAnimator.SetBool("speed", false);
            return true;
        }

        else if (isAggressive == true) {
            myAnimator.SetBool("block", true);
            return true;
        }

        else {
            myAnimator.SetBool("kick", false);
            myAnimator.SetBool("attack", false);
            myAnimator.SetBool("block", false);
            // Debug.Log("In Zone- not");
            return false;
        }
    }

    public bool d_isPlayerTooClose() {

        if (Vector3.Distance(transform.position, target.position) < 1f) {
            myAnimator.SetBool("speed", true);
            return false;
        }
        else {
            return true;
        }
    }


    public bool d_isPlayerAggresive() {
        if (spaceBarCounter > 5 && aggressiveTimer > 0) {
            isAggressive = true;
            Debug.Log("Aggressive");
            return true;
        }

        else {
            isAggressive = false;
            Debug.Log("Not Aggresive");
            return false;
        }

    }

    public bool d_isPlayerBlocking() {
        if (isPlayerBlocking == true) {
            return true;
        }
        return false;
    }



    public bool d_isPlayerHpLow() {
        if ((playerHealthOriginal / 2) > playerHealth) {
            Debug.Log("Player Half Health");
            return true;
        }
        Debug.Log("Player Full Health");
        return false;
    }


    public bool d_isHpLow() {
        if ((original / 2) > enemyHealth) {
            Debug.Log("Enemy Half Health");
            return true;
        }

        Debug.Log("Enemy Full Health");
        return false;
    }


    //makes a random decision with a 75% true return and a 25% false return
    public bool d_randomDecision75() {
        int x = Random.Range(1, 4);
        // Debug.Log(x);
        if (x == 1) {
            return false;
        }
        else return true;
    }


    // Actions
    public void a_attack() {
        actionDelay = true;
        myAnimator.SetFloat("speed", 0f);
        if (coolDown <= 0) {
            coolDown = attackSpeed;
            Debug.Log("attacking");
            myAnimator.SetBool("attack", true);
            Enemy.velocity = Vector2.zero;
        }
        else {
            myAnimator.SetBool("attack", false);
        }
    }

    public void a_push() {
        actionDelay = true;
        Player.AddForce(new Vector2(-250, 500));
    }

    public void a_superAttack() {
        myAnimator.SetFloat("speed", 0f);
        Debug.Log("attacking");
        myAnimator.SetBool("attack", true);
    }

    public void a_jumpBack() {
        actionDelay = true;
        Enemy.AddForce(new Vector2(-250, 500));
    }

    public void a_jump() {
        actionDelay = true;
        Enemy.AddForce(new Vector2(0, 500));
    }

    public void a_block() {
        Debug.Log("Block");
        actionDelay = true;
        myAnimator.SetBool("attack", false);
        myAnimator.SetBool("block", true);
        Enemy.velocity = Vector2.zero;

    }

    public void a_kick() {
        actionDelay = true;
        isEnemyKicking = true;
        if (kickCoolDown <= 0) {
            kickCoolDown = kickTimer;
            Debug.Log("kicking");
            myAnimator.SetBool("kick", true);
            Enemy.velocity = Vector2.zero;
        }
        else {
            myAnimator.SetBool("kick", false);
            myAnimator.SetBool("attack", true);
        }


    }

    public void a_randomAction() {
        Debug.Log("Action");
        float x = Random.Range(0, 250);
        
        actionDelay = true;
        if (randomActionCoolDown <= 0) {
            //Debug.Log(x);
            randomActionCoolDown = randomAction;

            if (x < 125) {
                a_block();
            }
            if (x > 225) {
                a_jumpBack();
            }

            if (x >= 125 && x <= 225) {
                a_attack();
            }
        }

    }

    public void a_randomBlock() {

        float x = Random.Range(0, 250);

        actionDelay = true;
        if (randomActionCoolDown <= 0) {
            //Debug.Log(x);
            randomActionCoolDown = randomAction;

            if (x < 125) {
                a_block();
            }
            if (x >= 125 && x <= 200) {
                a_jumpBack();
            }

            if (x > 200) {
                a_jump();
            }
        }

    }


    //template for a 'poison' special attack. Will slowly and gradually drain players health over time.
    public void poison() {
        Debug.Log("Performing Poison Attack");

    }

    public void a_moveToPlayer() {
        Debug.Log("moving");
        //rotate to look at the player
        //transform.LookAt(target.position);
        myAnimator.SetFloat("speed", 1); // This should probbaly reflect the actual speed
        transform.position = Vector2.MoveTowards(transform.position, target.position, speed * Time.deltaTime);

        if (target.transform.position.x <= transform.position.x) //players spot in world space as opposed to enemy "self" spot 
        {
            transform.rotation = new Quaternion(0, 180, 0, 0); // flips enemy around to face the player on x axis only
        }
        else if (target.transform.position.x >= transform.position.x) //players spot in world space as opposed to enemy "self" spot
        {
            transform.rotation = new Quaternion(0, 0, 0, 0); // flips enemy around to face the player on x axis only }
        }
    }

    public void a_moveFromPlayer() {
        Debug.Log("movingAWAY");
        //rotate to look at the player
        //transform.LookAt(target.position);
        myAnimator.SetFloat("speed", 1); // This should probbaly reflect the actual speed
        transform.position = Vector2.MoveTowards(transform.position, target.position, -speed * Time.deltaTime);

        if (target.transform.position.x <= transform.position.x) //players spot in world space as opposed to enemy "self" spot 
        {
            transform.rotation = new Quaternion(0, 180, 0, 0); // flips enemy around to face the player on x axis only
        }
        else if (target.transform.position.x >= transform.position.x) //players spot in world space as opposed to enemy "self" spot
        {
            transform.rotation = new Quaternion(0, 0, 0, 0); // flips enemy around to face the player on x axis only }
        }
    }




    public void BuildDecisionTree() {

        //Actions
        DecisionTree RandomAction = new DecisionTree();
        RandomAction.setAction(a_randomAction);

        DecisionTree RandomBlock = new DecisionTree();
        RandomBlock.setAction(a_randomBlock);

        DecisionTree Kick = new DecisionTree();
        Kick.setAction(a_kick);

        DecisionTree JumpBack = new DecisionTree();
        JumpBack.setAction(a_jumpBack);

        DecisionTree Block = new DecisionTree();
        Block.setAction(a_block);

        DecisionTree MoveToPlayer = new DecisionTree();
        MoveToPlayer.setAction(a_moveToPlayer);

        DecisionTree Attack = new DecisionTree();
        Attack.setAction(a_attack);

        DecisionTree MoveAway = new DecisionTree();
        MoveAway.setAction(a_moveFromPlayer);


        // Decisions
        DecisionTree isPlayerBlocking = new DecisionTree();
        isPlayerBlocking.setDecision(d_isPlayerBlocking);
        isPlayerBlocking.setLeft(Kick);
        isPlayerBlocking.setRight(Attack);

        DecisionTree GettingAttacked = new DecisionTree();
        GettingAttacked.setDecision(d_isPlayerAttacking);
        GettingAttacked.setLeft(RandomBlock);
        GettingAttacked.setRight(Attack);

        DecisionTree PlayerHP = new DecisionTree();
        PlayerHP.setDecision(d_isPlayerHpLow);
        PlayerHP.setLeft(Attack);
        PlayerHP.setRight(GettingAttacked);

        DecisionTree PlayerHP2 = new DecisionTree();
        PlayerHP2.setDecision(d_isPlayerHpLow);
        PlayerHP2.setLeft(Attack);
        PlayerHP2.setRight(MoveAway);

        DecisionTree PlayerHP3 = new DecisionTree();
        PlayerHP3.setDecision(d_isPlayerHpLow);
        PlayerHP3.setLeft(Attack);
        PlayerHP3.setRight(isPlayerBlocking);

        DecisionTree EnemyHP = new DecisionTree();
        EnemyHP.setDecision(d_isHpLow);
        EnemyHP.setLeft(PlayerHP2);
        EnemyHP.setRight(PlayerHP3);

        DecisionTree GettingAttacked2 = new DecisionTree();
        GettingAttacked2.setDecision(d_isPlayerAttacking);
        GettingAttacked2.setLeft(RandomAction);
        GettingAttacked2.setRight(EnemyHP);

        

        //Random Action Trees
        DecisionTree Random01 = new DecisionTree();
        Random01.setDecision(d_randomDecision75);
        Random01.setLeft(PlayerHP);
        Random01.setRight(RandomAction);

        //Random Action Trees
        DecisionTree Random02 = new DecisionTree();
        Random02.setDecision(d_randomDecision75);
        Random02.setLeft(GettingAttacked2);
        Random02.setRight(RandomAction);


        DecisionTree Aggressiveness = new DecisionTree();
        Aggressiveness.setDecision(d_isPlayerAggresive);
        Aggressiveness.setLeft(Random01);
        Aggressiveness.setRight(Random02);

        DecisionTree IsPlayerTooClose = new DecisionTree();
        IsPlayerTooClose.setDecision(d_isPlayerTooClose);
        IsPlayerTooClose.setLeft(MoveToPlayer);
        IsPlayerTooClose.setRight(MoveAway);

        root.setDecision(d_inAttackRange);
        root.setLeft(Aggressiveness);
        root.setRight(IsPlayerTooClose);

    }


}