using System.Collections.Generic;
using UnityEngine;
using UnityEngine.AI;

///<summary>
/// Object handling Room logic
///</summary>
///
public class RoomHandler : MonoBehaviour
{
    [Header("Doors")]
    [SerializeField] private GameObject wallNorth;
    [SerializeField] private GameObject wallSouth;
    [SerializeField] private GameObject wallEast;
    [SerializeField] private GameObject wallWest;

    public enum Side
    {
        North,
        South,
        East,
        West
    }

    // Room Spawn Points
    [Header("Spawn Points")]
    [SerializeField] private List<GameObject> spawnPoints;
    [SerializeField] private GameObject test;
    [SerializeField] private bool allowSpawn = false;

    private readonly Dictionary<Side, DoorAnimation> doors = new();

    public void RegisterDoor(Side dir, DoorAnimation doorAnim) => doors[dir] = doorAnim;

    /// <summary>
    /// Creates entrances to corridors leading to other rooms
    /// </summary>
    /// <param name="northOpen"></param>
    /// <param name="southOpen"></param>
    /// <param name="eastOpen"></param>
    /// <param name="westOpen"></param>
    public void SetEntrances(bool northOpen, bool southOpen, bool eastOpen, bool westOpen)
    {
        wallNorth.SetActive(!northOpen);
        wallSouth.SetActive(!southOpen);
        wallEast.SetActive(!eastOpen);
        wallWest.SetActive(!westOpen);
    }

    public void ToggleAllDoors()
    {
        foreach (DoorAnimation door in doors.Values)
        {
            door.ToggleDoor();
        }
    }

    public void SetDoorState(Side dir, bool open)
    {
        if (doors.TryGetValue(dir, out DoorAnimation da))
        {
            da.ToggleDoor();
            Debug.Log("Door " + dir + " is now " + (open ? "open" : "closed"));
        }
    }

    public void SpawnEnemies(List<GameObject> enemyPrefabs)
    {
        if (!allowSpawn || enemyPrefabs == null || enemyPrefabs.Count == 0)
        {
            Debug.LogWarning("Enemy spawning is not allowed or no enemies to spawn.");
            return;
        }

        StartCoroutine(SpawnEnemiesWithDelay(enemyPrefabs));

    }


    private System.Collections.IEnumerator SpawnEnemiesWithDelay(List<GameObject> enemyPrefabs)
    {
        // Počkej až bude NavMesh ready
        yield return new WaitUntil(() => NavMesh.CalculateTriangulation().indices.Length > 0);

        for (int i = 0; i < enemyPrefabs.Count; i++)
        {
            if (spawnPoints == null || spawnPoints.Count == 0) yield break;

            GameObject spawnPoint = spawnPoints[i % spawnPoints.Count];
            Vector3 spawnPosition = spawnPoint.transform.position + new Vector3(0, 1, 0);

            GameObject enemy = Instantiate(enemyPrefabs[i], spawnPosition, Quaternion.identity);

            // Počkej než se objekt plně inicializuje
            yield return new WaitForEndOfFrame();

            // Zkus umístit enemy na NavMesh
            NavMeshAgent agent = enemy.GetComponent<NavMeshAgent>();
            if (agent != null)
            {
                if (!agent.isOnNavMesh)
                {
                    agent.Warp(spawnPosition);
                }

                if (!agent.isOnNavMesh)
                {
                    Debug.LogWarning("Enemy could not be placed on NavMesh");
                }
            }

            // Malý delay mezi spawny
            yield return new WaitForSeconds(0.2f);
        }
    }

    void Start()
    {
        int enemyCount = Random.Range(1, 4);
        List<GameObject> enemyPrefabs = new List<GameObject>();
        for (int i = 0; i < enemyCount; i++)
        {
            enemyPrefabs.Add(test);
        }

        StartCoroutine(DelayedSpawn(enemyPrefabs));
    }

    System.Collections.IEnumerator DelayedSpawn(List<GameObject> enemyPrefabs)
    {
        // Počkej než se místnost plně inicializuje
        yield return new WaitForSeconds(0.5f);
        SpawnEnemies(enemyPrefabs);
    }

    System.Collections.IEnumerator SetupEnemyAfterDelay(GameObject enemy)
    {
        yield return new WaitForSeconds(0.1f);

        NavMeshAgent agent = enemy.GetComponent<NavMeshAgent>();
        if (agent != null && agent.isOnNavMesh)
        {
            Debug.Log("Enemy je ready");
            // Enemy je ready
        }
    }
}
