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

namespace com.al_arcade.cs
{
    using shared;

    public class CsOptionDraggable : MonoBehaviour,
        IBeginDragHandler, IDragHandler, IEndDragHandler,
        IPointerEnterHandler, IPointerExitHandler
    {
        public string OptionText { get; private set; }
        public bool IsCorrect { get; private set; }

        private RectTransform _rect;
        private Image _bg;
        private ArabicTextMeshProUGUI _text;
        private Vector2 _originalAnchoredPos;
        private Canvas _canvas;
        private CsWordButton _targetWord;
        private CanvasGroup _canvasGroup;


        private Vector2 _dragOffset;
        private bool _originalPosCaptured;
        private Camera _canvasCamera;

        public void Setup(string text, bool isCorrect, Canvas canvas, CsWordButton targetWord)
        {
            OptionText = text;
            IsCorrect = isCorrect;
            _canvas = canvas;
            _targetWord = targetWord;

            _rect = GetComponent<RectTransform>();
            if (_rect == null) _rect = gameObject.AddComponent<RectTransform>();


            _canvasGroup = gameObject.AddComponent<CanvasGroup>();


            _canvasCamera = null;
            if (_canvas != null && _canvas.renderMode != RenderMode.ScreenSpaceOverlay)
                _canvasCamera = _canvas.worldCamera;


            _bg = gameObject.AddComponent<Image>();
            _bg.color = SSColorPalette.Card;
            _bg.raycastTarget = true;


            var textObj = new GameObject("Text");
            textObj.transform.SetParent(transform, false);
            var textRect = textObj.AddComponent<RectTransform>();
            textRect.anchorMin = Vector2.zero;
            textRect.anchorMax = Vector2.one;
            textRect.offsetMin = new Vector2(10, 5);
            textRect.offsetMax = new Vector2(-10, -5);

            _text = textObj.AddComponent<ArabicTextMeshProUGUI>();
            _text.arabicText = text;
            _text.fontSize = 22;
            _text.alignment = TMPro.TextAlignmentOptions.Center;
            _text.color = SSColorPalette.TextDark;
            _text.fontStyle = TMPro.FontStyles.Bold;
            _text.raycastTarget = false;
            _text.enableAutoSizing = true;
            _text.fontSizeMin = 14;
            _text.fontSizeMax = 22;
            SSFontManager.Apply(_text);


            transform.localScale = Vector3.one * 0.5f;
            transform.DOScale(Vector3.one, 0.3f).SetEase(Ease.OutBack);

            _originalPosCaptured = false;
        }


        public void OnBeginDrag(PointerEventData eventData)
        {

            _originalAnchoredPos = _rect.anchoredPosition;
            _originalPosCaptured = true;


            Vector2 localPointerPos;
            RectTransformUtility.ScreenPointToLocalPointInRectangle(
                _rect.parent as RectTransform,
                eventData.position,
                _canvasCamera,
                out localPointerPos);

            _dragOffset = _rect.anchoredPosition - localPointerPos;


            _bg.color = SSColorPalette.WithAlpha(SSColorPalette.Primary, 0.3f);
            DOTween.Kill(transform, "optScale");
            transform.DOScale(Vector3.one * 1.08f, 0.12f).SetId("optScale");
            transform.SetAsLastSibling();


            _canvasGroup.blocksRaycasts = false;

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

        public void OnDrag(PointerEventData eventData)
        {
            if (_rect == null || _canvas == null) return;


            Vector2 localPointerPos;
            RectTransformUtility.ScreenPointToLocalPointInRectangle(
                _rect.parent as RectTransform,
                eventData.position,
                _canvasCamera,
                out localPointerPos);


            _rect.anchoredPosition = localPointerPos + _dragOffset;
        }

        public void OnEndDrag(PointerEventData eventData)
        {

            _canvasGroup.blocksRaycasts = true;


            bool droppedOnTarget = false;
            if (_targetWord != null && Camera.main != null)
            {
                Vector3 worldPos = _targetWord.transform.position;
                Vector3 screenPos = Camera.main.WorldToScreenPoint(worldPos);
                float distance = Vector2.Distance(eventData.position, (Vector2)screenPos);

                if (distance < 120f)
                {
                    droppedOnTarget = true;

                    if (CsGameManager.Instance != null)
                        CsGameManager.Instance.OnOptionDropped(IsCorrect);

                    if (IsCorrect)
                    {

                        DOTween.Kill(transform);
                        transform.DOScale(Vector3.zero, 0.3f)
                            .SetEase(Ease.InBack)
                            .OnComplete(() =>
                            {
                                if (gameObject != null) Destroy(gameObject);
                            });
                        return;
                    }
                    else
                    {

                        DOTween.Kill(transform, "optShake");
                        transform.DOShakePosition(0.3f, 10f, 15).SetId("optShake");
                    }
                }
            }


            ReturnToOrigin();
        }

        private void ReturnToOrigin()
        {
            _bg.color = SSColorPalette.Card;
            DOTween.Kill(transform, "optScale");
            transform.DOScale(Vector3.one, 0.2f).SetId("optScale");

            if (_originalPosCaptured)
            {
                DOTween.Kill(_rect, "optReturn");
                _rect.DOAnchorPos(_originalAnchoredPos, 0.35f)
                    .SetEase(Ease.OutBack).SetId("optReturn");
            }
        }


        public void OnPointerEnter(PointerEventData eventData)
        {
            DOTween.Kill(_bg, "optHover");
            _bg.DOColor(SSColorPalette.WithAlpha(SSColorPalette.Primary, 0.1f), 0.15f)
                .SetId("optHover");
        }

        public void OnPointerExit(PointerEventData eventData)
        {
            DOTween.Kill(_bg, "optHover");
            _bg.DOColor(SSColorPalette.Card, 0.15f).SetId("optHover");
        }


        private void OnDestroy()
        {
            DOTween.Kill(transform);
            if (_rect != null) DOTween.Kill(_rect);
            if (_bg != null) DOTween.Kill(_bg);
        }
    }
}
