using System;
using UnityEngine;
using Zenject;

namespace FlappyBird.Core
{
    public class ScoreManager : IScoreManager, IInitializable, IDisposable
    {
        private const string BestScoreKey = "BestScore";

        private readonly IGameManager _gameManager;
        private readonly IPlayerPrefsStorage _playerPrefsStorage;

        [Inject]
        public ScoreManager(IGameManager gameManager, IPlayerPrefsStorage playerPrefsStorage)
        {
            _gameManager = gameManager;
            _playerPrefsStorage = playerPrefsStorage;
        }

        public int CurrentScore { get; private set; }
        public int BestScore { get; private set; }

        public event Action<int> OnScoreChanged;
        public event Action<int> OnBestScoreChanged;

        public void Initialize()
        {
            BestScore = _playerPrefsStorage.GetInt(BestScoreKey, 0);
            OnBestScoreChanged?.Invoke(BestScore);
            Debug.Log($"High score loaded: {BestScore}");
            _gameManager.OnGameStateChanged += HandleGameStateChanged;
            ResetScore();
        }

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

        public void AddScore(int points)
        {
            if (points <= 0 || _gameManager.CurrentState != GameState.Playing)
            {
                return;
            }

            CurrentScore += points;
            OnScoreChanged?.Invoke(CurrentScore);
            Debug.Log($"Current score: {CurrentScore}");
            UpdateBestScore(CurrentScore);
        }

        public void ResetScore()
        {
            CurrentScore = 0;
            OnScoreChanged?.Invoke(CurrentScore);
            Debug.Log($"Current score reset: {CurrentScore}");
        }

        private void HandleGameStateChanged(GameState state)
        {
            if (state == GameState.Menu)
            {
                ResetScore();
            }
        }

        private void UpdateBestScore(int score)
        {
            if (score <= BestScore)
            {
                return;
            }

            BestScore = score;
            _playerPrefsStorage.SetInt(BestScoreKey, BestScore);
            _playerPrefsStorage.Save();
            OnBestScoreChanged?.Invoke(BestScore);
            Debug.Log($"High score updated: {BestScore}");
        }
    }
}
