using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Random = UnityEngine.Random;

public class WaypointSystem : MonoBehaviour
{
    [SerializeField] private Waypoint[] waypoints;
    [SerializeField] private Color gizmosColour = Color.cyan;
    [SerializeField] private Color gizmosColourTurnDistMin = Color.blue;
    [SerializeField] private Color gizmosColourTurnDistMax = Color.magenta;
    [SerializeField] private bool circularPath = false;
    [SerializeField] private bool stand = false;
    private int m_waypointIndex = 0;
    private bool m_goBackwards = false;
    private bool m_stoppedMoving = false;
    public event Action onCanMove;
    public event Action onStopMove;
    private float m_distanceToTarget = 2f;
    private Timer m_pointTimer;
    private Vision m_vision;
    private bool m_canMove = true;
    
    // Start is called before the first frame update
    void Start()
    {
        m_pointTimer = new Timer(waypoints[m_waypointIndex].waitTime, Time.time);
        m_vision = transform.GetComponent<Vision>();
        m_vision.onFoundPlayer += OnFoundPlayerResponse;
        for (int i = 0; i < waypoints.Length; i++)
        {
            if (waypoints[i].turnDistanceMin <= 0)
                waypoints[i].turnDistanceMin = 2f;
            if (waypoints[i].turnDistanceMax <= 0)
                waypoints[i].turnDistanceMax = 4f;
            if (waypoints[i].waypointTransform != null)
            {
                waypoints[i].waypointTransform.position = new Vector3(waypoints[i].waypointTransform.position.x,
                    transform.position.y, waypoints[i].waypointTransform.position.z);
            }
        }

    }
    
    void OnFoundPlayerResponse()
    {
        m_canMove = false;
    }
    
    private void OnDisable()
    {
        m_vision.onFoundPlayer -= OnFoundPlayerResponse;
    }
    
    private void OnDestroy()
    {
        m_vision.onFoundPlayer -= OnFoundPlayerResponse;
    }

    private void OnValidate()
    {
        for (int i = 0; i < waypoints.Length; i++)
        {
            if (waypoints[i].turnDistanceMin <= 0)
                waypoints[i].turnDistanceMin = 2f;
            if (waypoints[i].turnDistanceMax <= 0)
                waypoints[i].turnDistanceMax = 4f;
            
            if (waypoints[i].waypointTransform != null)
            {
                waypoints[i].waypointTransform.position = new Vector3(waypoints[i].waypointTransform.position.x,
                    transform.position.y, waypoints[i].waypointTransform.position.z);
            }
        }
    }

    public Transform GetWayPointTransform()
    {
        return waypoints[m_waypointIndex].waypointTransform;
    }
    
    // Update is called once per frame
    void Update()
    {
        if(waypoints == null || !m_canMove)
            return;

        if (stand)
        {
            onStopMove?.Invoke();
            return;
        }

        if (m_pointTimer.IsFinished())
        {
            onCanMove?.Invoke();
            m_stoppedMoving = false;
        }

        CheckWayPointDistance();
    }

    void CheckWayPointDistance()
    {
        if(m_distanceToTarget == 0)
        {
            m_distanceToTarget = Random.Range(waypoints[m_waypointIndex].turnDistanceMin,
            waypoints[m_waypointIndex].turnDistanceMax);
        }
        
        if (Vector3.Distance(transform.position, waypoints[m_waypointIndex].waypointTransform.position) <=
            m_distanceToTarget && !m_stoppedMoving)
        {
            m_pointTimer = new Timer(waypoints[m_waypointIndex].waitTime, Time.time);
            CheckDiraction();
            ChangeIndex();
            onStopMove?.Invoke();
            m_stoppedMoving = true;
            m_distanceToTarget = 0;
        }
    }

    void ChangeIndex()
    {
        if (m_goBackwards)
        {
            if (circularPath)
            {
                m_waypointIndex = 0;
                m_goBackwards = false;
            }
            else
            {
                m_waypointIndex--;
            }

        }
        else
        {
            m_waypointIndex++;
        }
    }

    void CheckDiraction()
    {
        if (m_waypointIndex >= waypoints.Length - 1)
            m_goBackwards = true;
        else if(m_waypointIndex <= 0)
            m_goBackwards = false;
    }

    private void OnDrawGizmos()
    {
        if(waypoints == null)
            return;
        if (waypoints.Length <= 0)
            return;

        Gizmos.color = gizmosColour;
        for (int i = 0; i < waypoints.Length; i++)
        {
            if (waypoints[i].waypointTransform != null)
            {
                Gizmos.color = gizmosColourTurnDistMin;
                Gizmos.DrawWireSphere(waypoints[i].waypointTransform.position, waypoints[i].turnDistanceMin);
                Gizmos.color = gizmosColourTurnDistMax;
                Gizmos.DrawWireSphere(waypoints[i].waypointTransform.position, waypoints[i].turnDistanceMax);
                Gizmos.color = gizmosColour;
                Gizmos.DrawWireSphere(waypoints[i].waypointTransform.position, 0.2f);
                if (i < waypoints.Length - 1)
                {
                    if(!(waypoints[i].waypointTransform.position == waypoints[i + 1].waypointTransform.position))
                        Gizmos.DrawLine(waypoints[i].waypointTransform.position, waypoints[i + 1].waypointTransform.position);
                }
                else if (circularPath)
                {
                    if(!(waypoints[i].waypointTransform.position == waypoints[0].waypointTransform.position))
                        Gizmos.DrawLine(waypoints[i].waypointTransform.position, waypoints[0].waypointTransform.position);
                }
            }
        }
    }
}
