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

namespace com.al_arcade.tf
{
    using shared;

    public class TfHandController : MonoBehaviour
    {
        private GameObject _leftHand, _rightHand;
        private GameObject _leftBtn, _rightBtn;
        private ArabicTextMeshPro _leftLabel, _rightLabel;
        private Material _leftMat, _rightMat;

        private Vector3 _leftRestPos, _rightRestPos;
        private Vector3 _leftBtnBaseScale, _rightBtnBaseScale;
        private bool _isReady;
        private Sequence _idleSeq;
        private Camera _cam;

        public void Build(Camera cam)
        {
            _cam = cam;
            transform.SetParent(cam.transform);
            transform.localPosition = Vector3.zero;
            transform.localRotation = Quaternion.identity;

            BuildHand(true, out _leftHand, out _leftBtn, out _leftLabel, out _leftMat);
            BuildHand(false, out _rightHand, out _rightBtn, out _rightLabel, out _rightMat);

            _leftRestPos = _leftHand.transform.localPosition;
            _rightRestPos = _rightHand.transform.localPosition;
            _leftBtnBaseScale = _leftBtn.transform.localScale;
            _rightBtnBaseScale = _rightBtn.transform.localScale;

            StartIdleAnimation();
        }

        private void BuildHand(bool isLeft, out GameObject hand, out GameObject btn,
            out ArabicTextMeshPro label, out Material mat)
        {
            float side = isLeft ? -1f : 1f;
            var shader = GetShader();


            hand = new GameObject(isLeft ? "LeftHand" : "RightHand");
            hand.transform.SetParent(transform);
            hand.transform.localPosition = new Vector3(side * 0.35f, -0.3f, 0.55f);
            hand.transform.localRotation = Quaternion.Euler(12f, -side * 8f, side * 4f);


            var arm = GameObject.CreatePrimitive(PrimitiveType.Capsule);
            arm.name = "Arm";
            arm.transform.SetParent(hand.transform);
            arm.transform.localPosition = new Vector3(0, -0.08f, 0);
            arm.transform.localScale = new Vector3(0.08f, 0.14f, 0.08f);
            Destroy(arm.GetComponent<Collider>());
            arm.GetComponent<Renderer>().material =
                new Material(shader) { color = new Color32(255, 220, 180, 255) };


            btn = GameObject.CreatePrimitive(PrimitiveType.Cylinder);
            btn.name = isLeft ? "TrueButton" : "FalseButton";
            btn.transform.SetParent(hand.transform);
            btn.transform.localPosition = new Vector3(0, 0.1f, 0.06f);
            btn.transform.localScale = new Vector3(0.16f, 0.025f, 0.16f);
            Destroy(btn.GetComponent<Collider>());

            mat = new Material(shader)
            {
                color = isLeft ? SSColorPalette.TrueGreen : SSColorPalette.FalseRed
            };
            btn.GetComponent<Renderer>().material = mat;


            var labelObj = new GameObject("Label");
            labelObj.transform.SetParent(btn.transform);
            labelObj.transform.localPosition = new Vector3(0, 0.8f, 0);
            labelObj.transform.localRotation = Quaternion.Euler(90, 0, 0);

            labelObj.transform.localScale = new Vector3(0.6f, 0.6f, 0.6f);

            label = labelObj.AddComponent<ArabicTextMeshPro>();
            label.arabicText = isLeft ? "صح ✓" : "خطأ ✗";

            label.fontSize = 2.2f;
            label.fontSizeMin = 1.5f;
            label.fontSizeMax = 2.5f;
            label.enableAutoSizing = true;
            label.alignment = TMPro.TextAlignmentOptions.Center;
            label.color = Color.white;
            label.fontStyle = TMPro.FontStyles.Bold;

            label.rectTransform.sizeDelta = new Vector2(1.2f, 0.5f);
            label.overflowMode = TMPro.TextOverflowModes.Overflow;
            SSFontManager.Apply(label);


            var ring = GameObject.CreatePrimitive(PrimitiveType.Cylinder);
            ring.name = "GlowRing";
            ring.transform.SetParent(btn.transform);
            ring.transform.localPosition = Vector3.zero;
            ring.transform.localScale = new Vector3(1.15f, 0.4f, 1.15f);
            Destroy(ring.GetComponent<Collider>());
            ring.GetComponent<Renderer>().material = new Material(shader)
            {
                color = SSColorPalette.WithAlpha(
                    isLeft ? SSColorPalette.TrueGreen : SSColorPalette.FalseRed, 0.25f)
            };
        }


        private void StartIdleAnimation()
        {
            KillIdleTween();
            if (_leftHand == null || _rightHand == null) return;

            _idleSeq = DOTween.Sequence();
            _idleSeq.Append(_leftHand.transform
                .DOLocalMoveY(_leftRestPos.y + 0.015f, 1.8f)
                .SetEase(Ease.InOutSine));
            _idleSeq.Join(_rightHand.transform
                .DOLocalMoveY(_rightRestPos.y - 0.015f, 1.8f)
                .SetEase(Ease.InOutSine));
            _idleSeq.Append(_leftHand.transform
                .DOLocalMoveY(_leftRestPos.y, 1.8f)
                .SetEase(Ease.InOutSine));
            _idleSeq.Join(_rightHand.transform
                .DOLocalMoveY(_rightRestPos.y, 1.8f)
                .SetEase(Ease.InOutSine));
            _idleSeq.SetLoops(-1, LoopType.Restart);
        }

        private void KillIdleTween()
        {
            _idleSeq?.Kill();
            _idleSeq = null;
        }


        public void SetReady(bool ready) => _isReady = ready;

        private void Update()
        {
            if (!_isReady) return;
            if (Input.GetMouseButtonDown(0))
            {
                PressButton(Input.mousePosition.x < Screen.width / 2f);
            }
        }

        private void PressButton(bool isTrue)
        {
            if (!_isReady) return;

            var hand = isTrue ? _leftHand : _rightHand;
            var btn = isTrue ? _leftBtn : _rightBtn;
            var restPos = isTrue ? _leftRestPos : _rightRestPos;
            var btnBaseScale = isTrue ? _leftBtnBaseScale : _rightBtnBaseScale;


            KillIdleTween();
            DOTween.Kill(hand.transform);
            DOTween.Kill(btn.transform);
            hand.transform.localPosition = restPos;
            btn.transform.localScale = btnBaseScale;


            var pressSeq = DOTween.Sequence();
            pressSeq.Append(hand.transform
                .DOLocalMoveY(restPos.y + 0.06f, 0.07f)
                .SetEase(Ease.OutQuad));
            pressSeq.Append(hand.transform
                .DOLocalMoveY(restPos.y - 0.04f, 0.05f)
                .SetEase(Ease.InQuad));
            pressSeq.Append(hand.transform
                .DOLocalMoveY(restPos.y, 0.2f)
                .SetEase(Ease.OutBounce));
            pressSeq.OnComplete(() => StartIdleAnimation());


            btn.transform.DOScaleY(btnBaseScale.y * 0.3f, 0.05f)
                .SetEase(Ease.InQuad)
                .OnComplete(() =>
                    btn.transform.DOScaleY(btnBaseScale.y, 0.15f)
                        .SetEase(Ease.OutBounce));

            var audio = SSAudioManager.Instance;
            if (audio != null) audio.PlayClickBeep();

            if (TfGameManager.Instance != null)
                TfGameManager.Instance.SubmitAnswer(isTrue);
        }


        public void PlayCorrectFeedback(bool wasTrue)
        {
            var hand = wasTrue ? _leftHand : _rightHand;
            var mat = wasTrue ? _leftMat : _rightMat;
            var restPos = wasTrue ? _leftRestPos : _rightRestPos;
            if (hand == null || mat == null) return;

            DOTween.Kill(hand.transform);
            DOTween.Kill(mat);
            var orig = mat.color;

            var seq = DOTween.Sequence();
            seq.Append(hand.transform
                .DOLocalMoveY(restPos.y + 0.12f, 0.2f)
                .SetEase(Ease.OutBack));
            seq.Join(mat.DOColor(Color.white, 0.1f));
            seq.Append(mat.DOColor(orig, 0.3f));
            seq.Append(hand.transform.DOLocalMove(restPos, 0.3f));
            seq.OnComplete(() => StartIdleAnimation());
        }

        public void PlayWrongFeedback(bool wasTrue)
        {
            var hand = wasTrue ? _leftHand : _rightHand;
            var restPos = wasTrue ? _leftRestPos : _rightRestPos;
            if (hand == null) return;

            DOTween.Kill(hand.transform);
            var seq = DOTween.Sequence();
            seq.Append(hand.transform.DOShakePosition(0.35f, 0.03f, 18));
            seq.Append(hand.transform.DOLocalMove(restPos, 0.25f));
            seq.OnComplete(() => StartIdleAnimation());
        }

        public void Reset()
        {
            KillIdleTween();
            _isReady = false;
            if (_leftHand != null)
            {
                DOTween.Kill(_leftHand.transform);
                _leftHand.transform.localPosition = _leftRestPos;
            }
            if (_rightHand != null)
            {
                DOTween.Kill(_rightHand.transform);
                _rightHand.transform.localPosition = _rightRestPos;
            }
            if (_leftBtn != null)
            {
                DOTween.Kill(_leftBtn.transform);
                _leftBtn.transform.localScale = _leftBtnBaseScale;
            }
            if (_rightBtn != null)
            {
                DOTween.Kill(_rightBtn.transform);
                _rightBtn.transform.localScale = _rightBtnBaseScale;
            }
        }

        private void OnDestroy()
        {
            KillIdleTween();
            if (_leftHand != null) DOTween.Kill(_leftHand.transform);
            if (_rightHand != null) DOTween.Kill(_rightHand.transform);
            if (_leftBtn != null) DOTween.Kill(_leftBtn.transform);
            if (_rightBtn != null) DOTween.Kill(_rightBtn.transform);
        }

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