using System.Collections.Generic;
using FishNet.Object;
using FishNet.Object.Synchronizing;
using UnityEngine;
using IStalk.Data;
using IStalk.Runner;

namespace IStalk.Core
{
    public class AntiAfkRitual : NetworkBehaviour
    {
        private readonly SyncVar<float> _ritualTimer = new();
        private readonly SyncVar<int> _targetObjectId = new();
        private readonly SyncVar<int> _voterCount = new();
        private readonly SyncVar<bool> _isActive = new();

        private readonly HashSet<NetworkObject> _voters = new();
        private NetworkObject _target;
        private ExtractionManager _extractionManager;

        private GlobalRules_SO Rules => GlobalRules_SO.Instance;

        public bool IsActive => _isActive.Value;
        public float Timer => _ritualTimer.Value;
        public int TargetId => _targetObjectId.Value;
        public int VoterCount => _voterCount.Value;

        public event System.Action<NetworkObject> OnRitualStarted;
        public event System.Action OnRitualCancelled;
        public event System.Action<NetworkObject> OnRitualComplete;

        public override void OnStartServer()
        {
            base.OnStartServer();
            _extractionManager = FindAnyObjectByType<ExtractionManager>();
        }

        [ServerRpc(RequireOwnership = false)]
        public void ServerVoteKick(NetworkObject voter, NetworkObject target)
        {
            if (voter == null || target == null) return;
            if (voter == target) return;

            var voterHealth = voter.GetComponent<RunnerHealth>();
            if (voterHealth != null && voterHealth.IsDown) return;

            var targetHealth = target.GetComponent<RunnerHealth>();
            if (targetHealth != null && targetHealth.IsDown) return;

            if (_isActive.Value && _target != target)
                return;

            if (!_isActive.Value)
            {
                _target = target;
                _targetObjectId.Value = target.ObjectId;
                _ritualTimer.Value = Rules.antiAfkRitualDuration;
                _isActive.Value = true;
                _voters.Clear();
            }

            _voters.Add(voter);
            _voterCount.Value = _voters.Count;

            if (_voters.Count < Rules.antiAfkMinVoters)
            {
                _isActive.Value = false;
                _voters.Clear();
                _voterCount.Value = 0;
                return;
            }

            RitualStartedObservers(target);
        }

        [ServerRpc(RequireOwnership = false)]
        public void ServerCancelVote(NetworkObject voter)
        {
            if (!_isActive.Value) return;
            _voters.Remove(voter);
            _voterCount.Value = _voters.Count;

            if (_voters.Count < Rules.antiAfkMinVoters)
            {
                _isActive.Value = false;
                _target = null;
                _targetObjectId.Value = 0;
                _voters.Clear();
                _voterCount.Value = 0;
                RitualCancelledObservers();
            }
        }

        private void Update()
        {
            if (!IsServerInitialized || !_isActive.Value) return;

            if (_voters.Count < Rules.antiAfkMinVoters)
            {
                CancelRitual();
                return;
            }

            _ritualTimer.Value -= Time.deltaTime;
            if (_ritualTimer.Value <= 0)
                CompleteRitual();
        }

        [Server]
        private void CompleteRitual()
        {
            if (_target == null) return;

            var health = _target.GetComponent<RunnerHealth>();
            if (health != null)
                health.TakeHit();

            if (health != null && !health.IsDown)
            {
                health.TakeHit();
                if (!health.IsDown) health.TakeHit();
            }

            if (_extractionManager != null)
                _extractionManager.MarkRunnerDead(_target);

            RitualCompleteObservers(_target);
            ResetState();
        }

        [Server]
        private void CancelRitual()
        {
            ResetState();
            RitualCancelledObservers();
        }

        private void ResetState()
        {
            _isActive.Value = false;
            _target = null;
            _targetObjectId.Value = 0;
            _voters.Clear();
            _voterCount.Value = 0;
            _ritualTimer.Value = 0;
        }

        [ObserversRpc]
        private void RitualStartedObservers(NetworkObject target)
        {
            OnRitualStarted?.Invoke(target);
        }

        [ObserversRpc]
        private void RitualCancelledObservers()
        {
            OnRitualCancelled?.Invoke();
        }

        [ObserversRpc]
        private void RitualCompleteObservers(NetworkObject target)
        {
            OnRitualComplete?.Invoke(target);
        }
    }
}
