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

public class PawnController : MonoBehaviour, IPooledObject{

    [Range(1, 5)] [SerializeField] int framesToMove = 1;
    int currentFrame = 1;
    bool moving;

    [Space]
    [Range(0, .3f)] [SerializeField] float movementSmoothingTime = .1f;
    [SerializeField] LayerMask whatIsEnemy;
    [SerializeField] LayerMask whatIsPlayer;

    Vector3[] possiblePositions;
    Vector3[] availablePositions;
    Vector3 playerKillPosition;
    public Vector3 positionToGo;
    Vector3 currentPosition;
    Vector3 velocity;

    Transform player;

    void Awake(){
        player = FindObjectOfType<PlayerController>().transform;
        FindObjectOfType<PlayerController>().onMove.AddListener(() => Move());
    }

    // Start is called before the first frame update
    public void OnObjectSpawn(){
        positionToGo = currentPosition = transform.position;
        currentFrame = 1;
        moving = false;
    }

    // Update is called once per frame
    void Update(){
        if (Vector3.Distance(transform.position, positionToGo) > .1f){
            transform.position = Vector3.SmoothDamp(transform.position, positionToGo, ref velocity, movementSmoothingTime);
        }else if (Vector3.Distance(transform.position, positionToGo) < .1f){
            transform.position = positionToGo;
        }
    }

    void OnDrawGizmos(){
        if (!Application.isPlaying){
            Gizmos.color = Color.cyan;
            Gizmos.DrawSphere(transform.position + Vector3.right * 1.25f, .15f);
            Gizmos.DrawSphere(transform.position + Vector3.left * 1.25f, .15f);
            Gizmos.DrawSphere(transform.position + Vector3.forward * 1.25f, .15f);
            Gizmos.DrawSphere(transform.position + Vector3.back * 1.25f, .15f);

            Gizmos.color = Color.red;
            Gizmos.DrawWireSphere(transform.position + new Vector3(1.25f, 0, 1.25f), .3f);
            Gizmos.DrawWireSphere(transform.position + new Vector3(-1.25f, 0, 1.25f), .3f);
            Gizmos.DrawWireSphere(transform.position + new Vector3(1.25f, 0, -1.25f), .3f);
            Gizmos.DrawWireSphere(transform.position + new Vector3(-1.25f, 0, -1.25f), .3f);
        }
    }

    void Move(){
        if(currentFrame < framesToMove){
            currentFrame++;
            moving = false;
            return;
        }
        currentFrame = 1;
        moving = true;
        if (gameObject.activeSelf){
            StartCoroutine(ResetMoving());
        }

        currentPosition = positionToGo;

        possiblePositions = new Vector3[4];
        possiblePositions[0] = currentPosition + Vector3.right * 1.25f;
        possiblePositions[1] = currentPosition + Vector3.left * 1.25f;
        possiblePositions[2] = currentPosition + Vector3.forward * 1.25f;
        possiblePositions[3] = currentPosition + Vector3.back * 1.25f;

        availablePositions = new Vector3[4];
        if(!Physics.CheckSphere(possiblePositions[0], .3f, whatIsEnemy) && !Physics.CheckSphere(possiblePositions[0], .3f, whatIsPlayer)){
            availablePositions[0] = possiblePositions[0];
        }
        if (!Physics.CheckSphere(possiblePositions[0], .3f, whatIsEnemy) && !Physics.CheckSphere(possiblePositions[0], .3f, whatIsPlayer)){
            availablePositions[1] = possiblePositions[1];
        }
        if (!Physics.CheckSphere(possiblePositions[0], .3f, whatIsEnemy) && !Physics.CheckSphere(possiblePositions[0], .3f, whatIsPlayer)){
            availablePositions[2] = possiblePositions[2];
        }
        if (!Physics.CheckSphere(possiblePositions[0], .3f, whatIsEnemy) && !Physics.CheckSphere(possiblePositions[0], .3f, whatIsPlayer)){
            availablePositions[3] = possiblePositions[3];
        }

        if (Physics.CheckSphere(currentPosition + new Vector3(1.25f, 0, 1.25f), .3f, whatIsPlayer)){
            playerKillPosition = currentPosition + new Vector3(1.25f, 0, 1.25f);
        }
        if (Physics.CheckSphere(currentPosition + new Vector3(-1.25f, 0, 1.25f), .3f, whatIsPlayer)){
            playerKillPosition = currentPosition + new Vector3(-1.25f, 0, 1.25f);
        }
        if (Physics.CheckSphere(currentPosition + new Vector3(1.25f, 0, -1.25f), .3f, whatIsPlayer)){
            playerKillPosition = currentPosition + new Vector3(1.25f, 0, -1.25f);
        }
        if (Physics.CheckSphere(currentPosition + new Vector3(-1.25f, 0, -1.25f), .3f, whatIsPlayer)){
            playerKillPosition = currentPosition + new Vector3(-1.25f, 0, -1.25f);
        }

        if(playerKillPosition == Vector3.zero){
            float nearestDist = float.MaxValue;
            Vector3 nearestPos = new Vector3();

            foreach (Vector3 v in availablePositions){
                if (v != Vector3.zero){
                    float dist = Vector3.Distance(v, player.position);
                    if (dist < nearestDist){
                        nearestDist = dist;
                        nearestPos = v;
                    }
                }
            }

            positionToGo = (nearestPos == Vector3.zero) ? currentPosition : nearestPos;
        }else{
            positionToGo = playerKillPosition;
            playerKillPosition = Vector3.zero;
        }
    }

    IEnumerator ResetMoving(){
        yield return new WaitForSeconds(movementSmoothingTime * 3);
        moving = false;
    }

    void OnTriggerEnter(Collider col){
        if (col.CompareTag("Limits")){
            positionToGo = currentPosition;
        }
    }

    void OnCollisionEnter(Collision col){
        if (col.gameObject.layer == Mathf.RoundToInt(Mathf.Log(whatIsEnemy.value, 2))){
            BishopController bishop = col.gameObject.GetComponent<BishopController>();
            KnightController knight = col.gameObject.GetComponent<KnightController>();
            PawnController pawn = col.gameObject.GetComponent<PawnController>();
            RookController rook = col.gameObject.GetComponent<RookController>();
            if (bishop != null){
                if (bishop.positionToGo == positionToGo){
                    if (Vector3.Distance(transform.position, positionToGo) > Vector3.Distance(col.transform.position, bishop.positionToGo)){
                        positionToGo = currentPosition;
                    }
                }
            }else if (knight != null){
                if (knight.positionToGo == positionToGo){
                    if (Vector3.Distance(transform.position, positionToGo) > Vector3.Distance(col.transform.position, knight.positionToGo)){
                        positionToGo = currentPosition;
                    }
                }
            }else if (pawn != null){
                if (pawn.positionToGo == positionToGo){
                    if (Vector3.Distance(transform.position, positionToGo) > Vector3.Distance(col.transform.position, pawn.positionToGo)){
                        positionToGo = currentPosition;
                    }
                }
            }else if (rook != null){
                if (rook.positionToGo == positionToGo){
                    if (Vector3.Distance(transform.position, positionToGo) > Vector3.Distance(col.transform.position, rook.positionToGo)){
                        positionToGo = currentPosition;
                    }
                }
            }
        }

        if (col.gameObject.tag == "Player"){
            PlayerController player = col.gameObject.GetComponent<PlayerController>();
            if(player.positionToGo == positionToGo && moving){
                player.Damage();
                positionToGo = currentPosition;
            }
        }
    }
}
