using System;
using UnityEngine;
using VContainer;
using YachtDice.Categories;
using YachtDice.Scoring;

namespace YachtDice.Game
{
    public class GameManager : MonoBehaviour
    {
        [Header("Settings")]
        [SerializeField] private int maxRollsPerTurn = 3;

        private DiceManager diceManager;
        private ScoringSystem scoringSystem;

        public int CurrentRoll { get; private set; }
        public int CurrentTurn { get; private set; }

        public bool CanRoll => CurrentRoll < maxRollsPerTurn && !diceManager.IsAnyRolling;
        public bool CanScore => CurrentRoll > 0 && !diceManager.IsAnyRolling;
        public bool IsGameOver => scoringSystem.IsComplete;

        public event Action<int> OnTurnStarted;
        public event Action<int> OnRollComplete;
        public event Action<CategoryDefinition, int> OnScored;
        public event Action<int> OnGameOver;

        [Inject]
        public void Construct(DiceManager diceManager, ScoringSystem scoringSystem)
        {
            this.diceManager = diceManager;
            this.scoringSystem = scoringSystem;
        }

        public void StartNewGame()
        {
            scoringSystem.ResetScorecard();
            CurrentTurn = 0;
            StartNewTurn();
        }

        private void StartNewTurn()
        {
            CurrentTurn++;
            CurrentRoll = 0;
            diceManager.UnlockAll();
            OnTurnStarted?.Invoke(CurrentTurn);
            Debug.Log($"=== Turn {CurrentTurn} ===");
        }

        public void Roll()
        {
            if (!CanRoll) return;

            CurrentRoll++;
            diceManager.OnAllDiceSettled += HandleAllDiceSettled;
            diceManager.RollUnlocked();
        }

        private void HandleAllDiceSettled()
        {
            diceManager.OnAllDiceSettled -= HandleAllDiceSettled;

            int[] values = diceManager.GetCurrentValues();
            Debug.Log($"Roll {CurrentRoll}/{maxRollsPerTurn} | Dice: [{string.Join(", ", values)}]");

            OnRollComplete?.Invoke(CurrentRoll);
        }

        public void ToggleDiceLock(int index)
        {
            if (diceManager.IsAnyRolling) return;
            if (CurrentRoll == 0) return;
            diceManager.ToggleLock(index);

            bool isLocked = diceManager.IsLocked(index);
            Debug.Log($"Dice {index + 1} (value={diceManager.GetValue(index)}): {(isLocked ? "LOCKED" : "UNLOCKED")}");
        }

        public void ScoreInCategory(CategoryDefinition category)
        {
            if (!CanScore) return;
            if (scoringSystem.IsCategoryUsed(category)) return;

            var dice = diceManager.GetDice();
            ScoreResult result = scoringSystem.ScoreCategory(dice, category);

            Debug.Log($"Scored {category.DisplayName}: base={result.BaseScore}, " +
                      $"bonus=+{result.FlatBonus}, mult=x{result.Multiplier:F1}, " +
                      $"FINAL={result.FinalScore} | Total={scoringSystem.TotalScore}");

            OnScored?.Invoke(category, result.FinalScore);

            if (scoringSystem.IsComplete)
            {
                int total = scoringSystem.TotalScore;
                Debug.Log($"*** GAME OVER *** Total Score: {total}");
                OnGameOver?.Invoke(total);
            }
            else
            {
                StartNewTurn();
            }
        }
    }
}
