using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Unity.VisualScripting;
using UnityEngine;
using UnityEngine.UIElements;

public class NewBehaviourScript : MonoBehaviour
{
    // Shared
    public int Wave = 0;
    public float difficulty = 1;

    // Inspector
    [SerializeField] private float difficultyIncreasePerWave = 0.1f;
    [SerializeField] private float WaveTime = 20f;
    [SerializeField] private List<float> enemyDifficulties;
    [SerializeField] private float SpawnRadius = 10;
    [SerializeField] private int NumEnemies = 6;
    [SerializeField] private GameObject[] players;

    // Private
    private bool nextWaveRequested = false;
    private float timer = 0f;
    private Camera mainCam;
    private GameObject SpawnedEnenmyHolder;
    [SerializeField] private List<EnemyPrefabInfo> enemyList;

    private bool SpawnerStarted = false;

    private void Start()
    {
        mainCam = Camera.main;
        SpawnedEnenmyHolder = new GameObject("SpawnedEnenmyHolder");

        for (int i = 0; i < 6; i++)
        {
            enemyList.Add(new EnemyPrefabInfo() { Difficulty = i+1, prefabs = Resources.LoadAll<GameObject>("Enemies/" + (i+1)) });
        }

        StartSpawning();
    }

    public void Update()
    {
        if (SpawnerStarted)
            timer += Time.deltaTime;

        if (timer > WaveTime || nextWaveRequested)
        {
            Task.Factory.StartNew(() => { Task.Delay(100); timer = 0; });

            SpawnWave(difficulty);

            Wave++;
            difficulty *= difficultyIncreasePerWave + 1;
            nextWaveRequested = false;
            timer = 0;
        }
        
    }

    public void StartSpawning() => SpawnerStarted = true;
    public void StartNextWave() => nextWaveRequested = true;

    void SpawnWave(float difficulty)
    {
        //SpawnStrongestFirst(difficulty);

        if (Wave != 0 && Wave % 10 == 0)
            SpawnStrongestFirst(difficulty);
        else
            SpawnRandom(difficulty);
    }

    void SpawnStrongestFirst(float difficulty)
    {
        var decendingList = enemyList.Where(x => x.Difficulty < difficulty).OrderByDescending(x => x.Difficulty).ToArray();
        for (int i = 0; i < decendingList.Length; i++)
        {
            while (difficulty > decendingList[i].Difficulty)
            {
                GameObject enemy = Instantiate(decendingList[i].prefabs[UnityEngine.Random.Range(0, decendingList[i].prefabs.Length)], GetRandomPointOnCircle(mainCam.transform.position, SpawnRadius), Quaternion.identity, SpawnedEnenmyHolder.transform);
                difficulty -= decendingList[i].Difficulty;

                enemy.GetComponent<EnemyPathFinding>().targets = players.Select(x=>x.transform).ToArray();
            }
        }
    }

    void SpawnRandom(float difficulty)
    {
        while (difficulty > 1f) // Spawn until difficulty is less than 0.5f
        {
            var validEnemies = enemyList.Where(x => x.Difficulty <= difficulty).ToArray();
            int enemyIndex = UnityEngine.Random.Range(0, validEnemies.Length);
            var enemyToSpawn = validEnemies[enemyIndex];
            difficulty -= enemyToSpawn.Difficulty;

            int variant = UnityEngine.Random.Range(0, enemyToSpawn.prefabs.Length);
            GameObject variantToSpawn = enemyToSpawn.prefabs[variant];

            GameObject enemy = Instantiate(variantToSpawn, GetRandomPointOnCircle(mainCam.transform.position, SpawnRadius), Quaternion.identity, SpawnedEnenmyHolder.transform);

            enemy.GetComponent<EnemyPathFinding>().targets = players.Select(x => x.transform).ToArray();
        }
    }

    public Vector3 GetRandomPointOnCircle(Vector3 location, float radius)
    {
        float angle = UnityEngine.Random.Range(0f, 360f);
        float radians = Mathf.Deg2Rad * angle;

        Vector3 position = transform.position;
        float x = position.x + radius * Mathf.Cos(radians);
        float y = position.y + radius * Mathf.Sin(radians);

        return new Vector3(x, y, position.z);
    }

#if UNITY_EDITOR
    private void OnDrawGizmosSelected()
    {
        Gizmos.color = Color.green;
        Gizmos.DrawWireSphere(transform.position, SpawnRadius);

        for (int i = 0; i < 10; i++)
        {
            Gizmos.DrawWireSphere(GetRandomPointOnCircle(transform.position, SpawnRadius), 0.25f);
        }
    }
#endif
}