namespace Scripts.Routes
{
    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    using Scripts.Waypoints;
    using Scripts.IA;
    using Mapbox.Utils;
    using Mapbox.Unity.Map;

    //! @authors MrWarzo
    //!     Wakestufou
    //! @brief Trace la route entre le départ et l'arrivée.
    //! @details Récupère tout les points formants un chemin entre le départ et l'arrivée et crée une ligne visible en jeu pour le représenter.
    public class RouteTracer : MonoBehaviour
    {
        // Champs publiques
        public Material mat; //!< Matériaux de la ligne.
        public Transform linesParent; //!< @b GameObject contenant tout les morceaux de ligne.

        // Champs privés
        private List<GameObject> _waypoints; //!< Liste de tout les waypoints par lesquels la ligne doit passer.
        [SerializeField] Vector3 _startObject; //!< @b GameObject de début de la ligne. 
        [SerializeField] Vector3 _finishObject; //!< @b GameObject de fin de la ligne.
        private AbstractMap _map;

        //! @brief Se lance au lancement du script.
        //! @details Initialise une coroutine sur @b CreateLine().
        private void Start()
        {
            _map = GameObject.Find("Map").GetComponent<AbstractMap>();
            CreateLine();
        }

        //! @brief Création d'une ligne entre deux @b GameObject
        //! @details Récupère les waypoints de départ et d'arrivée et utilise le script @b Waypoints.WaypointsFactory afin de récupérer la liste des points suivant les routes réelles.
        //!     Lance ensuite la fonction @b DrawLine(Vector3, Vector3, Color, float) avec en paramètre des couples de cette liste de manière à tracer une ligne complète suivant les étapes entre le départ et l'arrivée.
        //!     Une fois la ligne entière terminée, active la @b IA.RunnersFactory puis arrête la coroutine.
        //! @return @eIEnumerator Permet d'assigner un délai à la répétition de la coroutine.
        void CreateLine()
        {
            _waypoints = SpawnOnMap.getInstance().getSpawnedObject();

            for (int i = 0; i < _waypoints.Count - 1; i++)
            {

                _startObject = _waypoints[i].transform.position;
                _finishObject = _waypoints[i + 1].transform.position;
                 DrawLine(_startObject, _finishObject, Color.cyan, 1f);
            }

     

                GameObject.Find("Player").transform.position =
                new Vector3(
                     (float)((_waypoints[0].transform.position.x + _waypoints[_waypoints.Count - 1].transform.position.x) / 2d),
                     GameObject.Find("Player").transform.position.y,
                     (float)((_waypoints[0].transform.position.z + _waypoints[_waypoints.Count - 1].transform.position.z) / 2d)// + 19f
                    );



                GameObject.Find("Sportifs").GetComponent<RunnersFactory>().enabled = true;
        }

        //! @param start Position du @b GameObject de départ.
        //! @param end Position du @b GameObject d'arrivée.
        //! @param color Couleur de la ligne.
        //! @param width Largeur de la ligne.
        //! @brief Crée une ligne entre deux @b GameObject.
        //! @details Crée un @b GameObject, lui assigne un  @b LineRenderer et initialise celui-ci pour rejoindre les objets @a start et @a end afin de former une ligne.
        void DrawLine(Vector3 start, Vector3 end, Color color, float width)
        {
            GameObject myLine = new GameObject();
            myLine.transform.position = start;
            myLine.AddComponent<LineRenderer>();
            myLine.transform.parent = linesParent;
            LineRenderer lr = myLine.GetComponent<LineRenderer>();
            lr.material = mat;
            lr.startColor = color;
            lr.endColor = color;
            lr.startWidth = width;
            lr.endWidth = width;
            lr.SetPosition(0, start + Vector3.up);
            lr.SetPosition(1, end + Vector3.up);
        }
    }
}