using RootMotion.FinalIK;
using UnityEngine;

namespace NBF
{
    /// <summary>
    /// 
    /// </summary>
    public class PlayerLocalMover : PlayerDriveBase
    {
        public LayerMask interactableLayer;

        public LookAtIK lookAtIK; // 挂在背部上的 LookAtIK 脚本
        public float aimDistance = 1.5f; // 目标点离相机多远

        private Transform lookTarget; // 实际目标点
        [Header("限制角度（单位：度）")] public float maxUpAngle = 20f; // 相机抬头最多20°
        public float maxDownAngle = 40f; // 相机低头最多40°

        /// <summary>
        /// 基础移动速度
        /// </summary>
        private const float MoveSpeed = 3f;

        /// <summary>
        /// 冲刺速度
        /// </summary>
        private const float SprintSpeed = 5f;

        private float acceleration = 10f; // 加速度

        /// <summary>
        /// 重力加速度
        /// </summary>
        private float gravity = 9.81f;

        private float groundedGravity = -0.5f; // 小的向下力确保角色保持在地面
        private float airControl = 0.5f; // 空中控制系数


        private float verticalVelocity = 0f;
        private Vector3 currentVelocity = Vector3.zero;
        private float currentSpeed = 0f;

        [Tooltip("视角旋转敏感度")] public Vector2 sensitivity = new Vector2(0.015f, 0.015f);
        public float minPitch = -40.0f;
        public float maxPitch = 75.0f;
        public float boatMaxPitch = 60;
        private float _cameraPitch;
        private Vector3 _rotationInput = Vector3.zero;
        private bool _isRun;

        [HideInInspector] public int nextShowSlotIndex = -1;

        protected override void OnStart()
        {
            lookAtIK = Character.gameObject.GetComponent<LookAtIK>();
            lookTarget = new GameObject("SpineLookTarget").transform;
            lookTarget.SetParent(Character.transform);
            interactableLayer = LayerMask.GetMask("Interactive");

            InputManager.OnPlayerCanceled += OnPlayerCanceled;
            InputManager.OnPlayerPerformed += OnPlayerPerformed;
        }

        protected override void OnUpdate()
        {
            UpdateGear();
            InteractiveCheck();
        }

        protected override void OnLateUpdate()
        {
            UpdatePlayerHandView();
        }

        protected override void OnFixedUpdate()
        {
            UpdatePlayerPosition();
            UpdatePlayerRotation();
        }

        public override void OnDestroy()
        {
            InputManager.OnPlayerCanceled -= OnPlayerCanceled;
            InputManager.OnPlayerPerformed -= OnPlayerPerformed;
        }

        #region 钓组控制

        private void UpdateGear()
        {
            if (Player.CanChangeGear())
            {
                if (nextShowSlotIndex > 0)
                {
                    var data = Fishing.Inst.Datasource;
                    data.SetSelfTestGear(nextShowSlotIndex);
                    nextShowSlotIndex = -1;
                }
            }
        }

        #endregion

        #region 事件输入

        private void OnPlayerPerformed(string action)
        {
            if (action == "Run")
            {
                _isRun = true;
            }
        }

        private void OnPlayerCanceled(string action)
        {
            if (action == "Run")
            {
                _isRun = false;
            }
            else if (action.StartsWith("Quick"))
            {
                nextShowSlotIndex = int.Parse(action.Substring("Quick".Length));
            }
            else if (action == "UseTorch")
            {
                Player.Data.openLight = !Player.Data.openLight;
            }
            else if (action == "UseTelescope")
            {
                Player.Data.openTelescope = !Player.Data.openTelescope;
                Player.ToggleTelescope();
            }
        }

        #endregion

        #region 交互检测

        private RaycastHit hitInfo;
        private bool isHit;
        private readonly float _interactionDistance = 8f;
        private InteractiveObject _lastInteractiveObject;

        private void InteractiveCheck()
        {
            if (Player.NowBoat)
            {
                SetInteractiveObject(null);
                return;
            }

            if (Player && Player.Fsm.CurrentStateId == States.Player.Idle)
            {
                // 从屏幕中心发射射线
                Ray ray = BaseCamera.Main.ViewportPointToRay(new Vector3(0.5f, 0.5f, 0));
                isHit = Physics.Raycast(ray, out hitInfo, _interactionDistance, interactableLayer);

                // 检测到可交互物体时
                if (isHit)
                {
                    var interactiveObject = hitInfo.transform.gameObject.GetComponent<InteractiveObject>();
                    if (interactiveObject != null)
                    {
                        SetInteractiveObject(interactiveObject);
                        return;
                    }
                }
            }


            SetInteractiveObject(null);
        }

        private void SetInteractiveObject(InteractiveObject interactiveObject)
        {
            if (_lastInteractiveObject != interactiveObject)
            {
                _lastInteractiveObject = interactiveObject;
                InputManager.Instance.OnInteractiveObject(_lastInteractiveObject);
            }
        }

        #endregion

        #region 肩膀控制

        private void UpdatePlayerHandView()
        {
            var cameraTransform = BaseCamera.Main.transform;
            Vector3 cameraForward = cameraTransform.forward;
            Vector3 flatForward = Vector3.ProjectOnPlane(cameraForward, Vector3.up).normalized;

            // 获取相机 pitch 角度（负值是上看，正值是下看）
            float pitchAngle = Vector3.SignedAngle(flatForward, cameraForward, cameraTransform.right);

            // 限制 pitch 角度
            pitchAngle = Mathf.Clamp(pitchAngle, -maxUpAngle, maxDownAngle);

            // 重新构造限制后的目标方向
            Quaternion limitedPitch = Quaternion.AngleAxis(pitchAngle, cameraTransform.right);
            Vector3 limitedDirection = limitedPitch * flatForward;

            // 设置目标点
            lookTarget.position = cameraTransform.position + limitedDirection * aimDistance;
            lookAtIK.solver.target = lookTarget;
        }

        #endregion

        #region 位移和旋转控制

        private void UpdatePlayerPosition()
        {
            Vector2 movementInput = InputManager.GetMovementInput();
            if (Player.NowBoat)
            {
                Player.NowBoat.BoatInput(movementInput);
                return;
            }

            Vector3 movementDirection = Vector3.zero;

            movementDirection += Vector3.forward * movementInput.y;
            movementDirection += Vector3.right * movementInput.x;

            movementDirection = movementDirection.relativeTo(BaseCamera.Main.transform, Character.transform.up);

            // 计算目标速度
            float targetSpeed = _isRun ? SprintSpeed : MoveSpeed;

            // 平滑加速
            if (movementDirection.magnitude > 0.1f)
            {
                currentSpeed = Mathf.Lerp(currentSpeed, targetSpeed, acceleration * Time.deltaTime);
            }
            else
            {
                currentSpeed = Mathf.Lerp(currentSpeed, 0f, acceleration * 2f * Time.deltaTime);
            }

            // 处理重力
            if (Character.CharacterController.isGrounded)
            {
                verticalVelocity = groundedGravity;

                // 地面移动 - 完全控制
                currentVelocity = Vector3.Lerp(currentVelocity, movementDirection.normalized * currentSpeed,
                    acceleration * Time.deltaTime);
            }
            else
            {
                verticalVelocity -= gravity * Time.deltaTime;

                // 空中移动 - 有限控制
                Vector3 targetAirVelocity = movementDirection.normalized * currentSpeed * airControl;
                currentVelocity = Vector3.Lerp(currentVelocity,
                    new Vector3(targetAirVelocity.x, currentVelocity.y, targetAirVelocity.z),
                    acceleration * Time.deltaTime);
            }

            // 组合移动
            Vector3 totalMovement = currentVelocity * Time.deltaTime;
            totalMovement.y = verticalVelocity * Time.deltaTime;

            Character.CollisionFlags = Character.CharacterController.Move(totalMovement);
        }

        private void UpdatePlayerRotation()
        {
            // Look
            Vector2 lookInput = InputManager.GetLookInput() * sensitivity;

            if (lookInput.x != 0.0f)
            {
                _rotationInput.y += lookInput.x;
            }

            AddControlPitchInput(-lookInput.y, minPitch, Player.NowBoat ? boatMaxPitch : maxPitch);

            Player.CameraRoot.transform.localRotation = Quaternion.Euler(_cameraPitch, 0.0f, 0.0f);
            if (_rotationInput != Vector3.zero)
            {
                Character.CharacterController.transform.rotation *= Quaternion.Euler(_rotationInput);
                _rotationInput = Vector3.zero;
            }
        }


        /// <summary>
        /// 添加输入（影响俯仰）。
        /// 此操作应用于相机父级的本地旋转。
        /// </summary>
        private void AddControlPitchInput(float value, float minPitch = -40.0f, float maxPitch = 70.0f)
        {
            if (value != 0.0f)
                _cameraPitch = VectorUtil.ClampAngle(_cameraPitch + value, minPitch, maxPitch);
        }

        #endregion
    }
}