using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Mirror;
using UnityEngine.SceneManagement;
using System.Threading.Tasks;
using TMPro;

public class MinigameManager : NetworkBehaviour
{
    public static MinigameManager instance;
    public float mapRadius;
    public int maxMoons, maxStars = 100;
    public Transform pickupItemsParent;
    private List<PickupItem> ActiveMoons = new List<PickupItem>();
    private List<PickupItem> ActiveStars = new List<PickupItem>();

    List<PickupItem> MoonPool = new List<PickupItem>();
    List<PickupItem> StarsPool = new List<PickupItem>();
    public GameObject moon;
    public GameObject star;

    private void Awake()
    {
        SceneData.GameManager = this;
        instance = this;

        DBmanager.OnStateChanged.AddListener(UpdateMaterialValues);
         UpdateMaterialValues();
    }

    void Update()
    {
      //  if(!DBmanager.LoggedIn){SceneManager.LoadScene(0);} //Signed out, no game for u
        if (!isServer) { return; }

        HandlePickupSpawn();
        KillOutOfBoundsPlayers();

    }

    void KillOutOfBoundsPlayers()
    {
        SpaceshipController[] players = FindObjectsOfType<SpaceshipController>();
        foreach (SpaceshipController player in players)
        {
            if (Vector3.Distance(player.transform.position, Vector3.zero) > mapRadius)
            {
                //Out of bounds. Kill him
                player.Die("Playzone");
            }
        }
    }

    void HandlePickupSpawn()
    {
        int moonsNeed = maxMoons - ActiveMoons.Count;
        int starsNeed = maxStars - ActiveStars.Count;

        if (moonsNeed > 0)
        { // <-- We need more moons!
            SpawnMoons(moonsNeed);
        }

        if (starsNeed > 0)
        { // <-- We need more moons!
            SpawnStars(starsNeed);
        }
    }

    public void SpawnLeftoverPickups(Vector3 position, int amount)
    {
        SpawnStars(amount, focusedPosition: position);
    }

    void SpawnStars(int amount, Vector3? focusedPosition = null)
    {
        for (int i = 0; i < amount; i++)
        {
            Vector3 newPosition = (focusedPosition == null) ? getRandomPositionOnMap() : getRandomPointInCirlce((Vector3)focusedPosition, 10);
            if (StarsPool.Count > 0)
            { // <-- Got some in the pool, no need to spawn new
                PickupItem pickedStar = StarsPool[0];
                pickedStar.Reposition(newPosition);

                ActiveStars.Add(pickedStar);
                StarsPool.RemoveAt(0);
            }
            else
            {
                GameObject newStar = Instantiate(star, pickupItemsParent);
                NetworkServer.Spawn(newStar);
                newStar.GetComponent<PickupItem>().Reposition(newPosition);
                ActiveStars.Add(newStar.GetComponent<PickupItem>());
            }
        }
    }

    void SpawnMoons(int amount)
    {
        for (int i = 0; i < amount; i++)
        {
            if (MoonPool.Count > 0)
            { // <-- Got some in the pool, no need to spawn new
                PickupItem pickedMoon = MoonPool[0];
                pickedMoon.Reposition(getRandomPositionOnMap());

                ActiveMoons.Add(pickedMoon);
                MoonPool.RemoveAt(0);
            }
            else
            {
                GameObject newMoon = Instantiate(moon, pickupItemsParent);
                NetworkServer.Spawn(newMoon);
                newMoon.GetComponent<PickupItem>().Reposition(getRandomPositionOnMap());
                ActiveMoons.Add(newMoon.GetComponent<PickupItem>());
            }
        }
    }

    public void DeactivatePickupItem(PickupItem item)
    {
        if (item.type == PickupItem.PickupType.Moon)
        {
            ActiveMoons.Remove(item);
            MoonPool.Add(item);
        }
        else if (item.type == PickupItem.PickupType.Star)
        {
            ActiveStars.Remove(item);
            StarsPool.Add(item);
        }
    }

    public void SetRespawn(GameObject player)
    {
        StartCoroutine(setRespawn(player));
    }

    IEnumerator setRespawn(GameObject player)
    {
        if (isServer)
        {
            player.SetActive(false);
            yield return new WaitForSeconds(3);
            Vector3 RespawnPoint = NetworkManager.startPositions[Random.Range(0, NetworkManager.startPositions.Count - 1)].position;

            player.GetComponent<SpaceshipController>().Respawn(RespawnPoint);
        }
        else
        {
            yield return new WaitForSeconds(1);
        }
    }

    Vector3 getRandomPositionOnMap()
    {
        return getRandomPointInCirlce(Vector3.zero, mapRadius);
    }

    Vector3 getRandomPointInCirlce(Vector3 center, float radius)
    {
        float r = radius * Mathf.Sqrt(Random.Range(0f, 1f));
        float theta = Random.Range(0f, 1f) * 2 * Mathf.PI;
        float x = center.x + r * Mathf.Cos(theta);
        float y = center.y + r * Mathf.Sin(theta);
        return new Vector3(x, y);
    }

    void OnDrawGizmos()
    {
        Gizmos.DrawWireSphere(transform.position, mapRadius);
    }

    public GameObject loadingScreen;
    public async void BackToBase(){
        loadingScreen.SetActive(true);
        await Task.Delay(1000); 
        NetworkManager.singleton.StopClient();
        SceneManager.LoadScene("MinigameMenu");
    }


    //Materials
    [Header("Materials")]
    public TMP_Text metalTxt;

    public void GainMetals(int amount){
        int newAmount = DBmanager.Metal+amount;
        DBmanager.SetMetal(newAmount);
    }

    public void UpdateMaterialValues(){
        metalTxt.text = DBmanager.Metal.ToString();
    }
}
