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

namespace com.al_arcade.tf
{
    using shared;

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


        [Header("Scene Environment")]
        [Tooltip("Your full factory environment prefab.")]
        [SerializeField] private GameObject environmentPrefab;

        [Header("Camera")]
        [SerializeField] private Vector3 cameraPosition = new Vector3(-11f, 3.5f, 12f);
        [SerializeField] private Vector3 cameraLookAt = new Vector3(0f, 1.5f, 12f);
        [SerializeField] private float cameraFOV = 55f;
        [SerializeField] private Color cameraBgColor = new Color32(70, 80, 110, 255);


        [Header("Lighting")]
        [SerializeField] private GameObject directionalLightPrefab;
        [SerializeField] private GameObject[] extraLightPrefabs;
        [SerializeField] private Color ambientColor = new Color32(75, 78, 95, 255);


        [Header("Production Line")]
        [Tooltip("Your production line prefab. MUST have TfProductionLine.\n" +
                 "If null, a procedural one is created.")]
        [SerializeField] private GameObject productionLinePrefab;
        [SerializeField] private Vector3 productionLinePosition = new Vector3(0, 0, 2);


        [Header("Question Screen")]
        [Tooltip("Your question screen prefab. MUST have TfQuestionScreen.\n" +
                 "If null, a procedural one is created.")]
        [SerializeField] private GameObject questionScreenPrefab;
        [SerializeField] private Vector3 questionScreenPosition = new Vector3(0, 5f, 12f);


        [Header("Hands / Buttons")]
        [Tooltip("Your hands prefab. MUST have TfHandController.\n" +
                 "If null, procedural hands are created.")]
        [SerializeField] private GameObject handsPrefab;


        [Header("UI Canvas")]
        [Tooltip("Your Canvas prefab. MUST have TfUIManager 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 sfxSlam;


        [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 = 15;
        [SerializeField] private string classCode = "";
        [SerializeField] private int stepsToWin = 5;
        [SerializeField] private float stepDistance = 3f;

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


        private TfGameManager _gm;
        private TfHandController _handController;
        private TfProductionLine _productionLine;
        private TfQuestionScreen _questionScreen;
        private TfUIManager _uiManager;

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

        private IEnumerator BuildEverything()
        {
            Debug.Log("═══ TF 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;


            SetupCamera();
            yield return null;


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


            SetupLighting();
            yield return null;


            if (productionLinePrefab != null)
            {
                var lineObj = Instantiate(productionLinePrefab,
                    productionLinePosition, Quaternion.identity);
                lineObj.name = "ProductionLine";
                _productionLine = lineObj.GetComponent<TfProductionLine>();
                if (_productionLine == null)
                {
                    Debug.LogError("[TF] ProductionLine prefab missing TfProductionLine!");
                    yield break;
                }
            }
            else
            {
                var lineObj = new GameObject("ProductionLine");
                lineObj.transform.position = productionLinePosition;
                _productionLine = lineObj.AddComponent<TfProductionLine>();
                _productionLine.Build(stepsToWin, stepDistance, cameraPosition);
            }
            yield return null;


            if (questionScreenPrefab != null)
            {
                var screenObj = Instantiate(questionScreenPrefab,
                    questionScreenPosition, Quaternion.identity);
                screenObj.name = "QuestionScreen";
                _questionScreen = screenObj.GetComponent<TfQuestionScreen>();
                if (_questionScreen == null)
                {
                    Debug.LogError("[TF] QuestionScreen prefab missing TfQuestionScreen!");
                    yield break;
                }
            }
            else
            {
                var screenObj = new GameObject("QuestionScreen");
                _questionScreen = screenObj.AddComponent<TfQuestionScreen>();
                _questionScreen.Build(questionScreenPosition, cameraPosition);
            }
            yield return null;


            if (handsPrefab != null)
            {
                var handsObj = Instantiate(handsPrefab);
                handsObj.name = "Hands";
                _handController = handsObj.GetComponent<TfHandController>();
                if (_handController == null)
                {
                    Debug.LogError("[TF] Hands prefab missing TfHandController!");
                    yield break;
                }
            }
            else
            {
                var handsObj = new GameObject("Hands");
                _handController = handsObj.AddComponent<TfHandController>();
                _handController.Build(Camera.main);
            }
            yield return null;


            if (canvasPrefab != null)
            {
                var canvasObj = Instantiate(canvasPrefab);
                canvasObj.name = "TfUI";
                _uiManager = canvasObj.GetComponentInChildren<TfUIManager>();
                if (_uiManager == null)
                {
                    Debug.LogError("[TF] Canvas prefab missing TfUIManager!");
                    yield break;
                }
            }
            else
            {
                var uiObj = new GameObject("TfUI");
                _uiManager = uiObj.AddComponent<TfUIManager>();
                _uiManager.BuildUI();
            }

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


            var gmObj = new GameObject("TfGameManager");
            _gm = gmObj.AddComponent<TfGameManager>();
            _gm.handController = _handController;
            _gm.productionLine = _productionLine;
            _gm.questionScreen = _questionScreen;
            _gm.uiManager = _uiManager;
            _uiManager.onRestartClicked.AddListener(OnRestartClicked);
            yield return null;

            Debug.Log("═══ TF Ready! A/← = True  D/→ = False ═══");
            yield return new WaitForSeconds(0.5f);

            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;
            cam.transform.position = cameraPosition;
            cam.transform.LookAt(cameraLookAt);
            cam.fieldOfView = cameraFOV;
            cam.nearClipPlane = 0.1f;
        }

        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 (sfxSlam    != null) a.sfxSlam    = sfxSlam;
        }

        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();
            SetupCamera();
            if (_gm != null) _gm.StartGame();
        }

        private TfQuestion[] GetTestQuestions()
        {
            return new TfQuestion[]
            {
                new() { id="1", question_text="الشمس تدور حول الأرض",
                    is_true=false, source="علوم" },
                new() { id="2", question_text="الماء يتكون من الهيدروجين والأكسجين",
                    is_true=true, source="كيمياء" },
                new() { id="3", question_text="القمر ينير بذاته",
                    is_true=false, source="فلك" },
                new() { id="4", question_text="النباتات تحتاج ضوء الشمس لعملية البناء الضوئي",
                    is_true=true, source="أحياء" },
                new() { id="5", question_text="الحديد يتمدد بالحرارة",
                    is_true=true, source="فيزياء" },
            };
        }
    }
}
