using System.Collections;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.Events;
using DG.Tweening;
using TMPro;

namespace com.al_arcade.mcq
{
    using shared;

    [AddComponentMenu("Science Street/MCQ Prefab Builder")]
    public class McqPrefabBuilder : MonoBehaviour
    {


        [Header("Scene Environment")]
        [Tooltip("Your full road/environment prefab. Spawned at origin.")]
        [SerializeField] private GameObject environmentPrefab;

        [Header("Camera")]
        [SerializeField] private Vector3 cameraOffset = new Vector3(0, 5f, -8f);
        [SerializeField] private Vector3 cameraLookOffset = new Vector3(0, 1.5f, 12f);
        [SerializeField] private float cameraSmoothSpeed = 6f;
        [SerializeField] private Color cameraBgColor = new Color32(180, 200, 240, 255);


        [Header("Lighting")]
        [SerializeField] private GameObject directionalLightPrefab;
        [SerializeField] private GameObject[] extraLightPrefabs;
        [SerializeField] private Color ambientColor = new Color32(80, 85, 110, 255);


        [Header("Player")]
        [Tooltip("Your player prefab. MUST have McqPlayerRunner + Rigidbody + Collider.\n" +
                 "Tag it 'Player'. If null, a procedural player is created.")]
        [SerializeField] private GameObject playerPrefab;
        [SerializeField] private Vector3 playerSpawnPosition = Vector3.zero;
        [SerializeField] private GameObject competitorPrefab;


        [Header("Answer Gate")]
        [Tooltip("Your gate prefab. MUST have McqGateController.\n" +
                 "If null, the procedural gate is used.")]
        [SerializeField] private GameObject gatePrefab;


        [Header("Question Display")]
        [Tooltip("Your question display prefab. MUST have McqQuestionDisplay.\n" +
                 "If null, a procedural one is created.")]
        [SerializeField] private GameObject questionDisplayPrefab;
        [SerializeField] private Vector3 questionDisplayOffset = new Vector3(0, 8, 10);


        [Header("UI Canvas")]
        [Tooltip("Your Canvas prefab. MUST have McqUIManager with all references wired.\n" +
                 "If null, procedural UI is created.")]
        [SerializeField] private GameObject canvasPrefab;


        [Header("Audio — SFX Clips")]
        [SerializeField] private AudioClip sfxCorrect;
        [SerializeField] private AudioClip sfxWrong;
        [SerializeField] private AudioClip sfxClick;
        [SerializeField] private AudioClip sfxVictory;
        [SerializeField] private AudioClip sfxDefeat;
        [SerializeField] private AudioClip sfxWhoosh;
        [SerializeField] private AudioClip sfxPop;
        [SerializeField] private AudioClip sfxCheer;
        [SerializeField] private AudioClip sfxCountdown;


        [Header("Particles")]
        [SerializeField] private ParticleSystem correctBurstParticle;
        [SerializeField] private ParticleSystem wrongBurstParticle;
        [SerializeField] private ParticleSystem confettiParticle;
        [SerializeField] private ParticleSystem sparksParticle;
        [SerializeField] private ParticleSystem starBurstParticle;


        [Header("Arabic Font")]
        [SerializeField] private TMP_FontAsset arabicFont;


        [Header("Game Settings")]
        [SerializeField] private string buildType = "scistreet";
        [SerializeField] private int gradeId = 0;
        [SerializeField] private int questionCount = 10;
        [SerializeField] private string classCode = "";
        [SerializeField] private float runSpeed = 12f;
        [SerializeField] private int lives = 3;

        [Header("Debug")]
        [SerializeField] private bool useOfflineTestData = false;


        private McqGameManager _gm;
        private McqPlayerRunner _player;
        private McqQuestionDisplay _questionDisplay;
        private McqUIManager _uiManager;
        private McqCompetitor _competitor;

        private void Start()
        {
            DOTween.Init();
            if (arabicFont != null) SSFontManager.Font = arabicFont;
            StartCoroutine(BuildEverything());
        }

        private IEnumerator BuildEverything()
        {
            Debug.Log("═══ MCQ Prefab Builder — Starting ═══");


            if (FindObjectOfType<EventSystem>() == null)
            {
                var es = new GameObject("EventSystem");
                es.AddComponent<EventSystem>();
                es.AddComponent<StandaloneInputModule>();
            }


            SSApiManager.EnsureInstance();
            SetupAudioManager();
            SetupParticleManager();

            var session = SSGameSession.EnsureInstance();
            session.buildType = buildType;
            session.gradeId = gradeId;
            session.questionCount = questionCount;
            session.classCode = classCode;
            yield return null;


            if (environmentPrefab != null)
                Instantiate(environmentPrefab, Vector3.zero, Quaternion.identity);
            yield return null;


            if (playerPrefab != null)
            {
                var playerObj = Instantiate(playerPrefab, playerSpawnPosition, Quaternion.identity);
                playerObj.name = "Player";
                if (!playerObj.CompareTag("Player"))
                    playerObj.tag = "Player";

                _player = playerObj.GetComponent<McqPlayerRunner>();
                if (_player == null)
                {
                    Debug.LogError("[MCQ] Player prefab missing McqPlayerRunner!");
                    yield break;
                }


                var rb = playerObj.GetComponent<Rigidbody>();
                if (rb == null) rb = playerObj.AddComponent<Rigidbody>();
                rb.isKinematic = true;
                rb.useGravity = false;
            }
            else
            {
                var obj = new GameObject("Player");
                obj.tag = "Player";
                obj.transform.position = playerSpawnPosition;
                _player = obj.AddComponent<McqPlayerRunner>();
                _player.BuildDefaultVisuals();
                var rb = obj.GetComponent<Rigidbody>();
                if (rb == null) rb = obj.AddComponent<Rigidbody>();
                rb.isKinematic = true;
                rb.useGravity = false;
            }

            if (competitorPrefab != null)
            {
                var competitorObj = Instantiate(competitorPrefab, playerSpawnPosition, Quaternion.identity);
                _competitor = competitorObj.GetComponent<McqCompetitor>();
            }
            yield return null;


            if (questionDisplayPrefab != null)
            {
                var qdObj = Instantiate(questionDisplayPrefab,
                    _player.transform.position + questionDisplayOffset,
                    Quaternion.identity);
                qdObj.name = "QuestionDisplay";
                _questionDisplay = qdObj.GetComponent<McqQuestionDisplay>();
                if (_questionDisplay == null)
                {
                    Debug.LogError("[MCQ] QuestionDisplay prefab missing McqQuestionDisplay!");
                    yield break;
                }
                _questionDisplay.Build(_player.transform, true);
            }
            else
            {
                var obj = new GameObject("QuestionDisplay");
                obj.transform.position = _player.transform.position + questionDisplayOffset;
                _questionDisplay = obj.AddComponent<McqQuestionDisplay>();
                _questionDisplay.Build(_player.transform);
            }
            yield return null;


            if (canvasPrefab != null)
            {
                var canvasObj = Instantiate(canvasPrefab);
                canvasObj.name = "McqUI";
                _uiManager = canvasObj.GetComponent<McqUIManager>();
                if (_uiManager == null)
                {
                    Debug.LogError("[MCQ] Canvas prefab missing McqUIManager!");
                    yield break;
                }
            }
            else
            {
                var obj = new GameObject("McqUI");
                _uiManager = obj.AddComponent<McqUIManager>();
                _uiManager.BuildUI();
            }

            if (_uiManager.onRestartClicked == null)
                _uiManager.onRestartClicked = new UnityEvent();
            yield return null;


            var gmObj = new GameObject("McqGameManager");
            _gm = gmObj.AddComponent<McqGameManager>();
            _gm.player = _player;
            _gm.competitor = _competitor;
            _gm.questionDisplay = _questionDisplay;
            _gm.uiManager = _uiManager;
            _gm.gateParent = new GameObject("Gates").transform;
            _gm.prefabBuilder = this;

            _uiManager.onRestartClicked.AddListener(OnRestartClicked);
            yield return null;


            SetupCamera();
            yield return null;


            SetupLighting();
            yield return null;

            Debug.Log("═══ MCQ Ready — A/D or ←/→ to steer ═══");
            yield return new WaitForSeconds(0.3f);

            if (useOfflineTestData)
                _gm.StartWithQuestions(GetTestQuestions());
            else
                _gm.StartGame();
        }


        private void SetupCamera()
        {
            var cam = Camera.main;
            if (cam == null) return;
            //cam.clearFlags = CameraClearFlags.SolidColor;
            //cam.backgroundColor = cameraBgColor;

            var follower = cam.GetComponent<McqCameraFollow>();
            if (follower == null)
                follower = cam.gameObject.AddComponent<McqCameraFollow>();

            follower.target = _player != null ? _player.transform : null;
            follower.offset = cameraOffset;
            follower.lookOffset = cameraLookOffset;
            follower.smoothSpeed = cameraSmoothSpeed;
        }

        private void SetupLighting()
        {
            if (directionalLightPrefab != null)
                Instantiate(directionalLightPrefab);

            if (extraLightPrefabs != null)
                foreach (var lp in extraLightPrefabs)
                    if (lp != null) Instantiate(lp);

            RenderSettings.ambientMode = UnityEngine.Rendering.AmbientMode.Flat;
            RenderSettings.ambientLight = ambientColor;
        }

        private void SetupAudioManager()
        {
            var a = SSAudioManager.EnsureInstance();
            if (sfxCorrect   != null) a.sfxCorrect   = sfxCorrect;
            if (sfxWrong     != null) a.sfxWrong     = sfxWrong;
            if (sfxClick     != null) a.sfxClick     = sfxClick;
            if (sfxVictory   != null) a.sfxVictory   = sfxVictory;
            if (sfxDefeat    != null) a.sfxDefeat    = sfxDefeat;
            if (sfxWhoosh    != null) a.sfxWhoosh    = sfxWhoosh;
            if (sfxPop       != null) a.sfxPop       = sfxPop;
            if (sfxCheer     != null) a.sfxCheer     = sfxCheer;
            if (sfxCountdown != null) a.sfxCountdown = sfxCountdown;
        }

        private void SetupParticleManager()
        {
            var p = SSParticleManager.EnsureInstance();
            if (correctBurstParticle != null) p.correctBurstPrefab = correctBurstParticle;
            if (wrongBurstParticle   != null) p.wrongBurstPrefab   = wrongBurstParticle;
            if (confettiParticle     != null) p.confettiPrefab     = confettiParticle;
            if (sparksParticle       != null) p.sparksPrefab       = sparksParticle;
            if (starBurstParticle    != null) p.starBurstPrefab    = starBurstParticle;
        }

        private void OnRestartClicked()
        {
            if (_gm != null) _gm.ResetGame();
            if (_player != null) _player.ResetToStart();
            if (_competitor != null) _competitor.ResetToStart();
            SetupCamera();
            if (_gm != null) _gm.StartGame();
        }

        public GameObject GetGatePrefab()
        {
            return gatePrefab;
        }

        private McqQuestion[] GetTestQuestions()
        {
            return new McqQuestion[]
            {
                new() { id="1", question_text="ما هي عاصمة مصر؟",
                    answer1="القاهرة", answer2="الإسكندرية",
                    answer3="أسوان", answer4="المنصورة", source="جغرافيا" },
                new() { id="2", question_text="كم عدد كواكب المجموعة الشمسية؟",
                    answer1="8", answer2="9",
                    answer3="7", answer4="10", source="علوم" },
                new() { id="3", question_text="ما هو أكبر محيط في العالم؟",
                    answer1="المحيط الهادي", answer2="المحيط الأطلسي",
                    answer3="المحيط الهندي", answer4="المحيط المتجمد", source="جغرافيا" },
            };
        }
    }
}
