using System;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.EventSystems;

namespace RothenburgAR.UI
{
    public class DetailsModelBehaviour : MonoBehaviour
    {
        public GameObject CurrentModel;

        private float _baseRotationSpeed = 0.5f;
        private float _rotationSpeed = 0.5f;
        private bool _autoRotate = true;

        private Quaternion _startingDragRotation = Quaternion.identity;
        private Queue<Vector2> _previousMousePositions = new Queue<Vector2>();

        public void OnEnable()
        {
            SetDefaultValues();
        }

        void FixedUpdate()
        {
            if (_autoRotate == true && CurrentModel != null)
            {
                NormalizeRotationSpeed();
                CurrentModel.transform.Rotate(Vector3.up, _rotationSpeed);
            }
        }

        private void NormalizeRotationSpeed()
        {
            if (_rotationSpeed > 0)
            {
                _rotationSpeed = (_rotationSpeed - _baseRotationSpeed) * 0.99f + _baseRotationSpeed;
            }
            else if (_rotationSpeed < 0)
            {
                _rotationSpeed = (_rotationSpeed + _baseRotationSpeed) * 0.99f - _baseRotationSpeed;
            }
        }

        public void RotateModelByDrag(PointerEventData data)
        {
            if (CurrentModel == null) return;

            var modelDistanceConst = 50.0f;
            var draggedVector = data.pressPosition - data.position;
            var draggedDistanceX = draggedVector.x;
            var rotationAngle = Mathf.Atan(draggedDistanceX / modelDistanceConst) * Mathf.Rad2Deg;
            var targetRotation = _startingDragRotation * Quaternion.Euler(Vector3.up * rotationAngle);
            CurrentModel.transform.rotation = targetRotation;

            _previousMousePositions.Enqueue(data.position);
            if (_previousMousePositions.Count > 2)
            {
                _previousMousePositions.Dequeue();
            }
        }

        public void BeginRotateModelByDrag(PointerEventData data)
        {
            if (CurrentModel == null) return;
            _startingDragRotation = CurrentModel.transform.rotation;
            _autoRotate = false;
        }

        public void EndRotateModelByDrag(PointerEventData data)
        {
            if (CurrentModel == null) return;
            var previousMousePosition = _previousMousePositions.Dequeue();

            var endDistance = previousMousePosition.x - data.position.x;
            _rotationSpeed = endDistance / 15;
            _autoRotate = true;
        }

        private void SetDefaultValues()
        {
            _rotationSpeed = 0.5f;
            _autoRotate = true;
            _startingDragRotation = Quaternion.identity;
            _previousMousePositions.Clear();
        }
    }
}