using UnityEngine;
using UnityEngine.UI;
using UnityEngine.EventSystems;
#if UNITY_EDITOR
using UnityEditor;
#endif

public class AdvancedImageViewer : MonoBehaviour, 
    IBeginDragHandler, IDragHandler, IEndDragHandler, 
    IScrollHandler, IPointerClickHandler
{
    [Header("Zoom Settings")]
    [Range(0.1f, 0.5f)] public float minZoom = 0.3f;
    [Range(2f, 10f)] public float maxZoom = 4f;
    [Range(0.01f, 0.2f)] public float zoomSpeed = 0.1f;
    [Range(0.001f, 0.05f)] public float touchZoomSpeed = 0.01f;
    
    [Header("Move Settings")]
    [Range(0.5f, 2f)] public float moveSpeed = 1f;
    [Range(0.01f, 0.3f)] public float elasticFactor = 0.1f;
    
    [Header("References")]
    public RectTransform imageRect;
    public RectTransform contentRect;
    
    private Vector2 lastDragPosition;
    private float currentZoom = 1f;
    private Vector2 initialAnchoredPosition;
    private Vector2 initialSizeDelta;
    
    private float lastTapTime;
    private const float DoubleTapTime = 0.3f;
    private bool isDragging;
    private Vector2 velocity;
    private const float friction = 0.95f;

    private void OnEnable()
    {

        Screen.orientation = ScreenOrientation.LandscapeLeft;
        Screen.autorotateToLandscapeLeft = false;
        Screen.autorotateToLandscapeRight = false;
        Screen.autorotateToPortrait = false;
        Screen.autorotateToPortraitUpsideDown = false;
        Initialize();
    }
    private void OnDisable()
    {
        // 强制横屏并禁止自动旋转
        Screen.orientation = ScreenOrientation.Portrait;
        Screen.autorotateToLandscapeLeft = false;
        Screen.autorotateToLandscapeRight = false;
        Screen.autorotateToPortrait = false;
        Screen.autorotateToPortraitUpsideDown = false;
    }

    private void Initialize()
    {
        if (imageRect == null) imageRect = GetComponent<RectTransform>();
        if (contentRect == null) contentRect = transform.parent.GetComponent<RectTransform>();
        
        initialAnchoredPosition = imageRect.anchoredPosition;
        initialSizeDelta = imageRect.sizeDelta;
        currentZoom = 1f;
        imageRect.localScale = Vector3.one;
    }

    private void Update()
    {
        #if UNITY_EDITOR
        if (!Application.isPlaying)
        {
            // 编辑器模式下保持初始化状态
            if (currentZoom != 1f)
            {
                currentZoom = 1f;
                imageRect.localScale = Vector3.one;
                imageRect.anchoredPosition = initialAnchoredPosition;
            }
            return;
        }
        #endif

        HandleTouchZoom();
        ApplyInertia();
    }

    private void HandleTouchZoom()
    {
        if (Input.touchCount == 2)
        {
            Touch touchZero = Input.GetTouch(0);
            Touch touchOne = Input.GetTouch(1);

            if (touchZero.phase == TouchPhase.Moved || touchOne.phase == TouchPhase.Moved)
            {
                Vector2 touchZeroPrevPos = touchZero.position - touchZero.deltaPosition;
                Vector2 touchOnePrevPos = touchOne.position - touchOne.deltaPosition;

                float prevDistance = Vector2.Distance(touchZeroPrevPos, touchOnePrevPos);
                float currentDistance = Vector2.Distance(touchZero.position, touchOne.position);

                float difference = currentDistance - prevDistance;
                ZoomImage(1 + difference * touchZoomSpeed, (touchZero.position + touchOne.position) / 2);
            }
            isTwo=true;
        }
        else if(Input.touchCount == 0)
        {
            isTwo=false;

        }
    }

    private void ApplyInertia()
    {
        if (!isDragging && velocity.magnitude > 0.1f)
        {
            imageRect.anchoredPosition += velocity * Time.deltaTime;
            velocity *= friction;
            ClampImagePosition();
        }
        else
        {
            velocity = Vector2.zero;
        }
    }

    public void OnBeginDrag(PointerEventData eventData)
    {
        if (Input.touchCount > 1) return;
        
        isDragging = true;
        lastDragPosition = eventData.position;
    }

    public void OnDrag(PointerEventData eventData)
    {
        if (Input.touchCount > 1 || currentZoom <= 1f) return;
        
        Vector2 delta = eventData.position - lastDragPosition;
        imageRect.anchoredPosition += delta * moveSpeed;
        velocity = delta * moveSpeed;
        lastDragPosition = eventData.position;
        
        ClampImagePosition();
    }

    public void OnEndDrag(PointerEventData eventData)
    {
        isDragging = false;
    }

    public void OnScroll(PointerEventData eventData)
    {
        float scrollDelta = eventData.scrollDelta.y;
        float zoomFactor = 1f + scrollDelta * zoomSpeed;
        ZoomImage(zoomFactor, eventData.position);
    }

    bool isTwo=false;
    public void OnPointerClick(PointerEventData eventData)
    {
        if (eventData.clickCount == 2)
        {
            HandleDoubleTap(eventData.position);
        }
        else if (eventData.clickCount == 1&&!isTwo)
        {
            float currentTime = Time.time;
            if (currentTime - lastTapTime < DoubleTapTime)
            {
                HandleDoubleTap(eventData.position);
            }
            lastTapTime = currentTime;
        }
    }

    private void HandleDoubleTap(Vector2 position)
    {
        if (currentZoom > 1f)
        {
            ResetView();
        }
        else
        {
            ZoomImage(2f, position);
        }
    }

    private void ZoomImage(float zoomFactor, Vector2 zoomCenter)
    {
        float newZoom = currentZoom * zoomFactor;
        newZoom = Mathf.Clamp(newZoom, minZoom, maxZoom);
        
        RectTransformUtility.ScreenPointToLocalPointInRectangle(
            imageRect, 
            zoomCenter, 
            null, 
            out Vector2 localPoint);
        
        Vector2 pivotOffset = (Vector2)imageRect.pivot - new Vector2(0.5f, 0.5f);
        Vector2 offset = localPoint * (newZoom - currentZoom);
        
        imageRect.localScale = Vector3.one * newZoom;
       // imageRect.anchoredPosition -= zoomCenter-imageRect.sizeDelta*imageRect.localScale.x;
        currentZoom = newZoom;
        
        ClampImagePosition();
    }

    private void ClampImagePosition()
    {
        if (currentZoom <= 1f)
        {
            imageRect.anchoredPosition = initialAnchoredPosition;
            return;
        }

        Vector3[] corners = new Vector3[4];
        imageRect.GetWorldCorners(corners);
        
        if (contentRect == null) return;
        
        Vector3[] contentCorners = new Vector3[4];
        contentRect.GetWorldCorners(contentCorners);
        
        float imageWidth = (corners[2].x - corners[0].x)*imageRect.localScale.x;
        float imageHeight = (corners[2].y - corners[0].y)*imageRect.localScale.x;
        
        float contentWidth = contentCorners[2].x - contentCorners[0].x;
        float contentHeight = contentCorners[2].y - contentCorners[0].y;
        
        float minX = contentWidth - imageWidth;
        float maxX = 0+ imageWidth;
        float minY = contentHeight - imageHeight;
        float maxY = 0+ imageHeight;
        
        Vector3 pos = imageRect.localPosition;
        pos.x = Mathf.Clamp(pos.x, minX, maxX);
        pos.y = Mathf.Clamp(pos.y, minY, maxY);
        
        // 弹性效果
        if (pos.x != imageRect.localPosition.x || pos.y != imageRect.localPosition.y)
        {
            velocity = Vector2.zero;
            imageRect.localPosition = Vector3.Lerp(imageRect.localPosition, pos, elasticFactor);
        }
        else
        {
            imageRect.localPosition = pos;
        }
    }

    public void ResetView()
    {
        currentZoom = 1f;
        imageRect.localScale = Vector3.one;
        imageRect.anchoredPosition = initialAnchoredPosition;
        velocity = Vector2.zero;
    }

    #if UNITY_EDITOR
    private void OnValidate()
    {
        if (EditorApplication.isPlayingOrWillChangePlaymode) return;
        
        if (imageRect == null) imageRect = GetComponent<RectTransform>();
        if (contentRect == null && transform.parent != null) 
            contentRect = transform.parent.GetComponent<RectTransform>();
        
        initialAnchoredPosition = imageRect.anchoredPosition;
        initialSizeDelta = imageRect.sizeDelta;
    }
    #endif
}