using System.Collections;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
using UnityEngine.UI;

public class EnemySpawnManager : MonoBehaviour
{
    public int WaveNum = 0;

    public bool HasStarted = false;
    public bool IsAutoPlaying = false;

    private float time = 0f;
    [SerializeField] private LevelDefinition levelDefinition;
    [SerializeField] private EnemyCollection enemyCollection;

    [SerializeField] private WaypointPath groundPath;
    [SerializeField] private WaypointPath skyPath;

    [Header("Buttons")]

    [SerializeField] private Button PlayButton;
    [SerializeField] private Button AutoPlayButton;

    private Queue<Wave> waveQueue;
    private List<GameObject> SpawnedEnemies = new();

    public static EnemySpawnManager Instance;

    private void Awake()
    {
        if (Instance != null)
            Destroy(Instance);
        Instance = this;

        waveQueue = new Queue<Wave>(levelDefinition.Waves);

        if (PlayButton != null)
            PlayButton.onClick.AddListener(OnPlayButtonClicked);
        if (AutoPlayButton != null)
            AutoPlayButton.onClick.AddListener(ToggleAutoPlayClicked);
    }

    public void OnPlayButtonClicked()
    {
        if (GameManager.Instance.CurrentNumEnemies != 0) return;

        HasStarted = true;
        PopWave();
    }

    public void ToggleAutoPlayClicked()
    {
        IsAutoPlaying = !IsAutoPlaying;
    }

    void Update()
    {
        if (HasStarted && IsAutoPlaying)
            time += Time.deltaTime;

        if (waveQueue.Count > 0 && (GameManager.Instance.CurrentNumEnemies == 0 && IsAutoPlaying))
        {
            PopWave();
        }

        // Removes all null from list
        for (int i = 0; i < SpawnedEnemies.Count; i++)
        {
            if (SpawnedEnemies[i] == null)
                SpawnedEnemies.Remove(SpawnedEnemies[i]);
        }

        // Updates the state of a round
        GameManager.Instance.CurrentNumEnemies = SpawnedEnemies.Count;
    }

    void PopWave()
    {
        if (waveQueue.Count <= 0)
            return;


        time = 0;
        WaveNum++;

        Wave spawnWave = waveQueue.Dequeue();
        for (int i = 0; i < spawnWave.groups.Length; i++)
        {
            var group = spawnWave.groups[i];
            StartCoroutine(StartSpawnGroup(group));
        }
    }

    IEnumerator StartSpawnGroup(SpawnGroup group)
    {
        for (int i = 0; i < group.num; i++)
        {
            EnemyInfo enemyInfo = enemyCollection.Enemies[group.enemyIndex];

            GameObject spawned = Instantiate(enemyInfo.prefab);
            WaypointEntityData data = new WaypointEntityData(spawned.transform, enemyInfo.moveSpeed, enemyInfo.feetOffset, enemyInfo.damage);

            if (enemyInfo.FlyPath)
            {
                spawned.transform.position = skyPath.Waypoints.First().position;
                skyPath.AddObjectToPath(data);
            }
            else
            {
                spawned.transform.position = groundPath.Waypoints.First().position;
                groundPath.AddObjectToPath(data);
            }

            SpawnedEnemies.Add(spawned);

            yield return new WaitForSecondsRealtime(group.spawnInterval);
        }
    }
}