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;

        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();


            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;


            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);


            _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;
        }

        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);
            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);
            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");
        }
    }
}
