using System;
using FlappyBird.Core;
using UnityEngine;
using Zenject;

namespace FlappyBird.UI
{
    public class GameUIController : IGameUIController, IInitializable, IDisposable
    {
        private readonly IGameManager _gameManager;
        private readonly IScoreManager _scoreManager;
        private readonly IObjectPoolManager _poolManager;
        private readonly GameObject _popupPrefab;

        private GameUIView _view;

        [Inject]
        public GameUIController(
            IGameManager gameManager,
            IScoreManager scoreManager,
            IObjectPoolManager poolManager,
            [Inject(Id = "ScorePopupPrefab")] GameObject popupPrefab)
        {
            _gameManager = gameManager;
            _scoreManager = scoreManager;
            _poolManager = poolManager;
            _popupPrefab = popupPrefab;
        }

        public void Initialize()
        {
            _poolManager.RegisterPool<ScorePopupView>(_popupPrefab, 5);
            _gameManager.OnGameStateChanged += HandleGameStateChanged;
            _scoreManager.OnScoreChanged += HandleScoreChanged;
        }

        public void Dispose()
        {
            _gameManager.OnGameStateChanged -= HandleGameStateChanged;
            _scoreManager.OnScoreChanged -= HandleScoreChanged;
        }

        public void Bind(GameUIView view)
        {
            _view = view;
            RefreshView();
        }

        private void HandleScoreChanged(int score)
        {
            if (_view == null || score == 0) return;

            _view.SetCurrentScore(score);
            _view.ShowScoreGain();

            // 1. Get from pool
            var popup = _poolManager.Get<ScorePopupView>();

            // 2. Use the container provided by the View
            // 'worldPositionStays: false' is CRITICAL for UI elements
            popup.transform.SetParent(_view.PopupContainer, false);

            // 3. Reset local position to zero (the center of the container)
            popup.transform.localPosition = Vector3.zero;
        }

        private void HandleGameStateChanged(GameState state) => ApplyState(state);

        private void ApplyState(GameState state)
        {
            if (_view == null) return;

            _view.SetTapToStartVisible(state == GameState.Menu);
            _view.SetGameOverVisible(state == GameState.GameOver);
            _view.SetCurrentScoreVisible(state == GameState.Playing);
        }

        private void RefreshView()
        {
            _view.SetCurrentScore(_scoreManager.CurrentScore);
            _view.SetBestScore(_scoreManager.BestScore);
            ApplyState(_gameManager.CurrentState);
        }
    }
}