using UnityEngine;
using UnityEngine.XR.Interaction.Toolkit;

public class SwingingArmMotionScript : MonoBehaviour
{
    // Game Objects
    [SerializeField] private GameObject LeftHand;
    [SerializeField] private GameObject RightHand;
    [SerializeField] private GameObject MainCamera;
    [SerializeField] private ActionBasedContinuousMoveProvider _MoveProvider;

    // Vector3 Positions
    [SerializeField] private Vector3 PositionPreviousFrameLeftHand;
    [SerializeField] private Vector3 PositionPreviousFrameRightHand;
    [SerializeField] private Vector3 PlayerPositionPreviousFrame;
    [SerializeField] private Vector3 PlayerPositionCurrentFrame;
    [SerializeField] private Vector3 PositionCurrentFrameLeftHand;
    [SerializeField] private Vector3 PositionCurrentFrameRightHand;

    // Speed
    [SerializeField] private float BaseSpeed;        // Базовая скорость
    [SerializeField] private float SprintSpeedMultiplier; // Множитель для бега
    [SerializeField] private float HandSpeedThreshold;  // Порог скорости рук для бега
    private float CurrentSpeed;                          // Текущая скорость
    [SerializeField] private float HandSpeed;

    private float SmoothedSpeed;
    [SerializeField] private float SpeedSmoothingFactor;

    // _Stamina (выносливость)
    [SerializeField] private float _MaxStamina;       // Максимальная выносливость
    public float MaxStamina
    {
        get { return _MaxStamina; }
    }

    [SerializeField] private float _Stamina;               // Текущая выносливость
    public float Stamina
    {
        get { return _Stamina; }
        set { _Stamina = value; }
    }
    [SerializeField] private float StaminaDrainRate; // Скорость расхода выносливости (единиц/сек)
    [SerializeField] private float StaminaRecoveryRate; // Скорость восстановления (единиц/сек)
    [SerializeField] private float LowStaminaMultiplier; // Снижение скорости при низкой выносливости
    [SerializeField] private float StaminaRecoveryDelay; // Задержка перед восстановлением после израсходования

    [SerializeField] private bool IsRecovering = false; // Флаг для ожидания восстановления
    [SerializeField] private float RecoveryTimer; // Таймер восстановления

    [SerializeField] private bool _IsPreRecovery = false;
    public bool IsPreRecovery
    {
        get { return _IsPreRecovery; }
    }

    void Start()
    {
        BaseSpeed = _MoveProvider.moveSpeed;
        PlayerPositionPreviousFrame = transform.position; // Set current positions
        PositionPreviousFrameLeftHand = LeftHand.transform.position; // Set previous positions
        PositionPreviousFrameRightHand = RightHand.transform.position;
        CurrentSpeed = BaseSpeed; // Initialize to base speed
        SmoothedSpeed = BaseSpeed;

        _Stamina = _MaxStamina; // Инициализация выносливости
    }

    // Update is called once per frame
    void Update()
    {
        // Get positions of hands
        PositionCurrentFrameLeftHand = LeftHand.transform.position;
        PositionCurrentFrameRightHand = RightHand.transform.position;

        // Position of player
        PlayerPositionCurrentFrame = transform.position;

        // Get distance the hands and player has moved from last frame
        var playerDistanceMoved = Vector3.Distance(PlayerPositionCurrentFrame, PlayerPositionPreviousFrame);
        var leftHandDistanceMoved = Vector3.Distance(PositionPreviousFrameLeftHand, PositionCurrentFrameLeftHand);
        var rightHandDistanceMoved = Vector3.Distance(PositionPreviousFrameRightHand, PositionCurrentFrameRightHand);

        // Aggregate to get hand speed
        HandSpeed = ((leftHandDistanceMoved - playerDistanceMoved) + (rightHandDistanceMoved - playerDistanceMoved));

        if (IsRecovering)
        {
            RecoveryTimer += Time.deltaTime;
            if (RecoveryTimer >= StaminaRecoveryDelay)
            {
                IsRecovering = false;
                RecoveryTimer = 0;
            }
            if (HandSpeed > HandSpeedThreshold)
            {
                CurrentSpeed = BaseSpeed; // Замедляем, если стамина истощена
                RecoveryTimer = 0;
            }
        }
        if (!IsRecovering)
        {
            _Stamina += StaminaRecoveryRate * Time.deltaTime; // Восстанавливаем стамину
            _Stamina = Mathf.Clamp(_Stamina, 0, _MaxStamina);

            if (_IsPreRecovery)
            {
                if (_Stamina >= 0.5 * _MaxStamina)
                {
                    _IsPreRecovery = false;
                }
            }

            if (HandSpeed > HandSpeedThreshold)
            {
                _Stamina -= StaminaDrainRate * Time.deltaTime; // Уменьшаем стамину
                _Stamina = Mathf.Clamp(_Stamina, 0, _MaxStamina);
                if (!_IsPreRecovery)
                {
                    CurrentSpeed = BaseSpeed * SprintSpeedMultiplier; // Замедляем, если стамина истощена                
                }
                else if (_IsPreRecovery)
                {
                    CurrentSpeed = BaseSpeed;
                }
            }
            else
            {
                CurrentSpeed = BaseSpeed;
            }
        }
        if (_Stamina <= 0)
        {
            IsRecovering = true;
            _IsPreRecovery = true;
        }

        SmoothedSpeed = Mathf.Lerp(SmoothedSpeed, CurrentSpeed, SpeedSmoothingFactor);

        _MoveProvider.moveSpeed = SmoothedSpeed;

        // Set previous position of hands for next frame
        PositionPreviousFrameLeftHand = PositionCurrentFrameLeftHand;
        PositionPreviousFrameRightHand = PositionCurrentFrameRightHand;
        // Set player position previous frame
        PlayerPositionPreviousFrame = PlayerPositionCurrentFrame;
    }
}