using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.Events;
using DG.Tweening;
using ALArcade.ArabicTMP;

namespace com.al_arcade.cs
{
    using shared;

    public class CsUIManager : MonoBehaviour
    {
        private Canvas _canvas;
        private CanvasGroup _gameUI, _loadingUI, _errorUI, _resultsUI;
        private CanvasGroup _optionsPanel, _feedbackGroup;

        private ArabicTextMeshProUGUI _scoreText, _streakText, _progressText, _hintText;
        private ArabicTextMeshProUGUI _feedbackText;
        private Image _feedbackBg, _progressFill;

        private ArabicTextMeshProUGUI _loadingText, _errorText;
        private ArabicTextMeshProUGUI _resultTitle, _resultScore, _resultStats;

        private Transform _optionsContainer;
        private List<CsOptionDraggable> _activeOptions = new();

        [Header("Events")]
        public UnityEvent onRestartClicked;


        public void BuildUI()
        {
            var co = new GameObject("CsCanvas");
            co.transform.SetParent(transform);
            _canvas = co.AddComponent<Canvas>();
            _canvas.renderMode = RenderMode.ScreenSpaceOverlay;
            _canvas.sortingOrder = 100;

            var sc = co.AddComponent<CanvasScaler>();
            sc.uiScaleMode = CanvasScaler.ScaleMode.ScaleWithScreenSize;
            sc.referenceResolution = new Vector2(1920, 1080);
            sc.matchWidthOrHeight = 0.5f;
            co.AddComponent<GraphicRaycaster>();

            BuildGameHUD(co.transform);
            BuildOptionsPanel(co.transform);
            BuildFeedbackOverlay(co.transform);
            BuildLoadingPanel(co.transform);
            BuildErrorPanel(co.transform);
            BuildResultsPanel(co.transform);

            _gameUI.alpha = 0; _gameUI.gameObject.SetActive(false);
            _loadingUI.alpha = 0; _loadingUI.gameObject.SetActive(false);
            _errorUI.alpha = 0; _errorUI.gameObject.SetActive(false);
            _resultsUI.alpha = 0; _resultsUI.gameObject.SetActive(false);
            _optionsPanel.alpha = 0; _optionsPanel.gameObject.SetActive(false);
            _feedbackGroup.alpha = 0;
        }


        private void BuildGameHUD(Transform parent)
        {
            var go = MkFull(parent, "GameUI");
            _gameUI = go.AddComponent<CanvasGroup>();


            var topBar = new GameObject("TopBar");
            topBar.transform.SetParent(go.transform, false);
            var tbr = topBar.AddComponent<RectTransform>();
            tbr.anchorMin = new Vector2(0, 1); tbr.anchorMax = new Vector2(1, 1);
            tbr.pivot = new Vector2(0.5f, 1);
            tbr.anchoredPosition = Vector2.zero; tbr.sizeDelta = new Vector2(0, 90);
            topBar.AddComponent<Image>().color =
                SSColorPalette.WithAlpha(SSColorPalette.PrimaryDark, 0.8f);

            _scoreText = MkTxt(topBar.transform, "Score", "0", 36,
                new Vector2(0, 1), new Vector2(40, -12), new Vector2(200, 50));
            _scoreText.color = SSColorPalette.Accent;
            _scoreText.fontStyle = TMPro.FontStyles.Bold;
            _scoreText.alignment = TMPro.TextAlignmentOptions.TopLeft;

            MkTxt(topBar.transform, "ScoreLbl", "النقاط", 14,
                new Vector2(0, 1), new Vector2(40, -55), new Vector2(100, 25))
                .color = SSColorPalette.WithAlpha(Color.white, 0.5f);

            _streakText = MkTxt(topBar.transform, "Streak", "", 26,
                new Vector2(0.5f, 1), new Vector2(0, -15), new Vector2(200, 50));
            _streakText.color = SSColorPalette.Warning;
            _streakText.alignment = TMPro.TextAlignmentOptions.Center;


            var pbg = MkFull(go.transform, "ProgressBg");
            var pr = pbg.GetComponent<RectTransform>();
            pr.anchorMin = new Vector2(0.25f, 1); pr.anchorMax = new Vector2(0.75f, 1);
            pr.pivot = new Vector2(0.5f, 1);
            pr.anchoredPosition = new Vector2(0, -95); pr.sizeDelta = new Vector2(0, 10);
            pbg.AddComponent<Image>().color = SSColorPalette.WithAlpha(Color.white, 0.08f);

            var fill = new GameObject("Fill");
            fill.transform.SetParent(pbg.transform, false);
            var fr = fill.AddComponent<RectTransform>();
            fr.anchorMin = Vector2.zero; fr.anchorMax = new Vector2(0, 1);
            fr.pivot = new Vector2(0, 0.5f);
            fr.offsetMin = fr.offsetMax = Vector2.zero;
            _progressFill = fill.AddComponent<Image>();
            _progressFill.color = SSColorPalette.Accent;

            _progressText = MkTxt(go.transform, "ProgTxt", "0 / 0", 14,
                new Vector2(0.5f, 1), new Vector2(0, -112), new Vector2(200, 25));
            _progressText.alignment = TMPro.TextAlignmentOptions.Center;
            _progressText.color = SSColorPalette.WithAlpha(Color.white, 0.5f);


            _hintText = MkTxt(go.transform, "Hint", "", 18,
                new Vector2(0.5f, 0), new Vector2(0, 200), new Vector2(600, 40));
            _hintText.alignment = TMPro.TextAlignmentOptions.Center;
            _hintText.color = SSColorPalette.WithAlpha(Color.white, 0.5f);
            _hintText.fontStyle = TMPro.FontStyles.Italic;
        }


        private void BuildOptionsPanel(Transform parent)
        {
            var go = new GameObject("OptionsPanel");
            go.transform.SetParent(parent, false);
            var r = go.AddComponent<RectTransform>();
            r.anchorMin = new Vector2(0, 0); r.anchorMax = new Vector2(1, 0);
            r.pivot = new Vector2(0.5f, 0);
            r.anchoredPosition = new Vector2(0, 20);
            r.sizeDelta = new Vector2(-80, 160);
            _optionsPanel = go.AddComponent<CanvasGroup>();
            go.AddComponent<Image>().color =
                SSColorPalette.WithAlpha(SSColorPalette.PrimaryDark, 0.85f);

            var layout = go.AddComponent<HorizontalLayoutGroup>();
            layout.spacing = 16;
            layout.padding = new RectOffset(30, 30, 20, 20);
            layout.childAlignment = TextAnchor.MiddleCenter;
            layout.childForceExpandWidth = true;
            layout.childForceExpandHeight = true;
            layout.childControlWidth = true;
            layout.childControlHeight = true;

            _optionsContainer = go.transform;

            MkTxt(parent, "OptionsLabel",
                "اسحب الإجابة الصحيحة إلى الكلمة الخاطئة ↑", 14,
                new Vector2(0.5f, 0), new Vector2(0, 185), new Vector2(500, 25))
                .color = SSColorPalette.WithAlpha(SSColorPalette.Accent, 0.6f);
        }


        private void BuildFeedbackOverlay(Transform parent)
        {
            var go = new GameObject("FeedbackOverlay");
            go.transform.SetParent(parent, false);
            var r = go.AddComponent<RectTransform>();
            r.anchorMin = new Vector2(0.2f, 0.4f);
            r.anchorMax = new Vector2(0.8f, 0.6f);
            r.sizeDelta = Vector2.zero;

            _feedbackGroup = go.AddComponent<CanvasGroup>();
            _feedbackGroup.blocksRaycasts = false;
            _feedbackGroup.interactable = false;

            _feedbackBg = go.AddComponent<Image>();
            _feedbackBg.color = SSColorPalette.WithAlpha(SSColorPalette.Success, 0.92f);

            _feedbackText = MkTxt(go.transform, "FeedbackTxt", "", 34,
                Vector2.zero, Vector2.zero, Vector2.zero);
            _feedbackText.rectTransform.anchorMin = Vector2.zero;
            _feedbackText.rectTransform.anchorMax = Vector2.one;
            _feedbackText.rectTransform.offsetMin = new Vector2(10, 5);
            _feedbackText.rectTransform.offsetMax = new Vector2(-10, -5);
            _feedbackText.alignment = TMPro.TextAlignmentOptions.Center;
            _feedbackText.color = Color.white;
            _feedbackText.fontStyle = TMPro.FontStyles.Bold;
            _feedbackText.enableWordWrapping = true;
        }


        private void BuildLoadingPanel(Transform parent)
        {
            var go = MkFull(parent, "LoadingUI");
            _loadingUI = go.AddComponent<CanvasGroup>();
            go.AddComponent<Image>().color =
                SSColorPalette.WithAlpha(SSColorPalette.PrimaryDark, 0.92f);
            _loadingText = MkTxt(go.transform, "Txt", "جاري التحميل...", 28,
                new Vector2(0.5f, 0.5f), Vector2.zero, new Vector2(500, 60));
            _loadingText.alignment = TMPro.TextAlignmentOptions.Center;
            _loadingText.color = Color.white;
        }


        private void BuildErrorPanel(Transform parent)
        {
            var go = MkFull(parent, "ErrorUI");
            _errorUI = go.AddComponent<CanvasGroup>();
            go.AddComponent<Image>().color =
                SSColorPalette.WithAlpha(SSColorPalette.Danger, 0.92f);
            _errorText = MkTxt(go.transform, "Txt", "خطأ", 24,
                new Vector2(0.5f, 0.5f), Vector2.zero, new Vector2(600, 100));
            _errorText.alignment = TMPro.TextAlignmentOptions.Center;
            _errorText.color = Color.white;
            _errorText.enableWordWrapping = true;
        }


        private void BuildResultsPanel(Transform parent)
        {
            var go = MkFull(parent, "ResultsUI");
            _resultsUI = go.AddComponent<CanvasGroup>();
            go.AddComponent<Image>().color =
                SSColorPalette.WithAlpha(SSColorPalette.PrimaryDark, 0.95f);

            _resultTitle = MkTxt(go.transform, "Title", "أحسنت! 🎉", 48,
                new Vector2(0.5f, 0.5f), new Vector2(0, 180), new Vector2(500, 70));
            _resultTitle.alignment = TMPro.TextAlignmentOptions.Center;
            _resultTitle.color = SSColorPalette.Accent;
            _resultTitle.fontStyle = TMPro.FontStyles.Bold;

            _resultScore = MkTxt(go.transform, "Score", "0", 72,
                new Vector2(0.5f, 0.5f), new Vector2(0, 90), new Vector2(300, 90));
            _resultScore.alignment = TMPro.TextAlignmentOptions.Center;
            _resultScore.color = Color.white;
            _resultScore.fontStyle = TMPro.FontStyles.Bold;

            _resultStats = MkTxt(go.transform, "Stats", "", 22,
                new Vector2(0.5f, 0.5f), new Vector2(0, -20), new Vector2(500, 80));
            _resultStats.alignment = TMPro.TextAlignmentOptions.Center;
            _resultStats.color = SSColorPalette.WithAlpha(Color.white, 0.7f);
            _resultStats.enableWordWrapping = true;


            var btn = new GameObject("RestartBtn");
            btn.transform.SetParent(go.transform, false);
            var br = btn.AddComponent<RectTransform>();
            br.anchorMin = br.anchorMax = new Vector2(0.5f, 0.5f);
            br.anchoredPosition = new Vector2(0, -110); br.sizeDelta = new Vector2(300, 60);
            btn.AddComponent<Image>().color = SSColorPalette.Accent;
            btn.AddComponent<Button>().onClick.AddListener(() =>
            {
                _resultsUI.DOFade(0, 0.3f).OnComplete(() =>
                    _resultsUI.gameObject.SetActive(false));
                onRestartClicked?.Invoke();
            });
            var bt = MkTxt(btn.transform, "BtnTxt", "إعادة اللعب 🔄", 24,
                Vector2.zero, Vector2.zero, Vector2.zero);
            bt.rectTransform.anchorMin = Vector2.zero;
            bt.rectTransform.anchorMax = Vector2.one;
            bt.rectTransform.offsetMin = bt.rectTransform.offsetMax = Vector2.zero;
            bt.alignment = TMPro.TextAlignmentOptions.Center;
            bt.color = SSColorPalette.TextDark;
            bt.fontStyle = TMPro.FontStyles.Bold;
        }


        public void ShowGameUI()
        { _gameUI.gameObject.SetActive(true); _gameUI.DOFade(1f, 0.3f); }

        public void SetScore(int score)
        {
            if (_scoreText == null) return;
            _scoreText.arabicText = score.ToString("N0");
            DOTween.Kill(_scoreText.transform, "sPunch");
            _scoreText.transform.DOPunchScale(Vector3.one * 0.2f, 0.3f, 6, 0.3f).SetId("sPunch");
        }

        public void SetStreak(int streak)
        {
            if (_streakText == null) return;
            _streakText.arabicText = streak > 1 ? $"🔥 ×{streak}" : "";
            if (streak > 1)
            {
                DOTween.Kill(_streakText.transform, "skPop");
                _streakText.transform.localScale = Vector3.one * 1.5f;
                _streakText.transform.DOScale(1f, 0.4f).SetEase(Ease.OutElastic).SetId("skPop");
            }
        }

        public void SetProgress(int current, int total)
        {
            if (_progressText != null) _progressText.arabicText = $"{current} / {total}";
            if (_progressFill != null && total > 0)
            {
                DOTween.Kill(_progressFill.rectTransform, "pFill");
                _progressFill.rectTransform.DOAnchorMax(new Vector2((float)current / total, 1f), 0.5f)
                    .SetEase(Ease.OutQuad).SetId("pFill");
            }
        }

        public void ShowHint(string hint)
        {
            if (_hintText == null) return;
            _hintText.arabicText = hint;
            DOTween.Kill(_hintText, "hintFade");
            _hintText.alpha = 0;
            _hintText.DOFade(1, 0.4f).SetId("hintFade");
        }

        public void ShowFeedback(string message, bool isCorrect)
        {
            if (_feedbackText != null) _feedbackText.arabicText = message;
            if (_feedbackBg != null)
                _feedbackBg.color = SSColorPalette.WithAlpha(
                    isCorrect ? SSColorPalette.Success : SSColorPalette.Danger, 0.92f);

            DOTween.Kill(_feedbackGroup, "fbAnim");
            _feedbackGroup.alpha = 0;
            var bgRect = _feedbackBg?.rectTransform;
            if (bgRect != null)
            {
                bgRect.localScale = new Vector3(0.3f, 0f, 1f);
                var seq = DOTween.Sequence().SetId("fbAnim");
                seq.Append(_feedbackGroup.DOFade(1f, 0.12f));
                seq.Join(bgRect.DOScaleX(1f, 0.25f).SetEase(Ease.OutBack));
                seq.Join(bgRect.DOScaleY(1f, 0.2f).SetEase(Ease.OutBack).SetDelay(0.04f));
                seq.AppendInterval(1f);
                seq.Append(_feedbackGroup.DOFade(0f, 0.3f));
            }
        }


        public void ShowOptions(CsOption[] options, CsWordButton targetWord)
        {
            ClearOptions();
            _optionsPanel.gameObject.SetActive(true);
            DOTween.Kill(_optionsPanel, "optFade");
            _optionsPanel.alpha = 0;
            _optionsPanel.DOFade(1f, 0.3f).SetId("optFade");

            var rect = _optionsPanel.GetComponent<RectTransform>();
            DOTween.Kill(rect, "optSlide");
            rect.anchoredPosition = new Vector2(rect.anchoredPosition.x, -100);
            rect.DOAnchorPosY(20, 0.4f).SetEase(Ease.OutBack).SetId("optSlide");

            if (options == null) return;
            for (int i = 0; i < options.Length; i++)
            {
                var opt = options[i];
                var optObj = new GameObject($"Option_{i}");
                optObj.transform.SetParent(_optionsContainer, false);
                optObj.AddComponent<RectTransform>().sizeDelta = new Vector2(200, 120);
                var draggable = optObj.AddComponent<CsOptionDraggable>();
                draggable.Setup(opt.option_text, opt.is_correct, _canvas, targetWord);
                _activeOptions.Add(draggable);
            }
        }

        public void HideOptions()
        {
            if (_optionsPanel == null) return;
            DOTween.Kill(_optionsPanel, "optFade");
            var rect = _optionsPanel.GetComponent<RectTransform>();
            DOTween.Kill(rect, "optSlide");
            var seq = DOTween.Sequence();
            seq.Append(_optionsPanel.DOFade(0f, 0.25f));
            seq.Join(rect.DOAnchorPosY(-100, 0.3f).SetEase(Ease.InBack));
            seq.OnComplete(() =>
            {
                ClearOptions();
                _optionsPanel.gameObject.SetActive(false);
            });
        }

        private void ClearOptions()
        {
            foreach (var opt in _activeOptions)
            {
                if (opt != null && opt.gameObject != null)
                { DOTween.Kill(opt.transform); Destroy(opt.gameObject); }
            }
            _activeOptions.Clear();
        }


        public void ShowLoading(string msg)
        { _loadingUI.gameObject.SetActive(true); if (_loadingText != null) _loadingText.arabicText = msg; _loadingUI.DOFade(1f, 0.3f); }

        public void HideLoading()
        { _loadingUI.DOFade(0f, 0.3f).OnComplete(() => _loadingUI.gameObject.SetActive(false)); }

        public void ShowError(string msg)
        { _errorUI.gameObject.SetActive(true); if (_errorText != null) _errorText.arabicText = msg; _errorUI.DOFade(1f, 0.3f); }

        public void ShowResults(int score, int correct, int wrong, int total, int bestStreak)
        {
            _resultsUI.gameObject.SetActive(true);
            _resultsUI.alpha = 0;

            float pct = total > 0 ? (float)correct / total * 100f : 0;
            if (_resultTitle != null)
                _resultTitle.arabicText = pct >= 70 ? "أحسنت! 🎉" : "عمل جيد! 👏";
            if (_resultScore != null) _resultScore.arabicText = score.ToString("N0");
            if (_resultStats != null)
                _resultStats.arabicText = $"✓ صحيح: {correct} / {total}  |  " +
                                    $"✗ خطأ: {wrong}  |  " +
                                    $"🔥 أعلى سلسلة: {bestStreak}";

            var seq = DOTween.Sequence();
            seq.Append(_resultsUI.DOFade(1f, 0.5f));
            if (_resultTitle != null)
            {
                _resultTitle.transform.localScale = Vector3.zero;
                seq.Append(_resultTitle.transform.DOScale(1f, 0.5f).SetEase(Ease.OutBack));
            }
            if (_resultScore != null)
            {
                _resultScore.transform.localScale = Vector3.zero;
                seq.Append(_resultScore.transform.DOScale(1f, 0.4f).SetEase(Ease.OutBack));
                int ds = 0;
                DOTween.To(() => ds, x => { ds = x; if (_resultScore != null) _resultScore.arabicText = x.ToString("N0"); },
                    score, 1.2f).SetEase(Ease.OutQuad).SetDelay(0.8f);
            }
        }

        public void ResetUI()
        {
            if (_gameUI != null) { _gameUI.alpha = 0; _gameUI.gameObject.SetActive(false); }
            if (_loadingUI != null) { _loadingUI.alpha = 0; _loadingUI.gameObject.SetActive(false); }
            if (_errorUI != null) { _errorUI.alpha = 0; _errorUI.gameObject.SetActive(false); }
            if (_resultsUI != null) { _resultsUI.alpha = 0; _resultsUI.gameObject.SetActive(false); }
            if (_optionsPanel != null) { _optionsPanel.alpha = 0; _optionsPanel.gameObject.SetActive(false); }
            if (_feedbackGroup != null) _feedbackGroup.alpha = 0;
            ClearOptions();
        }


        private GameObject MkFull(Transform p, string n)
        {
            var go = new GameObject(n);
            go.transform.SetParent(p, false);
            var r = go.AddComponent<RectTransform>();
            r.anchorMin = Vector2.zero; r.anchorMax = Vector2.one;
            r.sizeDelta = Vector2.zero; r.anchoredPosition = Vector2.zero;
            return go;
        }

        private ArabicTextMeshProUGUI MkTxt(Transform p, string n, string text,
            float sz, Vector2 anchor, Vector2 pos, Vector2 size)
        {
            var go = new GameObject(n);
            go.transform.SetParent(p, false);
            var r = go.AddComponent<RectTransform>();
            r.anchorMin = r.anchorMax = anchor;
            r.pivot = anchor;
            r.anchoredPosition = pos; r.sizeDelta = size;
            var t = go.AddComponent<ArabicTextMeshProUGUI>();
            t.arabicText = text; t.fontSize = sz; t.enableWordWrapping = true;
            SSFontManager.Apply(t);
            return t;
        }
    }
}
