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

namespace com.al_arcade.cs
{
    using shared;

    [AddComponentMenu("Science Street/CS Demo Builder")]
    public class CsDemoBuilder : MonoBehaviour
    {
        [Header("Build Configuration")]
        [SerializeField] private string buildType = "scistreet";
        [SerializeField] private int gradeId = 0;
        [SerializeField] private int questionCount = 8;
        [SerializeField] private string classCode = "";

        [Header("Arabic Font")]
        [Tooltip("Drag your Arabic TMP_FontAsset here")]
        [SerializeField] private TMP_FontAsset arabicFont;

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

        private CsGameManager _gm;
        private CsBotController _bot;
        private CsUIManager _uiManager;

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

        private IEnumerator BuildEverything()
        {
            Debug.Log("═══════════════════════════════════════════");
            Debug.Log("  Science Street — CS Demo Builder");
            Debug.Log("  Correct-the-Sentence Game");
            Debug.Log("═══════════════════════════════════════════");


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


            SSApiManager.EnsureInstance();
            SSAudioManager.EnsureInstance();
            SSParticleManager.EnsureInstance();

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


            BuildScene();
            yield return null;


            SetupCamera();
            yield return null;


            var botObj = new GameObject("Bot");
            botObj.transform.position = new Vector3(0, 0, 0);
            _bot = botObj.AddComponent<CsBotController>();
            _bot.Build();
            yield return null;


            var wordContainer = new GameObject("WordContainer");
            wordContainer.transform.position = Vector3.zero;
            yield return null;


            var uiObj = new GameObject("CsUI");
            _uiManager = uiObj.AddComponent<CsUIManager>();
            _uiManager.BuildUI();


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

            yield return null;


            var gmObj = new GameObject("CsGameManager");
            _gm = gmObj.AddComponent<CsGameManager>();
            _gm.bot = _bot;
            _gm.uiManager = _uiManager;
            _gm.wordContainer = wordContainer.transform;


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


            SetupLighting();
            yield return null;

            Debug.Log("═══════════════════════════════════════════");
            Debug.Log("  CS Game built! Starting...");
            Debug.Log("  Click words to find the wrong one,");
            Debug.Log("  then drag the correct replacement.");
            Debug.Log("═══════════════════════════════════════════");

            yield return new WaitForSeconds(0.5f);


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


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


        private void BuildScene()
        {
            Camera.main.clearFlags = CameraClearFlags.SolidColor;
            Camera.main.backgroundColor = new Color32(30, 30, 60, 255);

            var shader = GetShader();


            var ground = GameObject.CreatePrimitive(PrimitiveType.Cube);
            ground.name = "Ground";
            ground.transform.position = new Vector3(0, -0.05f, 0);
            ground.transform.localScale = new Vector3(20, 0.1f, 15);
            ground.GetComponent<Renderer>().material =
                new Material(shader) { color = new Color32(40, 40, 65, 255) };


            var platform = GameObject.CreatePrimitive(PrimitiveType.Cylinder);
            platform.name = "Platform";
            platform.transform.position = new Vector3(0, 0.05f, 0);
            platform.transform.localScale = new Vector3(3f, 0.1f, 3f);
            Destroy(platform.GetComponent<Collider>());
            platform.GetComponent<Renderer>().material =
                new Material(shader) { color = SSColorPalette.WithAlpha(SSColorPalette.Primary, 0.6f) };


            var ring = GameObject.CreatePrimitive(PrimitiveType.Cylinder);
            ring.name = "Ring";
            ring.transform.position = new Vector3(0, 0.04f, 0);
            ring.transform.localScale = new Vector3(3.5f, 0.08f, 3.5f);
            Destroy(ring.GetComponent<Collider>());
            var ringMat = new Material(shader)
                { color = SSColorPalette.WithAlpha(SSColorPalette.Accent, 0.3f) };
            ring.GetComponent<Renderer>().material = ringMat;
            ringMat.DOFade(0.1f, 1.5f).SetEase(Ease.InOutSine)
                .SetLoops(-1, LoopType.Yoyo);


            for (int i = 0; i < 20; i++)
            {
                var deco = GameObject.CreatePrimitive(
                    Random.value > 0.5f ? PrimitiveType.Cube : PrimitiveType.Sphere);
                deco.name = $"BgDeco_{i}";
                float x = Random.Range(-9f, 9f);
                float y = Random.Range(1f, 7f);
                float z = Random.Range(3f, 10f);
                deco.transform.position = new Vector3(x, y, z);
                float scale = Random.Range(0.2f, 0.8f);
                deco.transform.localScale = Vector3.one * scale;
                deco.transform.rotation = Random.rotation;
                Destroy(deco.GetComponent<Collider>());

                Color[] colors = {
                    SSColorPalette.Primary, SSColorPalette.Accent,
                    SSColorPalette.Success, SSColorPalette.Info
                };
                var dMat = new Material(shader)
                {
                    color = SSColorPalette.WithAlpha(
                        colors[Random.Range(0, colors.Length)],
                        Random.Range(0.05f, 0.2f))
                };
                deco.GetComponent<Renderer>().material = dMat;

                float spd = Random.Range(1.5f, 3f);
                float amt = Random.Range(0.3f, 0.8f);
                deco.transform.DOMoveY(y + amt, spd)
                    .SetEase(Ease.InOutSine).SetLoops(-1, LoopType.Yoyo);
                deco.transform.DORotate(
                    new Vector3(Random.Range(-30, 30), Random.Range(-30, 30),
                        Random.Range(-30, 30)),
                    Random.Range(5f, 10f), RotateMode.FastBeyond360)
                    .SetLoops(-1, LoopType.Incremental).SetEase(Ease.Linear);
            }


            for (float x = -9; x <= 9; x += 3)
            {
                var line = GameObject.CreatePrimitive(PrimitiveType.Cube);
                line.name = "GridX";
                line.transform.position = new Vector3(x, 0.01f, 3);
                line.transform.localScale = new Vector3(0.02f, 0.01f, 15);
                Destroy(line.GetComponent<Collider>());
                line.GetComponent<Renderer>().material = new Material(shader)
                    { color = SSColorPalette.WithAlpha(SSColorPalette.Primary, 0.08f) };
            }
            for (float z = -2; z <= 12; z += 3)
            {
                var line = GameObject.CreatePrimitive(PrimitiveType.Cube);
                line.name = "GridZ";
                line.transform.position = new Vector3(0, 0.01f, z);
                line.transform.localScale = new Vector3(20, 0.01f, 0.02f);
                Destroy(line.GetComponent<Collider>());
                line.GetComponent<Renderer>().material = new Material(shader)
                    { color = SSColorPalette.WithAlpha(SSColorPalette.Primary, 0.08f) };
            }


            var floorText = new GameObject("FloorLabel");
            floorText.transform.position = new Vector3(0, 0.02f, -3);
            floorText.transform.rotation = Quaternion.Euler(90, 0, 0);
            var ft = floorText.AddComponent<ArabicTextMeshPro>();
            ft.arabicText = "SCIENCE STREET";
            ft.fontSize = 6;
            ft.alignment = TMPro.TextAlignmentOptions.Center;
            ft.color = SSColorPalette.WithAlpha(SSColorPalette.Accent, 0.08f);
            ft.fontStyle = TMPro.FontStyles.Bold;
            ft.rectTransform.sizeDelta = new Vector2(15, 2);
            SSFontManager.Apply(ft);
        }

        private void SetupCamera()
        {
            var cam = Camera.main;
            if (cam == null) return;
            cam.transform.position = new Vector3(0, 4f, -6f);
            cam.transform.rotation = Quaternion.Euler(25, 0, 0);
            cam.fieldOfView = 60;
            cam.nearClipPlane = 0.1f;
        }

        private void SetupLighting()
        {
            var existing = FindObjectOfType<Light>();
            Light dirLight;
            if (existing != null)
                dirLight = existing;
            else
            {
                var lo = new GameObject("DirLight");
                dirLight = lo.AddComponent<Light>();
            }
            dirLight.type = LightType.Directional;
            dirLight.transform.rotation = Quaternion.Euler(50, -30, 0);
            dirLight.color = new Color32(180, 190, 220, 255);
            dirLight.intensity = 0.9f;
            dirLight.shadows = LightShadows.Soft;


            var accent = new GameObject("AccentLight");
            var aLight = accent.AddComponent<Light>();
            aLight.type = LightType.Point;
            aLight.transform.position = new Vector3(0, 5, -2);
            aLight.range = 10;
            aLight.intensity = 0.8f;
            aLight.color = SSColorPalette.Accent;


            var back = new GameObject("BackLight");
            var bLight = back.AddComponent<Light>();
            bLight.type = LightType.Point;
            bLight.transform.position = new Vector3(0, 3, 5);
            bLight.range = 12;
            bLight.intensity = 0.4f;
            bLight.color = SSColorPalette.Primary;

            RenderSettings.ambientMode = UnityEngine.Rendering.AmbientMode.Flat;
            RenderSettings.ambientLight = new Color32(40, 42, 60, 255);
        }


        private CsQuestion[] GetTestQuestions()
        {
            return new CsQuestion[]
            {
                new()
                {
                    id = "1", source = "علوم - الوحدة 3",
                    wrong_word = "القمر", correct_answer = "الشمس",
                    words = new CsWord[]
                    {
                        new() { word_text = "القمر",    position = 0, is_wrong = true  },
                        new() { word_text = "مصدر",     position = 1, is_wrong = false },
                        new() { word_text = "الضوء",    position = 2, is_wrong = false },
                        new() { word_text = "والحرارة", position = 3, is_wrong = false },
                        new() { word_text = "للأرض",    position = 4, is_wrong = false },
                    },
                    options = new CsOption[]
                    {
                        new() { option_text = "الشمس",   is_correct = true  },
                        new() { option_text = "النجوم",   is_correct = false },
                        new() { option_text = "الكواكب",  is_correct = false },
                        new() { option_text = "المذنبات", is_correct = false },
                    }
                },
                new()
                {
                    id = "2", source = "كيمياء",
                    wrong_word = "الأكسجين", correct_answer = "النيتروجين",
                    words = new CsWord[]
                    {
                        new() { word_text = "يتكون",    position = 0, is_wrong = false },
                        new() { word_text = "معظم",     position = 1, is_wrong = false },
                        new() { word_text = "الغلاف",   position = 2, is_wrong = false },
                        new() { word_text = "الجوي",    position = 3, is_wrong = false },
                        new() { word_text = "من",       position = 4, is_wrong = false },
                        new() { word_text = "الأكسجين", position = 5, is_wrong = true  },
                    },
                    options = new CsOption[]
                    {
                        new() { option_text = "النيتروجين",        is_correct = true  },
                        new() { option_text = "ثاني أكسيد الكربون", is_correct = false },
                        new() { option_text = "الهيليوم",           is_correct = false },
                    }
                },
                new()
                {
                    id = "3", source = "أحياء",
                    wrong_word = "الجذر", correct_answer = "الورقة",
                    words = new CsWord[]
                    {
                        new() { word_text = "الجذر",   position = 0, is_wrong = true  },
                        new() { word_text = "هي",      position = 1, is_wrong = false },
                        new() { word_text = "الجزء",   position = 2, is_wrong = false },
                        new() { word_text = "المسؤول", position = 3, is_wrong = false },
                        new() { word_text = "عن",      position = 4, is_wrong = false },
                        new() { word_text = "البناء",  position = 5, is_wrong = false },
                        new() { word_text = "الضوئي",  position = 6, is_wrong = false },
                    },
                    options = new CsOption[]
                    {
                        new() { option_text = "الورقة", is_correct = true  },
                        new() { option_text = "الساق",  is_correct = false },
                        new() { option_text = "الزهرة", is_correct = false },
                        new() { option_text = "البذرة", is_correct = false },
                    }
                },
                new()
                {
                    id = "4", source = "فيزياء",
                    wrong_word = "تنخفض", correct_answer = "ترتفع",
                    words = new CsWord[]
                    {
                        new() { word_text = "تنخفض",  position = 0, is_wrong = true  },
                        new() { word_text = "درجة",   position = 1, is_wrong = false },
                        new() { word_text = "غليان",  position = 2, is_wrong = false },
                        new() { word_text = "الماء",  position = 3, is_wrong = false },
                        new() { word_text = "عند",    position = 4, is_wrong = false },
                        new() { word_text = "مئة",    position = 5, is_wrong = false },
                        new() { word_text = "سلسيوس", position = 6, is_wrong = false },
                    },
                    options = new CsOption[]
                    {
                        new() { option_text = "ترتفع",  is_correct = true  },
                        new() { option_text = "تثبت",   is_correct = false },
                        new() { option_text = "تتذبذب", is_correct = false },
                    }
                },
                new()
                {
                    id = "5", source = "جغرافيا",
                    wrong_word = "خمس", correct_answer = "سبع",
                    words = new CsWord[]
                    {
                        new() { word_text = "يتكون", position = 0, is_wrong = false },
                        new() { word_text = "العالم", position = 1, is_wrong = false },
                        new() { word_text = "من",     position = 2, is_wrong = false },
                        new() { word_text = "خمس",    position = 3, is_wrong = true  },
                        new() { word_text = "قارات",  position = 4, is_wrong = false },
                    },
                    options = new CsOption[]
                    {
                        new() { option_text = "ست",  is_correct = false },
                        new() { option_text = "سبع", is_correct = true  },
                        new() { option_text = "ثمان", is_correct = false },
                    }
                },
            };
        }

        private Shader GetShader()
        {
            return Shader.Find("Universal Render Pipeline/Lit")
                ?? Shader.Find("Standard")
                ?? Shader.Find("Unlit/Color");
        }
    }
}
