using FishNet.Object;
using FishNet.Object.Synchronizing;
using UnityEngine;
using IStalk.Data;

namespace IStalk.Runner
{
    public class RunnerStamina : NetworkBehaviour
    {
        [SerializeField] private float _maxStamina = 100f;
        [SerializeField] private float _sprintDrainRate = 20f;
        [SerializeField] private float _regenRate = 15f;
        [SerializeField] private float _regenDelay = 1f;
        [SerializeField] private float _dashCost = 30f;
        [SerializeField] private float _wallRunDrainRate = 10f;

        private readonly SyncVar<float> _currentStamina = new(new SyncTypeSettings(0.2f));
        private float _regenTimer;

        public float CurrentStamina => _currentStamina.Value;
        public float MaxStamina => _maxStamina;
        public float StaminaPercent => _currentStamina.Value / _maxStamina;
        public bool CanSprint => _currentStamina.Value > 5f;
        public bool CanDash => _currentStamina.Value >= _dashCost;

        public event System.Action<float> OnStaminaChanged;

        public override void OnStartServer()
        {
            base.OnStartServer();
            _currentStamina.Value = _maxStamina;
        }

        public override void OnStartNetwork()
        {
            base.OnStartNetwork();
            _currentStamina.OnChange += (prev, next, asServer) => OnStaminaChanged?.Invoke(next);
        }

        private void Update()
        {
            if (!IsServerStarted) return;

            _regenTimer -= Time.deltaTime;
            if (_regenTimer <= 0 && _currentStamina.Value < _maxStamina)
            {
                _currentStamina.Value = Mathf.Min(_maxStamina, _currentStamina.Value + _regenRate * Time.deltaTime);
            }
        }

        [Server]
        public void DrainSprint(float dt)
        {
            _currentStamina.Value = Mathf.Max(0, _currentStamina.Value - _sprintDrainRate * dt);
            _regenTimer = _regenDelay;
        }

        [Server]
        public void DrainWallRun(float dt)
        {
            _currentStamina.Value = Mathf.Max(0, _currentStamina.Value - _wallRunDrainRate * dt);
            _regenTimer = _regenDelay;
        }

        [Server]
        public bool TryDash()
        {
            if (_currentStamina.Value < _dashCost) return false;
            _currentStamina.Value -= _dashCost;
            _regenTimer = _regenDelay;
            return true;
        }
    }
}
