using TMPro;
using UnityEditor;
using UnityEngine;

public enum GameState
{
  START_MENU,
  GAME_RUNNING,
  END_MENU
}


public class GameManager : MonoBehaviour
{

  private GameState gameState;

  public float gameDuration = 30;
  private float timeRemaining;
  public GameObject player;

  public GameObject startMenu;
  public GameObject gameHud;
  public GameObject endMenu;


  //game
  public int numberOfEnemies = 3;
  public GameObject enemyPrefab;
  public int enemyMinPoint = 100;
  public int enemyMaxPoint = 150;

  public float minSpawnDistance = 0.5f;
  public float maxSpawnDistance = 1f;


  private float points = 0;
  public TextMeshProUGUI pointHud;
  public TextMeshProUGUI timerHud;

  //end game
  public TextMeshProUGUI endPointHud;


  // Start is called once before the first execution of Update after the MonoBehaviour is created
  void Start()
  {
    SetStartMenu();
  }

  // Update is called once per frame
  void Update()
  {
    switch (gameState)
    {
      case GameState.START_MENU:


        break;
      case GameState.GAME_RUNNING:


        CountdownTimer();
        break;
      case GameState.END_MENU:


        break;
      default:


        break;
    }
  }

  private void CountdownTimer()
  {
    timeRemaining -= Time.deltaTime;
    timerHud.text = Mathf.Ceil(timeRemaining).ToString();
    if (timeRemaining <= 0)
    {
      timeRemaining = 0;
      timerHud.text = Mathf.Ceil(timeRemaining).ToString();
      EndGame();
    }
  }

  public void SetStartMenu()
  {
    gameState = GameState.START_MENU;

    
    startMenu?.SetActive(true);
    gameHud?.SetActive(false);
    endMenu?.SetActive(false);
  }

  public void StartGame()
  {
    gameState = GameState.GAME_RUNNING;
    timeRemaining = gameDuration;

    SetPoints(0);

    startMenu?.SetActive(false);
    gameHud?.SetActive(true);
    endMenu?.SetActive(false);


    for (int i = 0; i < numberOfEnemies; i++)
    {
      SpawnEnemy();
    }

  }

  public void EndGame()
  {
    gameState = GameState.END_MENU;

    endPointHud.text = points.ToString();

    GameObject[] enemies = GameObject.FindGameObjectsWithTag("Enemy");

    for (int i = 0; i < enemies.Length; i++)
    {
      Destroy(enemies[i]);
    }


    startMenu?.SetActive(false);
    gameHud?.SetActive(false);
    endMenu?.SetActive(true);
  }

  public void CloseGame()
  {

#if UNITY_EDITOR
    EditorApplication.ExitPlaymode();

#else
    Application.Quit();
#endif
  }

  public GameState GetGameState()
  {
    return gameState;
  }


  public void NotifyEnemyDeath(int points)
  {
    AddPoints(points);
    //spawn new enemy
    SpawnEnemy();
  }

  public void AddPoints(int points)
  {
    this.points += points;
    pointHud.text = this.points.ToString();
  }

  public void SetPoints(int points)
  {
    this.points = points;
    pointHud.text = this.points.ToString();
  }

  public void SpawnEnemy()
  {
    float spawnAngle = Random.Range(0, 360);
    float spawnDistance = Random.Range(minSpawnDistance, maxSpawnDistance);
    float spawnHeight = 0.2f;

    spawnAngle = spawnAngle * Mathf.Deg2Rad;


    Vector3 spawnPosition = new Vector3(
      player.transform.position.x + Mathf.Sin(spawnAngle) * spawnDistance,
      player.transform.position.y + spawnHeight,
      player.transform.position.z + Mathf.Cos(spawnAngle) * spawnDistance
    );

    GameObject spawnedEnemy = Instantiate(enemyPrefab);
    spawnedEnemy.transform.position = spawnPosition;
    float points = Random.Range(enemyMinPoint,enemyMaxPoint);
    points /= 10;
    points = Mathf.Round(points);
    points *= 10;

   EnemyController enemyController = spawnedEnemy.GetComponent<EnemyController>();
    if (enemyController != null) {
      enemyController.SetValues(10, (int) points);
    }

  }
}
