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

namespace com.al_arcade.mcq
{
    using shared;
    using UnityEngine.SocialPlatforms.Impl;

    public class McqUIManager : MonoBehaviour
    {
        private Canvas _canvas;
        [Header("CanvasGroups")]
        [SerializeField] private CanvasGroup _gameUI;
        [SerializeField] private CanvasGroup _loadingUI;
        [SerializeField] private CanvasGroup _errorUI;
        [SerializeField] private CanvasGroup _resultsUI;
        [SerializeField] private CanvasGroup _feedbackUI;

        [Header("Game UI")]
        [SerializeField] private ArabicTextMeshProUGUI _scoreText;
        [SerializeField] private ArabicTextMeshProUGUI _streakText;
        [SerializeField] private ArabicTextMeshProUGUI _progressText;
        [SerializeField] private ArabicTextMeshProUGUI _loadingText;
        [SerializeField] private ArabicTextMeshProUGUI _errorText;
        [SerializeField] private ArabicTextMeshProUGUI _feedbackText;
        [SerializeField] private Image _feedbackBg;
        [SerializeField] private Image[] _heartIcons;

        [Header("Results UI")]
        [SerializeField] private ArabicTextMeshProUGUI _resultTitle;
        [SerializeField] private ArabicTextMeshProUGUI _resultScore;
        [SerializeField] private ArabicTextMeshProUGUI _resultCorrect;
        [SerializeField] private ArabicTextMeshProUGUI _resultWrong;
        [SerializeField] private ArabicTextMeshProUGUI _resultStreak;
        [SerializeField] private Button _resultRestartBtn;
        [SerializeField] private Slider _progressSlider;
        [SerializeField] private GameObject _winIcon;
        [SerializeField] private GameObject _loseIcon;
        private Image _progressFill;

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

        private void Awake()
        {
            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 (_feedbackUI != null)
            {
                _feedbackUI.alpha = 0; _feedbackUI.gameObject.SetActive(true);
            }
            if (_winIcon != null) _winIcon.SetActive(false);
            if (_loseIcon != null) _loseIcon.SetActive(false);

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

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

            BuildGameUI(canvasObj.transform);
            BuildFeedbackUI(canvasObj.transform);
            BuildLoadingUI(canvasObj.transform);
            BuildErrorUI(canvasObj.transform);
            BuildResultsUI(canvasObj.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);
            _feedbackUI.alpha = 0;
        }

        private void BuildGameUI(Transform parent)
        {
            var go = MakePanel(parent, "GameUI", Vector2.zero, Vector2.one);
            _gameUI = go.AddComponent<CanvasGroup>();

            var topBar = MakeImg(go.transform, "TopBar",
                new Vector2(0, 1), new Vector2(1, 1),
                SSColorPalette.WithAlpha(SSColorPalette.PrimaryDark, 0.85f));
            topBar.rectTransform.pivot = new Vector2(0.5f, 1);
            topBar.rectTransform.sizeDelta = new Vector2(0, 80);

            _scoreText = MakeTxt(topBar.transform, "Score", "0",
                new Vector2(30, -15), 36, TMPro.TextAlignmentOptions.TopLeft);
            _scoreText.color = SSColorPalette.Accent;
            _scoreText.fontStyle = TMPro.FontStyles.Bold;

            MakeTxt(topBar.transform, "ScoreLabel", "النقاط",
                new Vector2(30, -50), 16, TMPro.TextAlignmentOptions.TopLeft)
                .color = SSColorPalette.WithAlpha(Color.white, 0.6f);

            _streakText = MakeTxt(topBar.transform, "Streak", "",
                new Vector2(200, -15), 24, TMPro.TextAlignmentOptions.TopLeft);
            _streakText.color = SSColorPalette.Warning;


            _heartIcons = new Image[5];
            for (int i = 0; i < 5; i++)
            {
                var h = new GameObject($"Heart_{i}");
                h.transform.SetParent(topBar.transform, false);
                var r = h.AddComponent<RectTransform>();
                r.anchorMin = r.anchorMax = new Vector2(1, 0.5f);
                r.pivot = new Vector2(1, 0.5f);
                r.anchoredPosition = new Vector2(-30 - i * 45, 0);
                r.sizeDelta = new Vector2(36, 36);
                _heartIcons[i] = h.AddComponent<Image>();
                _heartIcons[i].color = SSColorPalette.Danger;
                h.SetActive(false);
            }


            var progBg = MakeImg(go.transform, "ProgressBg",
                new Vector2(0, 0), new Vector2(1, 0),
                SSColorPalette.WithAlpha(Color.white, 0.1f));
            progBg.rectTransform.anchoredPosition = new Vector2(0, 15);
            progBg.rectTransform.sizeDelta = new Vector2(-80, 8);
            progBg.rectTransform.pivot = new Vector2(0.5f, 0);

            var fillObj = new GameObject("ProgressFill");
            fillObj.transform.SetParent(progBg.transform, false);
            var fr = fillObj.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 = fillObj.AddComponent<Image>();
            _progressFill.color = SSColorPalette.Accent;

            _progressText = MakeTxt(go.transform, "ProgressText", "0 / 0",
                new Vector2(0, 35), 16, TMPro.TextAlignmentOptions.Bottom);
            _progressText.rectTransform.anchorMin = _progressText.rectTransform.anchorMax =
                new Vector2(0.5f, 0);
            _progressText.color = SSColorPalette.WithAlpha(Color.white, 0.5f);
        }

        private void BuildFeedbackUI(Transform parent)
        {
            var go = MakePanel(parent, "FeedbackUI", Vector2.zero, Vector2.one);
            _feedbackUI = go.AddComponent<CanvasGroup>();
            _feedbackUI.blocksRaycasts = false;
            _feedbackUI.interactable = false;

            var bgObj = new GameObject("FeedbackBg");
            bgObj.transform.SetParent(go.transform, false);
            var bgRect = bgObj.AddComponent<RectTransform>();
            bgRect.anchorMin = new Vector2(0.2f, 0.4f);
            bgRect.anchorMax = new Vector2(0.8f, 0.6f);
            bgRect.offsetMin = bgRect.offsetMax = Vector2.zero;
            _feedbackBg = bgObj.AddComponent<Image>();
            _feedbackBg.color = SSColorPalette.WithAlpha(SSColorPalette.Success, 0.9f);

            _feedbackText = MakeTxt(bgObj.transform, "FeedbackText", "",
                Vector2.zero, 36, TMPro.TextAlignmentOptions.Center);
            _feedbackText.rectTransform.anchorMin = Vector2.zero;
            _feedbackText.rectTransform.anchorMax = Vector2.one;
            _feedbackText.rectTransform.sizeDelta = Vector2.zero;
            _feedbackText.color = Color.white;
            _feedbackText.fontStyle = TMPro.FontStyles.Bold;
        }

        private void BuildLoadingUI(Transform parent)
        {
            var go = MakePanel(parent, "LoadingUI", Vector2.zero, Vector2.one);
            _loadingUI = go.AddComponent<CanvasGroup>();
            go.AddComponent<Image>().color =
                SSColorPalette.WithAlpha(SSColorPalette.PrimaryDark, 0.9f);

            _loadingText = MakeTxt(go.transform, "LoadingText", "جاري التحميل...",
                Vector2.zero, 28, TMPro.TextAlignmentOptions.Center);
            _loadingText.rectTransform.anchorMin = new Vector2(0.2f, 0.4f);
            _loadingText.rectTransform.anchorMax = new Vector2(0.8f, 0.6f);
            _loadingText.rectTransform.sizeDelta = Vector2.zero;
            _loadingText.color = Color.white;
        }

        private void BuildErrorUI(Transform parent)
        {
            var go = MakePanel(parent, "ErrorUI", Vector2.zero, Vector2.one);
            _errorUI = go.AddComponent<CanvasGroup>();
            go.AddComponent<Image>().color =
                SSColorPalette.WithAlpha(SSColorPalette.Danger, 0.92f);

            _errorText = MakeTxt(go.transform, "ErrorText", "خطأ",
                Vector2.zero, 24, TMPro.TextAlignmentOptions.Center);
            _errorText.rectTransform.anchorMin = new Vector2(0.15f, 0.35f);
            _errorText.rectTransform.anchorMax = new Vector2(0.85f, 0.65f);
            _errorText.rectTransform.sizeDelta = Vector2.zero;
            _errorText.color = Color.white;
            _errorText.enableWordWrapping = true;
        }

        private void BuildResultsUI(Transform parent)
        {
            var go = MakePanel(parent, "ResultsUI", Vector2.zero, Vector2.one);
            _resultsUI = go.AddComponent<CanvasGroup>();
            go.AddComponent<Image>().color =
                SSColorPalette.WithAlpha(SSColorPalette.PrimaryDark, 0.95f);

            _resultTitle = MakeAnchoredTxt(go.transform, "Title", "أحسنت! 🎉",
                new Vector2(0, 200), 48);
            _resultTitle.color = SSColorPalette.Accent;
            _resultTitle.fontStyle = TMPro.FontStyles.Bold;

            _resultScore = MakeAnchoredTxt(go.transform, "Score", "0",
                new Vector2(0, 120), 64);
            _resultScore.color = Color.white;
            _resultScore.fontStyle = TMPro.FontStyles.Bold;

            _resultCorrect = MakeAnchoredTxt(go.transform, "Correct", "",
                new Vector2(-200, 0), 24);
            _resultCorrect.color = SSColorPalette.Success;

            _resultWrong = MakeAnchoredTxt(go.transform, "Wrong", "",
                new Vector2(0, 0), 24);
            _resultWrong.color = SSColorPalette.Danger;

            _resultStreak = MakeAnchoredTxt(go.transform, "Streak", "",
                new Vector2(200, 0), 24);
            _resultStreak.color = SSColorPalette.Accent;


            var btnObj = new GameObject("RestartBtn");
            btnObj.transform.SetParent(go.transform, false);
            var br = btnObj.AddComponent<RectTransform>();
            br.anchorMin = br.anchorMax = new Vector2(0.5f, 0.5f);
            br.anchoredPosition = new Vector2(0, -120);
            br.sizeDelta = new Vector2(300, 60);
            btnObj.AddComponent<Image>().color = SSColorPalette.Accent;
            _resultRestartBtn = btnObj.AddComponent<Button>();
            _resultRestartBtn.onClick.AddListener(() =>
            { HideResults(); onRestartClicked?.Invoke(); });

            var btnTxt = MakeTxt(btnObj.transform, "BtnText", "إعادة اللعب 🔄",
                Vector2.zero, 24, TMPro.TextAlignmentOptions.Center);
            btnTxt.rectTransform.anchorMin = Vector2.zero;
            btnTxt.rectTransform.anchorMax = Vector2.one;
            btnTxt.rectTransform.sizeDelta = Vector2.zero;
            btnTxt.color = SSColorPalette.TextDark;
            btnTxt.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, "scorePunch");
            _scoreText.transform.DOPunchScale(Vector3.one * 0.2f, 0.3f, 6, 0.3f)
                .SetId("scorePunch");
        }

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

        public void SetLives(int lives, int maxLives)
        {
            for (int i = 0; i < _heartIcons.Length; i++)
            {
                bool active = i < maxLives;
                _heartIcons[i].gameObject.SetActive(active);
                if (active)
                {
                    bool alive = i < lives;
                    _heartIcons[i].color = alive
                        ? SSColorPalette.Danger
                        : SSColorPalette.WithAlpha(SSColorPalette.Danger, 0.2f);
                    if (!alive && i == lives)
                    {
                        DOTween.Kill(_heartIcons[i].transform);
                        _heartIcons[i].transform.DOPunchScale(Vector3.one * 0.5f, 0.3f);
                    }
                }
            }
        }

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

        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(_feedbackUI);
            _feedbackUI.alpha = 0;
            var bgRect = _feedbackBg?.rectTransform;
            if (bgRect != null)
            {
                print("Showing Feedback");
                bgRect.localScale = new Vector3(0.5f, 0f, 1f);
                var seq = DOTween.Sequence();
                seq.Append(_feedbackUI.DOFade(1f, 0.15f));
                seq.Join(bgRect.DOScaleX(1f, 0.25f).SetEase(Ease.OutBack));
                seq.Join(bgRect.DOScaleY(1f, 0.2f).SetEase(Ease.OutBack).SetDelay(0.05f));
                seq.AppendInterval(1.2f);
                seq.Append(_feedbackUI.DOFade(0f, 0.3f));
            }
        }

        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 bestStreak, int total, bool won)
        {
            _resultsUI.gameObject.SetActive(true);
            _resultsUI.alpha = 0;

            if (_resultTitle != null) _resultTitle.arabicText = won ? "أحسنت!" : "حظ أوفر!";
            if (_resultScore != null) _resultScore.arabicText = score.ToString("N0");
            if (_resultCorrect != null) _resultCorrect.arabicText = $"صحيح: {correct}";
            if (_resultWrong != null) _resultWrong.arabicText = $"خطأ: {wrong}";
            if (_resultStreak != null) _resultStreak.arabicText = $"أعلى سلسلة: {bestStreak}";

            if (_winIcon != null) _winIcon.SetActive(won);
            if (_loseIcon != null) _loseIcon.SetActive(!won);

            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 (_winIcon != null)
            {
                _winIcon.transform.localScale = Vector3.zero;
                seq.Append(_winIcon.transform.DOScale(1f, 0.5f).SetEase(Ease.OutBack));
            }
            if (_loseIcon != null)
            {
                _loseIcon.transform.localScale = Vector3.zero;
                seq.Append(_loseIcon.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));
            }
        }

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

        public void RestartButtonFunction()
        {
            HideResults();
            onRestartClicked?.Invoke();
        }

        public void ResetUI()
        {
            _gameUI.gameObject.SetActive(false);
            _loadingUI.gameObject.SetActive(false);
            _errorUI.gameObject.SetActive(false);
            _resultsUI.gameObject.SetActive(false);
            _feedbackUI.alpha = 0;
        }


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

        private Image MakeImg(Transform p, string n, Vector2 amin, Vector2 amax, Color c)
        {
            var go = new GameObject(n);
            go.transform.SetParent(p, false);
            var r = go.AddComponent<RectTransform>();
            r.anchorMin = amin; r.anchorMax = amax; r.sizeDelta = Vector2.zero;
            var img = go.AddComponent<Image>();
            img.color = c;
            return img;
        }

        private ArabicTextMeshProUGUI MakeTxt(Transform p, string n, string text,
            Vector2 pos, float size, TMPro.TextAlignmentOptions align)
        {
            var go = new GameObject(n);
            go.transform.SetParent(p, false);
            var r = go.AddComponent<RectTransform>();
            r.anchoredPosition = pos; r.sizeDelta = new Vector2(400, 60);
            var tmp = go.AddComponent<ArabicTextMeshProUGUI>();
            tmp.arabicText = text; tmp.fontSize = size; tmp.alignment = align;
            tmp.enableWordWrapping = true;
            SSFontManager.Apply(tmp);
            return tmp;
        }

        private ArabicTextMeshProUGUI MakeAnchoredTxt(Transform p, string n, string text,
            Vector2 pos, float size)
        {
            var t = MakeTxt(p, n, text, pos, size, TMPro.TextAlignmentOptions.Center);
            t.rectTransform.anchorMin = t.rectTransform.anchorMax = new Vector2(0.5f, 0.5f);
            return t;
        }
    }
}
