using System;
using UnityEngine;
using DG.Tweening;
using ALArcade.ArabicTMP;

namespace com.al_arcade.mcq
{
    using shared;

    public class McqGateController : MonoBehaviour
    {
        public int GateIndex { get; private set; }
        public string AnswerText { get; private set; }
        public bool IsCorrect { get; private set; }
        public bool WasEntered { get; private set; }

        public event Action<int> onPlayerEnter;

        private GameObject _backPanel;
        private ArabicTextMeshPro _label;
        private BoxCollider _collider;
        private Material _panelMaterial;
        private Sequence _idleAnim;
        private Sequence _glowAnim;

        private const float GateWidth = 2.5f;
        private const float GateHeight = 3.5f;
        private const float GateDepth = 0.8f;
        private const float FrameThickness = 0.15f;

        [SerializeField] private GameObject _visualPrefab;
        [SerializeField] private ArabicTextMeshPro _answerText;
        [SerializeField] private MeshRenderer _panelRenderer;
        //[SerializeField] private ParticleSystem CorrectParticle;
        //[SerializeField] private ParticleSystem WrongParticle;

        public void Setup(int index, string text, bool correct)
        {
            GateIndex = index;
            AnswerText = text;
            IsCorrect = correct;
            WasEntered = false;
            BuildVisuals();
            StartIdleAnimation();
        }

        private void BuildVisuals()
        {
            var shader = GetShader();

            if (_visualPrefab == null)
            {
                CreatePillar(Vector3.left * (GateWidth / 2f), "LeftPillar", shader);
                CreatePillar(Vector3.right * (GateWidth / 2f), "RightPillar", shader);


                var topBar = GameObject.CreatePrimitive(PrimitiveType.Cube);
                topBar.name = "TopBar";
                topBar.transform.SetParent(transform);
                topBar.transform.localPosition = Vector3.up * GateHeight;
                topBar.transform.localScale = new Vector3(GateWidth + FrameThickness * 2, FrameThickness, GateDepth);
                Destroy(topBar.GetComponent<Collider>());
                var topMat = new Material(shader) { color = SSColorPalette.Primary };
                topBar.GetComponent<Renderer>().material = topMat;


                _backPanel = GameObject.CreatePrimitive(PrimitiveType.Cube);
                _backPanel.name = "AnswerPanel";
                _backPanel.transform.SetParent(transform);
                _backPanel.transform.localPosition = new Vector3(0, GateHeight / 2f, GateDepth / 2f - 0.05f);
                _backPanel.transform.localScale = new Vector3(GateWidth - 0.1f, GateHeight * 0.5f, 0.05f);
                Destroy(_backPanel.GetComponent<Collider>());
                _panelMaterial = new Material(shader) { color = SSColorPalette.GateDefault };
                _backPanel.GetComponent<Renderer>().material = _panelMaterial;


                _collider = gameObject.AddComponent<BoxCollider>();
                _collider.isTrigger = true;
                _collider.center = new Vector3(0, GateHeight / 2f, 0);
                _collider.size = new Vector3(GateWidth, GateHeight, GateDepth);


                var floor = GameObject.CreatePrimitive(PrimitiveType.Cube);
                floor.name = "FloorHighlight";
                floor.transform.SetParent(transform);
                floor.transform.localPosition = new Vector3(0, 0.01f, 0);
                floor.transform.localScale = new Vector3(GateWidth, 0.02f, GateDepth * 1.5f);
                Destroy(floor.GetComponent<Collider>());
                var floorMat = new Material(shader)
                { color = SSColorPalette.WithAlpha(SSColorPalette.Primary, 0.15f) };
                floor.GetComponent<Renderer>().material = floorMat;
            }
            
            if (_answerText == null)
            {
                var textObj = new GameObject("AnswerLabel");
                textObj.transform.SetParent(transform);
                textObj.transform.localPosition = new Vector3(0, GateHeight / 2f, GateDepth / 2f - 0.08f);


                textObj.transform.localRotation = Quaternion.identity;

                _label = textObj.AddComponent<ArabicTextMeshPro>();
                _label.arabicText = AnswerText;
                _label.fontSize = 4f;
                _label.alignment = TMPro.TextAlignmentOptions.Center;
                _label.color = Color.white;
                _label.fontStyle = TMPro.FontStyles.Bold;
                _label.enableAutoSizing = true;
                _label.fontSizeMin = 2f;
                _label.fontSizeMax = 5f;
                _label.rectTransform.sizeDelta = new Vector2(GateWidth - 0.4f, GateHeight * 0.45f);
                _label.enableWordWrapping = true;
                _label.overflowMode = TMPro.TextOverflowModes.Ellipsis;
                SSFontManager.Apply(_label);
            } else
            {
                _answerText.arabicText = AnswerText;
                SSFontManager.Apply(_answerText);
            }


        }

        private void CreatePillar(Vector3 offset, string name, Shader shader)
        {
            var pillar = GameObject.CreatePrimitive(PrimitiveType.Cube);
            pillar.name = name;
            pillar.transform.SetParent(transform);
            pillar.transform.localPosition = offset + Vector3.up * (GateHeight / 2f);
            pillar.transform.localScale = new Vector3(FrameThickness, GateHeight, GateDepth);
            Destroy(pillar.GetComponent<Collider>());
            var mat = new Material(shader) { color = SSColorPalette.PrimaryDark };
            pillar.GetComponent<Renderer>().material = mat;
        }

        private void StartIdleAnimation()
        {
            KillAllTweens();
            float baseY = transform.position.y;
            _idleAnim = DOTween.Sequence();
            _idleAnim.Append(transform.DOMoveY(baseY + 0.15f, 1.2f).SetEase(Ease.InOutSine));
            _idleAnim.Append(transform.DOMoveY(baseY, 1.2f).SetEase(Ease.InOutSine));
            _idleAnim.SetLoops(-1, LoopType.Restart);

            if (_panelMaterial != null)
            {
                _glowAnim = DOTween.Sequence();
                _glowAnim.Append(_panelMaterial.DOColor(SSColorPalette.PrimaryLight, 1.5f));
                _glowAnim.Append(_panelMaterial.DOColor(SSColorPalette.GateDefault, 1.5f));
                _glowAnim.SetLoops(-1, LoopType.Restart);
            }
        }

        private void KillAllTweens()
        {
            _idleAnim?.Kill();
            _glowAnim?.Kill();
            _idleAnim = null;
            _glowAnim = null;
            DOTween.Kill(transform);
            if (_panelMaterial != null) DOTween.Kill(_panelMaterial);
            if (_label != null) DOTween.Kill(_label.transform);
        }


        private void OnTriggerEnter(Collider other)
        {
            if (WasEntered) return;
            if (!other.CompareTag("Player") && other.GetComponent<McqPlayerRunner>() == null) return;
            WasEntered = true;
            onPlayerEnter?.Invoke(GateIndex);
        }


        public void PlayCorrectAnimation()
        {
            KillAllTweens();
            if (_panelMaterial != null) _panelMaterial.DOColor(SSColorPalette.GateCorrect, 0.3f);
            if (_panelRenderer != null) _panelRenderer.material.DOColor(SSColorPalette.GateCorrect, 0.3f);
            //if (CorrectParticle != null) CorrectParticle.Play();
            transform.DOPunchScale(Vector3.one * 0.2f, 0.5f, 8, 0.5f);
            if (_label != null) _label.transform.DOPunchScale(Vector3.one * 0.3f, 0.4f, 6, 0.3f);
        }

        public void PlayWrongAnimation()
        {
            KillAllTweens();
            if (_panelMaterial != null) _panelMaterial.DOColor(SSColorPalette.GateWrong, 0.3f);
            if (_panelRenderer != null) _panelRenderer.material.DOColor(SSColorPalette.GateWrong, 0.3f);
            //if (WrongParticle != null) WrongParticle.Play();
            transform.DOShakePosition(0.5f, 0.4f, 20, 90f, false, true);
            transform.DOShakeRotation(0.5f, 10f, 20, 90f, true);
        }

        public void PlayRevealCorrect()
        {
            KillAllTweens();
            if (_panelMaterial != null)
            {
                var seq = DOTween.Sequence();
                seq.Append(_panelMaterial.DOColor(SSColorPalette.GateCorrect, 0.2f));
                seq.Append(_panelMaterial.DOColor(SSColorPalette.Accent, 0.3f));
                seq.Append(_panelMaterial.DOColor(SSColorPalette.GateCorrect, 0.3f));
                seq.SetLoops(3, LoopType.Restart);
            }
            transform.DOPunchScale(Vector3.one * 0.15f, 0.8f, 4, 0.2f);
        }

        public void PlayFadeOut()
        {
            KillAllTweens();
            if (_panelMaterial != null) _panelMaterial.DOFade(0.3f, 0.5f);
            transform.DOScale(Vector3.one * 0.8f, 0.5f).SetEase(Ease.InBack);
        }

        private void OnDestroy() => KillAllTweens();

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