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

public class LevelManager : Simpleton<LevelManager> {

    public GameObject Floor;

    public GameObject ExplosionPrefab;
    public GameObject EnemyDeathPrefab;

    public GameObject LevelCompletePanel;
    public AudioClip LevelCompleteSound;

    public AudioClip Awa;

    public int InitialHearts;
    public GameObject HealthBar;
    public GameObject HeartPrefab;
    private List<GameObject> hearts;

    public List<EnemyGroup> Enemies;

    public List<Level> Levels;

    public void Awake() {
        InitializeHearts();
    }

    private void InitializeHearts() {
        this.hearts = new List<GameObject>();
        for (int i = 0; i < InitialHearts; i++) {
            Invoke("InstantiateHeart", .2f * (i + 1));
        }
    }

    public void LoseHeart() {
        GameObject.Destroy(this.hearts[0]);  // Remove heart.
        hearts.RemoveAt(0);
        if (hearts.Count == 0) {
            GameOver();
        }
    }

    private void InstantiateHeart() {
        var heart = Instantiate(HeartPrefab, HealthBar.transform, false);
        this.hearts.Add(heart);
    }

    public List<EnemySpawn> GetLevelEnemies(int levelIndex) {
        var enemies = new List<EnemySpawn>();
        float time = 0;
        foreach (var wave in Levels[PlayerPrefs.GetInt("CurrentLevel", 0)].Waves) {
            var enemyOptions = Enemies[wave.EnemyIndex];
            for (int i = 0; i < wave.Count; i++) {
                var enemy = enemyOptions.Enemies[UnityEngine.Random.Range(0, enemyOptions.Enemies.Count)];
                enemies.Add(new EnemySpawn(enemy, wave.BattleCry, time));
                time += wave.SpawnEvery;
            }
        }
        return enemies;
    }

    private void GameOver() {
        SceneManager.LoadScene("GameOver");
    }

    public void LevelComplete() {
        Debug.Log("LevelComplete");
        PlayerPrefs.SetInt("CurrentLevel", (PlayerPrefs.GetInt("CurrentLevel") + 1) % LevelManager.Instance.Levels.Count);
        LevelCompletePanel.SetActive(true);
        AudioSource.PlayClipAtPoint(LevelCompleteSound, transform.position);  // Level Complete sound.
        Invoke("GoToNextLevel", 2);
	}

    private void GoToNextLevel() {
        SceneManager.LoadScene("Main");
    }
}

[System.Serializable]
public class EnemyGroup {
    public string Name;
    public List<GameObject> Enemies;

    public EnemyGroup(string name, List<GameObject> enemies) {
        Name = name;
        Enemies = enemies;
    }
}

[System.Serializable]
public class Level {
    public List<Wave> Waves;

    public Level(List<Wave> waves) {
        Waves = waves;
    }
}

[System.Serializable]
public class Wave {
    public string Name;
    public int EnemyIndex;
    public int Count;
    public float SpawnEvery;
    public AudioClip BattleCry;

    public Wave(string name, int enemyIndex, int count, float spawnEvery, AudioClip battleCry) {
        Name = name;
        EnemyIndex = enemyIndex;
        Count = count;
        SpawnEvery = spawnEvery;
        BattleCry = battleCry;
    }
}

public class EnemySpawn {
    public GameObject Enemy { get; private set; }
    public AudioClip BattleCry { get; private set; }
    public float SpawnAfter { get; private set; }

    public EnemySpawn(GameObject enemy, AudioClip battleCry, float spawnAfter) {
        Enemy = enemy;
        BattleCry = battleCry;
        SpawnAfter = spawnAfter;
    }
}