using System.Collections;
using System.Collections.Generic;
using Core.Domain;
using UnityEngine;

namespace Infrastructure.Unity
{
    public class FloorVisibilityManager : MonoBehaviour
    {
        [SerializeField] private float fadeSpeed = 5f;
        [SerializeField] private float hiddenAlpha = 0.1f;
        [SerializeField] private float visibleAlpha = 1.0f;
        
        private GameSession _gameSession;
        private List<List<TileViewAdapter>> _floors;
        private int _currentFloorIndex = -1;
        
        public void Initialize(GameSession gameSession, List<Tile> allTiles, Dictionary<string, TileViewAdapter> tileViews, int totalFloors)
        {
            _gameSession = gameSession;

            _floors = new List<List<TileViewAdapter>>();
            for (var i = 0; i < totalFloors; i++)
            {
                _floors.Add(new List<TileViewAdapter>());
            }

            foreach (var tile in allTiles)
            {
                if (tileViews.TryGetValue(tile.Id, out var view))
                {
                    // Safety check for array bounds
                    if (tile.Floor < _floors.Count)
                    {
                        _floors[tile.Floor].Add(view);
                    }
                }
            }
        }

        private void Update()
        {
            if (_gameSession == null) return;

            // Check if player changed floors
            // We read the private field _playerFloorIndex via a public getter we need to add, 
            // OR we just track it locally if you updated GameSession to expose it.
            // Assuming GameSession doesn't expose it publically yet, let's rely on GameBootstrap passing it or just hack it:
            // Ideally, GameSession should emit an event 'OnFloorChanged'.
            // For now, let's assume we can get it or we passed the player reference.
        }

        // Call this from GameBootstrap.Update()
        public void UpdateFloorVisibility(int playerFloorIndex)
        {
            if (_currentFloorIndex == playerFloorIndex) return;

            _currentFloorIndex = playerFloorIndex;
            StopAllCoroutines();
            StartCoroutine(UpdateFloorsRoutine(playerFloorIndex));
        }

        private IEnumerator UpdateFloorsRoutine(int playerFloor)
        {
            for (var i = 0; i < _floors.Count; i++)
            {
                var targetAlpha = (i < playerFloor) ? hiddenAlpha : visibleAlpha;

                if (_floors[i].Count == 0) continue;

                foreach (var tile in _floors[i])
                {
                    if (tile && tile.gameObject.activeInHierarchy)
                    {
                        tile.SetAlpha(targetAlpha);
                    }
                }
                
                if (i % 2 == 0) yield return null; 
            }
        }
    }
}