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

namespace IStalk.Core
{
    public class ExtractionManager : NetworkBehaviour
    {
        private readonly SyncVar<int> _teamLootDeposited = new();
        private readonly SyncList<int> _extractedPlayerIds = new();

        private GlobalRules_SO Rules => GlobalRules_SO.Instance;
        private List<Vector3> _altarPositions = new();

        public int TeamLootDeposited => _teamLootDeposited.Value;
        public int ExtractionThreshold => Rules.extractionThreshold;
        public bool IsExtractionMet => _teamLootDeposited.Value >= Rules.extractionThreshold;

        public event System.Action<int> OnLootDeposited;
        public event System.Action<int> OnPlayerExtracted;
        public event System.Action OnExtractionThresholdMet;

        public void SetAltarPositions(List<Vector3> positions)
        {
            _altarPositions = positions;
        }

        [Server]
        public void DepositLoot(PlayerInventory inventory, int amount)
        {
            var items = inventory.GetItems();
            foreach (var id in items)
                inventory.TryRemoveItem(id);

            _teamLootDeposited.Value += amount;
            NotifyDepositObservers(_teamLootDeposited.Value);

            if (IsExtractionMet)
                OnExtractionThresholdMet?.Invoke();
        }

        [ObserversRpc]
        private void NotifyDepositObservers(int totalDeposited)
        {
            OnLootDeposited?.Invoke(totalDeposited);
        }

        [Server]
        public bool TryExtract(NetworkObject player)
        {
            if (!IsExtractionMet) return false;
            if (_extractedPlayerIds.Contains(player.ObjectId)) return false;

            _extractedPlayerIds.Add(player.ObjectId);
            OnPlayerExtracted?.Invoke(player.ObjectId);
            return true;
        }

        public bool IsNearAltar(Vector3 position)
        {
            foreach (var altar in _altarPositions)
            {
                if (Vector3.Distance(position, altar) <= Rules.altarInteractRadius)
                    return true;
            }
            return false;
        }

        public Vector3 GetNearestAltar(Vector3 position)
        {
            Vector3 nearest = Vector3.zero;
            float minDist = float.MaxValue;

            foreach (var altar in _altarPositions)
            {
                float dist = Vector3.Distance(position, altar);
                if (dist < minDist)
                {
                    minDist = dist;
                    nearest = altar;
                }
            }
            return nearest;
        }
    }
}
