using UnityEngine;

public class MovementController : MonoBehaviour
{
    [HideInInspector]
    public Entity entity;
    public bool automaticCrouch = false;

    // For non-player
    public static int mask = ~(27 << 9);
    protected Transform target;
    protected MovementController targetController;
    protected Vector3 lastTargetPosition;
    protected float distance;
    protected Vector3 addVec;
    protected Vector3 realAddVec;

    protected float randNum = 0.0f;

    protected virtual void GenRandNum() {

    }

    protected void UpdateDistance() {
        if (target != null) {
            Vector3 ortar = target.transform.position + realAddVec / 2;
            if (entity != null && entity.lookingTarget != null) {
                ortar = target.transform.position + (transform.forward * 0.3f);
            }
            ortar = new Vector3(ortar.x, transform.position.y, ortar.z);
            distance = Vector3.Distance(ortar, transform.position);
            if (distance > 1) {
                distance = distance * distance;
            }
            //Debug.Log(distance);
        }
    }

    protected void MoveTowardsPlayer(Transform[] targets, float widenessFactor) {
        int randInd = Random.Range(0, targets.Length);
        //randNum = (Random.value-0.5f)*2;
        bool canMove = !ScriptedScene.talking;
        if (GameInputManager.main != null) {
            canMove = canMove && GameInputManager.main.isControllable;
            //Debug.Log("Can I move? "+canMove);
        }
        if (widenessFactor < 0.1) {
            widenessFactor = 0.1f;
        }
        if (Random.value > 0.5f / widenessFactor && canMove) {
            addVec = (new Vector3((Random.value - 0.5f) * 2, 0, (Random.value - 0.5f) * 2) * widenessFactor);
        }
        else {
            addVec = new Vector3(0, 0, 0);
        }
        if (targets.Length > 0 && targets[0] != null) {
            if (canMove) {
                randNum = Random.Range(0.5f, 2.0f);
                MovementController movementController = targets[randInd].GetComponent<MovementController>();
                Vector3 targetHeadPos = targets[randInd].position + new Vector3(0, 1.0f, 0);
                if (targetController != null && targetController.entity != null) {
                    targetHeadPos = targetController.entity.head.position;
                }
                if (!Physics.Linecast(entity.head.position, targetHeadPos /*+ realAddVec*/, mask)) {
                    target = targets[randInd];
                    targetController = target.GetComponent<MovementController>();
                }
            }
            else {
                target = targets[0];
                targetController = target.GetComponent<MovementController>();
            }
        }
    }

    protected void CheckPath() {
        if (target != null) {
            Vector3 targetHeadPos = target.position + new Vector3(0, 1.0f, 0);
            RaycastHit hit = new RaycastHit();
            if (targetController != null) {
                targetHeadPos = targetController.entity.head.position;
            }
            if (entity.parameters.following && !Physics.Linecast(entity.head.position, targetHeadPos + realAddVec, out hit, mask)) {
                lastTargetPosition = target.position + realAddVec;
            }
            else if (entity.parameters.following && !Physics.Linecast(entity.head.position, targetHeadPos, out hit, mask)) {
                lastTargetPosition = target.position;
            }
        }
    }

    protected void MoveRandomly() {
        randNum = (Random.value - 0.5f) * 2;
        if (!entity.fighting && entity.isAlive()) {
            lastTargetPosition = transform.position + new Vector3(Random.Range(-5.0f, 5.0f), 0, Random.Range(-5.0f, 5.0f));
        }
        addVec = new Vector3(0, 0, 0);
    }

    protected void AutomaticCrouch(Animator animator) {
        bool crouching = false;
        if (automaticCrouch && !entity.fighting) {
            Collider[] colliders = Physics.OverlapSphere(transform.position + new Vector3(0.0f, 0.85f, 0.0f), 0.33f, MovementController.mask, QueryTriggerInteraction.Ignore);
            foreach (Collider c in colliders) {
                if (c.gameObject != this.gameObject) {
                    crouching = true;
                    break;
                }
            }
        }
        animator.SetBool("Crouching", crouching);
    }
}
