using System;
using Cinemachine.Utility;
using UnityEngine;

namespace Cinemachine.Examples
{
    public class PlayerMove : MonoBehaviour
    {
        public float Speed;
        public float VelocityDamping;
        public float JumpTime;

        public enum ForwardMode
        {
            Camera,
            Player,
            World
        };

        public ForwardMode InputForward;

        public bool RotatePlayer = true;

        public Action SpaceAction;
        public Action EnterAction;

        Vector3 m_currentVleocity;
        float m_currentJumpSpeed;
        float m_restY;

        private void Reset()
        {
            Speed = 5;
            InputForward = ForwardMode.Camera;
            RotatePlayer = true;
            VelocityDamping = 0.5f;
            m_currentVleocity = Vector3.zero;
            JumpTime = 1;
            m_currentJumpSpeed = 0;
        }

        private void OnEnable()
        {
            m_currentJumpSpeed = 0;
            m_restY = transform.position.y;
            SpaceAction -= Jump;
            SpaceAction += Jump;
        }

        void Update()
        {
#if ENABLE_LEGACY_INPUT_MANAGER
            Vector3 fwd;
            switch (InputForward)
            {
                case ForwardMode.Camera:
                    fwd = Camera.main.transform.forward;
                    break;
                case ForwardMode.Player:
                    fwd = transform.forward;
                    break;
                case ForwardMode.World:
                default:
                    fwd = Vector3.forward;
                    break;
            }

            fwd.y = 0;
            fwd = fwd.normalized;
            if (fwd.sqrMagnitude < 0.01f)
                return;

            Quaternion inputFrame = Quaternion.LookRotation(fwd, Vector3.up);
            Vector3 input = new Vector3(Input.GetAxis("Horizontal"), 0, Input.GetAxis("Vertical"));
            input = inputFrame * input;

            var dt = Time.deltaTime;
            var desiredVelocity = input * Speed;
            var deltaVel = desiredVelocity - m_currentVleocity;
            m_currentVleocity += Damper.Damp(deltaVel, VelocityDamping, dt);

            transform.position += m_currentVleocity * dt;
            if (RotatePlayer && m_currentVleocity.sqrMagnitude > 0.01f)
            {
                var qA = transform.rotation;
                var qB = Quaternion.LookRotation(
                    (InputForward == ForwardMode.Player && Vector3.Dot(fwd, m_currentVleocity) < 0)
                        ? -m_currentVleocity
                        : m_currentVleocity);
                transform.rotation = Quaternion.Slerp(qA, qB, Damper.Damp(1, VelocityDamping, dt));
            }

            // Process jump
            if (m_currentJumpSpeed != 0)
                m_currentJumpSpeed -= 10 * dt;
            var p = transform.position;
            p.y += m_currentJumpSpeed * dt;
            if (p.y < m_restY)
            {
                p.y = m_restY;
                m_currentJumpSpeed = 0;
            }

            transform.position = p;

            if (Input.GetKeyDown(KeyCode.Space) && SpaceAction != null)
                SpaceAction();
            if (Input.GetKeyDown(KeyCode.Return) && EnterAction != null)
                EnterAction();
#else
        InputSystemHelper.EnableBackendsWarningMessage();
#endif
        }

        public void Jump()
        {
            m_currentJumpSpeed += 10 * JumpTime * 0.5f;
        }
    }
}