// ==============================================
// ObstacleSpawner.cs - Hindernis-Generator
// ==============================================
// Spawnt Hindernisse, Items und Quiz-Trigger
// basierend auf Schwierigkeitsgrad.

using UnityEngine;

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

        [Header("Hindernis-Prefabs")]
        [SerializeField] private GameObject[] obstaclePrefabs;      // Verschiedene Hindernisse
        [SerializeField] private GameObject[] largObstaclePrefabs;  // Grosse Hindernisse (2 Spuren)

        [Header("Item-Prefabs")]
        [SerializeField] private GameObject coinPrefab;
        [SerializeField] private GameObject starPrefab;
        [SerializeField] private GameObject shieldPrefab;

        [Header("Quiz-Trigger-Prefabs")]
        [SerializeField] private GameObject bridgePrefab;
        [SerializeField] private GameObject treePrefab;
        [SerializeField] private GameObject housePrefab;

        [Header("Spawn-Einstellungen")]
        [SerializeField] private float laneDistance = 3f;
        [SerializeField] private float minObstacleSpacing = 10f;
        [SerializeField] private float maxObstacleSpacing = 30f;

        [Header("Wahrscheinlichkeiten (0-1)")]
        [SerializeField] private float obstacleChance = 0.6f;
        [SerializeField] private float coinChance = 0.3f;
        [SerializeField] private float starChance = 0.05f;
        [SerializeField] private float shieldChance = 0.02f;
        [SerializeField] private float quizTriggerChance = 0.1f;

        // Interner Zustand
        private float lastObstacleZ = 0f;
        private int quizTriggerCount = 0;

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

        void Start()
        {
            // Wahrscheinlichkeiten von Difficulty laden
            UpdateFromDifficulty();
        }

        private void UpdateFromDifficulty()
        {
            if (GameManager.Instance?.DifficultySettings != null)
            {
                var settings = GameManager.Instance.DifficultySettings;
                obstacleChance = settings.obstacle_frequency;
                // Power-Up Chance beeinflusst Items
                float powerUpChance = settings.power_up_chance;
                coinChance = powerUpChance * 0.8f;
                starChance = powerUpChance * 0.15f;
                shieldChance = powerUpChance * 0.05f;
            }
        }

        // ==============================================
        // Spawning auf Segment
        // ==============================================
        public void SpawnOnSegment(GameObject segment, float segmentStartZ)
        {
            float segmentLength = 50f; // Sollte mit TrackGenerator uebereinstimmen
            float currentZ = segmentStartZ + minObstacleSpacing;

            while (currentZ < segmentStartZ + segmentLength - minObstacleSpacing)
            {
                // Zufaelliger Abstand zum naechsten Objekt
                float spacing = Random.Range(minObstacleSpacing, maxObstacleSpacing);

                // Was spawnen?
                SpawnAtPosition(segment.transform, currentZ);

                currentZ += spacing;
            }
        }

        private void SpawnAtPosition(Transform parent, float zPosition)
        {
            float roll = Random.value;

            // Quiz-Trigger (selten, aber wichtig)
            if (roll < quizTriggerChance && quizTriggerCount < 3)
            {
                SpawnQuizTrigger(parent, zPosition);
                quizTriggerCount++;
                return;
            }

            // Hindernis
            roll = Random.value;
            if (roll < obstacleChance)
            {
                SpawnObstacle(parent, zPosition);
            }

            // Items (koennen neben Hindernissen sein)
            roll = Random.value;
            if (roll < coinChance)
            {
                SpawnCoinRow(parent, zPosition);
            }
            else if (roll < coinChance + starChance)
            {
                SpawnItem(starPrefab, parent, zPosition, GetRandomLane());
            }
            else if (roll < coinChance + starChance + shieldChance)
            {
                SpawnItem(shieldPrefab, parent, zPosition, GetRandomLane());
            }
        }

        // ==============================================
        // Hindernisse
        // ==============================================
        private void SpawnObstacle(Transform parent, float zPosition)
        {
            if (obstaclePrefabs == null || obstaclePrefabs.Length == 0) return;

            // Zufaelliges Hindernis und Spur waehlen
            int prefabIndex = Random.Range(0, obstaclePrefabs.Length);
            int lane = GetRandomLane();

            // Manchmal grosses Hindernis (blockiert 2 Spuren)
            if (largObstaclePrefabs != null && largObstaclePrefabs.Length > 0 && Random.value < 0.2f)
            {
                prefabIndex = Random.Range(0, largObstaclePrefabs.Length);
                SpawnObstacleAtLane(largObstaclePrefabs[prefabIndex], parent, zPosition, lane);
            }
            else
            {
                SpawnObstacleAtLane(obstaclePrefabs[prefabIndex], parent, zPosition, lane);
            }
        }

        private void SpawnObstacleAtLane(GameObject prefab, Transform parent, float zPosition, int lane)
        {
            float xPos = (lane - 1) * laneDistance;
            Vector3 position = new Vector3(xPos, 0, zPosition);

            GameObject obstacle = Instantiate(prefab, parent);
            obstacle.transform.localPosition = position;
            obstacle.tag = "Obstacle";
        }

        // ==============================================
        // Items
        // ==============================================
        private void SpawnItem(GameObject prefab, Transform parent, float zPosition, int lane)
        {
            if (prefab == null) return;

            float xPos = (lane - 1) * laneDistance;
            Vector3 position = new Vector3(xPos, 0.5f, zPosition); // Leicht ueber dem Boden

            GameObject item = Instantiate(prefab, parent);
            item.transform.localPosition = position;
        }

        private void SpawnCoinRow(Transform parent, float zPosition)
        {
            if (coinPrefab == null) return;

            int lane = GetRandomLane();
            int coinCount = Random.Range(3, 6);

            for (int i = 0; i < coinCount; i++)
            {
                SpawnItem(coinPrefab, parent, zPosition + (i * 2f), lane);
            }
        }

        // ==============================================
        // Quiz-Trigger
        // ==============================================
        private void SpawnQuizTrigger(Transform parent, float zPosition)
        {
            GameObject prefab = GetRandomTriggerPrefab();
            if (prefab == null) return;

            // Trigger sind meist in der Mitte oder ueber der Strasse
            Vector3 position = new Vector3(0, 0, zPosition);

            GameObject trigger = Instantiate(prefab, parent);
            trigger.transform.localPosition = position;
            trigger.tag = "QuizTrigger";

            // VisualTrigger-Komponente hinzufuegen falls nicht vorhanden
            if (trigger.GetComponent<VisualTrigger>() == null)
            {
                VisualTrigger vt = trigger.AddComponent<VisualTrigger>();
                vt.TriggerType = GetTriggerTypeFromPrefab(prefab);
            }
        }

        private GameObject GetRandomTriggerPrefab()
        {
            GameObject[] triggers = new GameObject[] { bridgePrefab, treePrefab, housePrefab };
            var validTriggers = System.Array.FindAll(triggers, t => t != null);

            if (validTriggers.Length == 0) return null;

            return validTriggers[Random.Range(0, validTriggers.Length)];
        }

        private string GetTriggerTypeFromPrefab(GameObject prefab)
        {
            if (prefab == bridgePrefab) return "bridge";
            if (prefab == treePrefab) return "tree";
            if (prefab == housePrefab) return "house";
            return "unknown";
        }

        // ==============================================
        // Helper
        // ==============================================
        private int GetRandomLane()
        {
            return Random.Range(0, 3); // 0, 1, oder 2
        }

        public void ResetSpawner()
        {
            lastObstacleZ = 0f;
            quizTriggerCount = 0;
            UpdateFromDifficulty();
        }
    }
}
