using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.InputSystem;
using UnityEngine.InputSystem.Controls;
using UnityEngine.InputSystem.EnhancedTouch;
using UnityEngine.InputSystem.Layouts;
using UnityEngine.InputSystem.OnScreen;
using UnityEngine.Serialization;

[AddComponentMenu("Input/����ҡ�� - ������ϵͳ(InputSystem)")]
public class JoyStick_InputSystem : OnScreenControl, IPointerDownHandler
{
    enum JoyStickType
    {
        [InspectorName("�̶���Ĭ��λ��")]
        FixedInDefaultPosition = 0,

        [InspectorName("�̶��ڴ���λ��")]
        FixedInClickPosition = 1,

        [InspectorName("���津���ƶ�")]
        Flexible = 2
    }

    [Header("��������")]
    [Tooltip("ҡ�˱���")]
    [SerializeField]
    private RectTransform joyStickBackGround;

    [Tooltip("ҡ�˰�ť")]
    [SerializeField]
    private RectTransform joyStickButton;

    [Tooltip("ҡ�˰�ť�ƶ���Χ(�뾶)")]
    [FormerlySerializedAs("movementRange")]
    [SerializeField]
    private float movementRange = 50;

    [Tooltip("�����豸·��")]
    [InputControl(layout = "Vector2")]
    [SerializeField]
    private new string controlPath;

    [Header("��������")]
    [Tooltip("ҡ������")]
    [SerializeField]
    private JoyStickType joyStickType;

    [Tooltip("ҡ���Ƿ�Ĭ������")]
    [SerializeField]
    private bool isHideWithoutTouch;

    //������(�豸)
    private Touchscreen currentTouchScreen;

    //����ҡ�˵Ĵ������
    private TouchControl joyStickTouch;

    //ҡ�˳�ʼλ��
    private Vector2 joyStickStartPos;

    //����Ļ��ص����(��Ҫ���ڽ���Ļ�ϵ�λ��ת��ΪijUI�����ڵ����λ��)
    private Camera screenCamera;

    //ģ��(�����߱�)����
    private TouchSimulation touchSimulation;

    //������Ⱦģʽ
    private RenderMode renderMode;

    //�������UI��RectTransform
    private RectTransform rectTransform;

    protected override string controlPathInternal
    {
        get => controlPath;
        set => controlPath = value;
    }

    private void Awake()
    {
#if UNITY_EDITOR
        if (!gameObject.TryGetComponent(out touchSimulation))
        {
            touchSimulation = gameObject.AddComponent<TouchSimulation>();
        }
#endif
    }

    private void Start()
    {
        currentTouchScreen = Touchscreen.current;
        //��¼ҡ�˳�ʼλ��
        joyStickStartPos = joyStickBackGround.anchoredPosition;
        if (isHideWithoutTouch)
        {
            joyStickBackGround.gameObject.SetActive(false);
        }
        //��ȡ��������Ⱦģʽ
        var canvas = transform.GetComponentInParent<Canvas>();
        renderMode = canvas != null ? canvas.renderMode : RenderMode.ScreenSpaceOverlay;
        //��ȡ�������UI��RectTransform
        rectTransform = transform.GetComponent<RectTransform>();
    }

    private void Update()
    {
        UpdateJoyStickUIPos();
    }

    private void OnDestroy()
    {
#if UNITY_EDITOR
        touchSimulation = null;
#endif
    }

    public void OnPointerDown(PointerEventData eventData)
    {
        //��ȡ����Ļ��ص����
        if (renderMode != RenderMode.ScreenSpaceOverlay)
        {
            screenCamera = eventData.pressEventCamera;
        }
        //ҡ��û�б�����ʱ�������Ȩ
        if (joyStickTouch == null)
        {
            for (int i = 0; i < currentTouchScreen.touches.Count; i++)
            {
                var touch = currentTouchScreen.touches[i];
                if (touch.phase.ReadValue() == UnityEngine.InputSystem.TouchPhase.Began)
                {
                    if (
                        RectTransformUtility.RectangleContainsScreenPoint(
                            rectTransform,
                            touch.position.ReadValue(),
                            screenCamera
                        )
                    )
                    {
                        joyStickTouch = touch;
                        RectTransformUtility.ScreenPointToLocalPointInRectangle(
                            rectTransform,
                            joyStickTouch.position.ReadValue(),
                            screenCamera,
                            out var joyStickBgPos
                        );
                        SetJoyStickUI(joyStickBgPos, Vector2.zero, true);
                    }
                }
            }
        }
    }

    private void UpdateJoyStickUIPos()
    {
        if (joyStickTouch == null)
            return;
        bool isActive = true;
        Vector2 joyStickBgPos = Vector2.zero;
        Vector2 joyStickBtnPos = Vector2.zero;
        Vector2 sendToControlValue = Vector2.zero;
        switch (joyStickTouch.phase.ReadValue())
        {
            case UnityEngine.InputSystem.TouchPhase.None:
                break;
            case UnityEngine.InputSystem.TouchPhase.Began:
            case UnityEngine.InputSystem.TouchPhase.Moved:
                //����ҡ��λ������
                RectTransformUtility.ScreenPointToLocalPointInRectangle(
                    rectTransform,
                    joyStickTouch.position.ReadValue(),
                    screenCamera,
                    out var touchInRectPos
                );
                Vector2 delta = touchInRectPos - joyStickBackGround.anchoredPosition;
                joyStickBgPos = joyStickBackGround.anchoredPosition;
                if (joyStickType == JoyStickType.Flexible)
                {
                    if (delta.magnitude > movementRange)
                    {
                        joyStickBgPos += delta.normalized * (delta.magnitude - movementRange);
                    }
                }
                joyStickBtnPos = Vector2.ClampMagnitude(delta, movementRange);
                isActive = true;
                sendToControlValue = delta / movementRange;
                break;
            case UnityEngine.InputSystem.TouchPhase.Ended:
            case UnityEngine.InputSystem.TouchPhase.Canceled:
                //�ջ�Touch��ҡ�˵Ŀ���Ȩ
                joyStickTouch = null;
                joyStickBgPos = joyStickStartPos;
                isActive = false;
                break;
            case UnityEngine.InputSystem.TouchPhase.Stationary:
                break;
        }
        //����ҡ��λ��
        SetJoyStickUI(joyStickBgPos, joyStickBtnPos, isActive);
        //���������������
        SendValueToControl(sendToControlValue);
    }

    private void SetJoyStickUI(Vector2 joyStickBgPos, Vector2 joyStickBtnPos, bool isActive)
    {
        //����joyStickBackGround�
        switch (joyStickType)
        {
            case JoyStickType.FixedInDefaultPosition:
                break;
            case JoyStickType.FixedInClickPosition:
            case JoyStickType.Flexible:
                joyStickBackGround.anchoredPosition = joyStickBgPos;
                break;
        }
        //����joyStickButton�
        joyStickButton.anchoredPosition = joyStickBtnPos;
        //����
        if (isHideWithoutTouch && joyStickBackGround.gameObject.activeSelf != isActive)
        {
            joyStickBackGround.gameObject.SetActive(isActive);
        }
    }
}