using HPJ.Presentation.Agents;
using HPJ.Simulation;
using HPJ.Simulation.Map;
using System.Collections;
using UnityEngine;

namespace HPJ.Presentation.Sample
{
    /// <summary>
    /// The all round example scene script
    /// </summary>
    public class SampleSceneScript : MonoBehaviour
    {
        [SerializeField]
        private int _agentSpawnCount = 100;
        [SerializeField]
        private NavigationAgent TestAgents;
        [SerializeField]
        private bool _rollOutSlow = false;
        [SerializeField]
        private bool _closeRangeRandomPosition = false;
        [SerializeField]
        private int _closeRangeRadius = 50;
        [SerializeField]
        private bool _keepAgentsOnSameMap = false;

        private void Start()
        {
            if (_rollOutSlow)
            {
                StartCoroutine(RollOutSlow());
            }
            else
            {
                StartCoroutine(RollOut());
            }
        }

        private IEnumerator RollOutSlow()
        {
            while (NavigationManager.Instance == null)
            {
                yield return null;
            }

            while (!NavigationManager.Instance.Initialized)
            {
                yield return null;
            }

            yield return null;

            for (int i = 0; i < _agentSpawnCount; i++)
            {
                Vector3 RandomPosition = NavigationManager.Instance.GetRandomValidPosition(TestAgents.TraversableTiles, true);
                NavigationAgent Agent = Instantiate(TestAgents, RandomPosition, Quaternion.identity);
                Agent.transform.SetParent(transform);
                Agent.OnMovingComplete.AddListener(SetRandomDestination);
                Agent?.GroundCast?.TeleportUp();
                Vector3 RandomDestination;
                if (_closeRangeRandomPosition)
                {
                    IntVector3 RandomPosition_WorldIndex = NavigationManager.Instance.GetTileWorldPosition(RandomPosition);
                    MapSet map = NavigationManager.Instance.GetCurrentMap(RandomPosition);
                    RandomDestination = NavigationManager.Instance.GetRandomValidPositionAtPosition(Agent.TraversableTiles, NavigationManager.Instance.GetTileIndexForMap(RandomPosition_WorldIndex, map), _closeRangeRadius, true);
                }
                else
                {
                    if (_keepAgentsOnSameMap)
                    {
                        MapSet map = NavigationManager.Instance.GetCurrentMap(RandomPosition);
                        Agent.SetCurrentMap(map);
                        RandomDestination = NavigationManager.Instance.GetRandomValidPosition(Agent.TraversableTiles, map, true);
                    }
                    else
                    {
                        RandomDestination = NavigationManager.Instance.GetRandomValidPosition(Agent.TraversableTiles, true);
                    }
                }
                Agent.SetDestination(RandomDestination);
                yield return null;
                yield return null;
            }
            enabled = false;
        }

        private IEnumerator RollOut()
        {
            while (NavigationManager.Instance == null)
            {
                yield return null;
            }

            while (!NavigationManager.Instance.Initialized)
            {
                yield return null;
            }

            yield return null;

            for (int i = 0; i < _agentSpawnCount; i++)
            {
                Vector3 RandomPosition = NavigationManager.Instance.GetRandomValidPosition(TestAgents.TraversableTiles, true);
                NavigationAgent Agent = Instantiate(TestAgents, RandomPosition, Quaternion.identity);
                Agent.OnMovingComplete.AddListener(SetRandomDestination);
                Agent?.GroundCast?.TeleportUp();
                Vector3 RandomDestination;
                if (_closeRangeRandomPosition)
                {
                    IntVector3 RandomPosition_WorldIndex = NavigationManager.Instance.GetTileWorldPosition(RandomPosition);
                    MapSet map = NavigationManager.Instance.GetCurrentMap(RandomPosition);
                    RandomDestination = NavigationManager.Instance.GetRandomValidPositionAtPosition(Agent.TraversableTiles, NavigationManager.Instance.GetTileIndexForMap(RandomPosition_WorldIndex, map), _closeRangeRadius, true);
                }
                else
                {
                    if (_keepAgentsOnSameMap)
                    {
                        MapSet map = NavigationManager.Instance.GetCurrentMap(RandomPosition);
                        Agent.SetCurrentMap(map);
                        RandomDestination = NavigationManager.Instance.GetRandomValidPosition(Agent.TraversableTiles, map, true);
                    }
                    else
                    {
                        RandomDestination = NavigationManager.Instance.GetRandomValidPosition(Agent.TraversableTiles, true);
                    }
                }
                Agent.SetDestination(RandomDestination);
            }
            enabled = false;
        }

        private void SetRandomDestination(NavigationAgent Agent)
        {
            Vector3 RandomDestination;
            if (_closeRangeRandomPosition)
            {
                IntVector3 RandomPosition_WorldIndex = NavigationManager.Instance.GetTileWorldPosition(transform.position);
                MapSet map = NavigationManager.Instance.GetCurrentMap(transform.position);
                RandomDestination = NavigationManager.Instance.GetRandomValidPositionAtPosition(Agent.TraversableTiles, NavigationManager.Instance.GetTileIndexForMap(RandomPosition_WorldIndex, map), _closeRangeRadius, true);
            }
            else
            {
                if (_keepAgentsOnSameMap)
                {
                    RandomDestination = NavigationManager.Instance.GetRandomValidPosition(Agent.TraversableTiles, Agent.StartingMap, true);
                    //Debug.Log($"Random Destination {RandomDestination}");
                }
                else
                {
                    RandomDestination = NavigationManager.Instance.GetRandomValidPosition(Agent.TraversableTiles, true);
                }
            }
            Agent.SetDestination(RandomDestination);
        }
    }
}