using JetBrains.Annotations;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.CompilerServices;
using Unity.VisualScripting;
using UnityEngine;
using static EnemySpawnerData;
using static UnityEngine.EventSystems.EventTrigger;



public class SpawnableEnemyInfo : MonoBehaviour {
  public static SpawnableEnemyInfo Instance;
  public static Action UpdateTick;
  public static Action GizmoTick;
  public static float SpawnIntervalInSeconds = 10;
  public static float NextSpawnableTime = 0;

  [SerializeField] public List<EnemySpawnInfo> SpawnableEnemies;

  public void Awake() {
    if (Instance != null && Instance != this) {
      Destroy(gameObject);
      return;
    }

    Instance = this;
    Owner = this.GameObject();
    RestartData();
    for (int i = 0; i < SpawnableEnemies.Count; i++) SpawnableEnemies[i] = Instantiate(SpawnableEnemies[i]);
    foreach (var enemy in SpawnableEnemies) InitializeEnemyData(enemy);
  }

  public static void DestroyEnemy(GameObject gameObject, Enemies enemy) {
    Destroy(gameObject);
    EnemySpawnerData.SpawnableEnemies[enemy].CurrentSpawnCount--;
  }

  public void Update() {
    StartSpawning();
    UpdateTick?.Invoke();
  }

  public void StartSpawning() {
    if (NextSpawnableTime > Time.time) return;
    NextSpawnableTime = Time.time + SpawnIntervalInSeconds;

    foreach (var enemy in SpawnableEnemies) {
      int currentSpawnCount = 0;
      while (enemy.CanStartSpawning && enemy.CurrentSpawnCount < enemy.MaxSpawnCount && currentSpawnCount++ < enemy.MaxCountPerSpawn) {
        var enemyObject = EnemyGameObjectPools[enemy.Type].Get(transform.position, Quaternion.identity);
        var enemyScript = new Gobler(enemyObject);
        EnemyMap.Add(enemyObject, enemyScript);
        enemy.CurrentSpawnCount++;
      }
    }
  }




  public void OnDrawGizmos() {
    GizmoTick?.Invoke();
  }

  public static void DrawWireSphere(Color color, Vector3 center, float radius) {
    Gizmos.color = color;
    Gizmos.DrawWireSphere(center, radius);
  }
}



public class EnemyManager : MonoBehaviour {
  public Action UpdateTick;
  public Action GizmoTick;

  public void Update() {
    UpdateTick?.Invoke();
  }

  public void OnDrawGizmos() {
    GizmoTick?.Invoke();
  }

  public void DrawWireSphere(Color color, Vector3 center, float radius) {
    Gizmos.color = color;
    Gizmos.DrawWireSphere(center, radius);
  }
}



public static class EnemySpawnerData {
  public enum Enemies {
    Gobler,
  }

  public static GameObject Owner;
  public static Dictionary<Enemies, EnemySpawnInfo> SpawnableEnemies = new Dictionary<Enemies, EnemySpawnInfo>();
  public static Dictionary<Enemies, GameObject> ObjectPrefabs = new Dictionary<Enemies, GameObject>();
  public static Dictionary<Enemies, GameObjectPool> EnemyGameObjectPools = new Dictionary<Enemies, GameObjectPool>();
  public static Dictionary<Enemies, EnemyManager> EnemyManagers = new Dictionary<Enemies, EnemyManager>();
  public static Dictionary<Enemies, int> MaxSpawnCount = new Dictionary<Enemies, int>();
  public static Dictionary<Enemies, int> CurrentSpawnCount = new Dictionary<Enemies, int>();
  public static Dictionary<GameObject, Enemy> EnemyMap = new Dictionary<GameObject, Enemy>();

  public static void RestartData() {
    ObjectPrefabs = new Dictionary<Enemies, GameObject>();
    EnemyGameObjectPools = new Dictionary<Enemies, GameObjectPool>();
    EnemyManagers = new Dictionary<Enemies, EnemyManager>();
    MaxSpawnCount = new Dictionary<Enemies, int>();
    CurrentSpawnCount = new Dictionary<Enemies, int>();
    EnemyMap = new Dictionary<GameObject, Enemy>();
  }

  public static void InitializeEnemyData(EnemySpawnInfo enemy) {
    SpawnableEnemies.Add(enemy.Type, enemy);
    EnemyGameObjectPools.Add(enemy.Type, new GameObjectPool(enemy.Prefab, 50, 200));
    EnemyManagers.Add(enemy.Type, Owner.AddComponent<EnemyManager>());
    MaxSpawnCount.Add(enemy.Type, 0);
    CurrentSpawnCount.Add(enemy.Type, 0);
  }
}

