// ==============================================
// DifficultyManager.cs - Schwierigkeits-Steuerung
// ==============================================
// Passt die Spielschwierigkeit dynamisch an
// basierend auf Lernniveau und Spielerleistung.

using System;
using UnityEngine;

namespace BreakpilotDrive
{
    public class DifficultyManager : MonoBehaviour
    {
        public static DifficultyManager Instance { get; private set; }

        [Header("Schwierigkeits-Bereich")]
        [SerializeField] private int minDifficulty = 1;
        [SerializeField] private int maxDifficulty = 5;

        [Header("Dynamische Anpassung")]
        [SerializeField] private bool enableDynamicDifficulty = true;
        [SerializeField] private int questionsForEvaluation = 5;
        [SerializeField] private float accuracyToIncrease = 0.8f;  // 80% richtig = schwerer
        [SerializeField] private float accuracyToDecrease = 0.4f;  // 40% richtig = leichter

        [Header("Geschwindigkeits-Steigerung")]
        [SerializeField] private bool enableSpeedIncrease = true;
        [SerializeField] private float speedIncreaseInterval = 30f;  // Alle X Sekunden
        [SerializeField] private float speedIncreaseAmount = 0.5f;   // Um X erhoehen

        // Aktueller Zustand
        private int currentDifficulty = 3;
        private GameDifficulty currentSettings;
        private float timeSinceLastSpeedIncrease = 0f;

        // Statistik fuer dynamische Anpassung
        private int recentQuestionsAnswered = 0;
        private int recentQuestionsCorrect = 0;

        // Events
        public event Action<int> OnDifficultyChanged;
        public event Action<GameDifficulty> OnSettingsUpdated;

        // Properties
        public int CurrentDifficulty => currentDifficulty;
        public GameDifficulty CurrentSettings => currentSettings;

        void Awake()
        {
            if (Instance == null)
            {
                Instance = this;
            }
            else
            {
                Destroy(gameObject);
            }
        }

        void Start()
        {
            // Quiz-Events abonnieren
            if (QuizManager.Instance != null)
            {
                QuizManager.Instance.OnQuestionAnswered += OnQuestionAnswered;
            }

            // Initiale Schwierigkeit laden
            LoadDifficulty(currentDifficulty);
        }

        void OnDestroy()
        {
            if (QuizManager.Instance != null)
            {
                QuizManager.Instance.OnQuestionAnswered -= OnQuestionAnswered;
            }
        }

        void Update()
        {
            if (GameManager.Instance?.CurrentState != GameState.Playing)
                return;

            // Geschwindigkeit graduell erhoehen
            if (enableSpeedIncrease)
            {
                timeSinceLastSpeedIncrease += Time.deltaTime;

                if (timeSinceLastSpeedIncrease >= speedIncreaseInterval)
                {
                    timeSinceLastSpeedIncrease = 0f;
                    IncreaseSpeed();
                }
            }
        }

        // ==============================================
        // Schwierigkeit laden
        // ==============================================
        public void LoadDifficulty(int level)
        {
            currentDifficulty = Mathf.Clamp(level, minDifficulty, maxDifficulty);

            if (BreakpilotAPI.Instance != null)
            {
                StartCoroutine(BreakpilotAPI.Instance.GetDifficulty(currentDifficulty,
                    onSuccess: (settings) =>
                    {
                        currentSettings = settings;
                        ApplySettings(settings);
                        OnSettingsUpdated?.Invoke(settings);
                        Debug.Log($"Schwierigkeit {currentDifficulty} geladen");
                    },
                    onError: (error) =>
                    {
                        Debug.LogWarning($"Konnte Schwierigkeit nicht laden: {error}");
                        // Fallback zu Default-Werten
                        currentSettings = GetDefaultSettings(currentDifficulty);
                        ApplySettings(currentSettings);
                    }
                ));
            }
            else
            {
                currentSettings = GetDefaultSettings(currentDifficulty);
                ApplySettings(currentSettings);
            }

            OnDifficultyChanged?.Invoke(currentDifficulty);
        }

        private void ApplySettings(GameDifficulty settings)
        {
            // Geschwindigkeit anwenden
            if (TrackGenerator.Instance != null)
            {
                TrackGenerator.Instance.SetSpeed(settings.lane_speed);
            }

            if (PlayerController.Instance != null)
            {
                PlayerController.Instance.SetSpeed(settings.lane_speed);
            }

            // Hindernis-Frequenz anwenden
            // ObstacleSpawner liest die Settings direkt aus GameManager

            Debug.Log($"Settings angewendet: Speed={settings.lane_speed}, " +
                      $"Obstacles={settings.obstacle_frequency}, " +
                      $"Hints={settings.hints_enabled}");
        }

        // ==============================================
        // Dynamische Anpassung
        // ==============================================
        private void OnQuestionAnswered(bool correct, int points)
        {
            if (!enableDynamicDifficulty) return;

            recentQuestionsAnswered++;
            if (correct) recentQuestionsCorrect++;

            // Evaluation nach X Fragen
            if (recentQuestionsAnswered >= questionsForEvaluation)
            {
                EvaluateAndAdjust();
            }
        }

        private void EvaluateAndAdjust()
        {
            float accuracy = (float)recentQuestionsCorrect / recentQuestionsAnswered;

            Debug.Log($"Quiz-Evaluation: {recentQuestionsCorrect}/{recentQuestionsAnswered} " +
                      $"= {accuracy:P0}");

            if (accuracy >= accuracyToIncrease && currentDifficulty < maxDifficulty)
            {
                // Spieler ist gut - Schwierigkeit erhoehen
                IncreaseDifficulty();
            }
            else if (accuracy <= accuracyToDecrease && currentDifficulty > minDifficulty)
            {
                // Spieler hat Probleme - Schwierigkeit verringern
                DecreaseDifficulty();
            }

            // Reset fuer naechste Evaluation
            recentQuestionsAnswered = 0;
            recentQuestionsCorrect = 0;
        }

        public void IncreaseDifficulty()
        {
            if (currentDifficulty < maxDifficulty)
            {
                LoadDifficulty(currentDifficulty + 1);
                Debug.Log($"Schwierigkeit erhoeht auf {currentDifficulty}");
            }
        }

        public void DecreaseDifficulty()
        {
            if (currentDifficulty > minDifficulty)
            {
                LoadDifficulty(currentDifficulty - 1);
                Debug.Log($"Schwierigkeit verringert auf {currentDifficulty}");
            }
        }

        // ==============================================
        // Geschwindigkeits-Steigerung
        // ==============================================
        private void IncreaseSpeed()
        {
            if (currentSettings == null) return;

            float newSpeed = currentSettings.lane_speed + speedIncreaseAmount;

            // Maximal-Geschwindigkeit basierend auf Difficulty
            float maxSpeed = 5f + (currentDifficulty * 2f);
            newSpeed = Mathf.Min(newSpeed, maxSpeed);

            currentSettings.lane_speed = newSpeed;

            if (TrackGenerator.Instance != null)
            {
                TrackGenerator.Instance.SetSpeed(newSpeed);
            }

            Debug.Log($"Geschwindigkeit erhoeht auf {newSpeed:F1}");
        }

        // ==============================================
        // Default-Werte (Fallback)
        // ==============================================
        private GameDifficulty GetDefaultSettings(int level)
        {
            return new GameDifficulty
            {
                lane_speed = 4f + level,
                obstacle_frequency = 0.3f + (level * 0.1f),
                power_up_chance = 0.4f - (level * 0.05f),
                question_complexity = level,
                answer_time = 15 - (level * 2),
                hints_enabled = level <= 2,
                speech_speed = 0.8f + (level * 0.1f)
            };
        }

        // ==============================================
        // Oeffentliche Methoden
        // ==============================================
        public void SetDifficulty(int level)
        {
            LoadDifficulty(level);
        }

        public void ResetForNewGame()
        {
            recentQuestionsAnswered = 0;
            recentQuestionsCorrect = 0;
            timeSinceLastSpeedIncrease = 0f;

            // Schwierigkeit von User-Level laden
            if (BreakpilotAPI.Instance != null)
            {
                var cachedLevel = BreakpilotAPI.Instance.GetCachedLevel();
                if (cachedLevel != null)
                {
                    LoadDifficulty(cachedLevel.overall_level);
                }
            }
        }

        public float GetCurrentSpeed()
        {
            return currentSettings?.lane_speed ?? 5f;
        }

        public bool AreHintsEnabled()
        {
            return currentSettings?.hints_enabled ?? false;
        }

        public int GetAnswerTime()
        {
            return currentSettings?.answer_time ?? 10;
        }
    }
}
