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

namespace IStalk.Runner
{
    public class PlayerInventory : NetworkBehaviour
    {
        [SerializeField] private int _maxSlots = 6;

        private readonly SyncList<string> _itemIds = new();
        private WeightComponent _weight;

        public int SlotCount => _maxSlots;
        public int UsedSlots => _itemIds.Count;
        public bool HasSpace => _itemIds.Count < _maxSlots;
        public int TotalLootValue { get; private set; }

        public event System.Action OnInventoryChanged;

        public override void OnStartNetwork()
        {
            base.OnStartNetwork();
            _weight = GetComponent<WeightComponent>();
            _itemIds.OnChange += HandleSyncListChange;
        }

        private void HandleSyncListChange(SyncListOperation op, int index, string oldItem, string newItem, bool asServer)
        {
            RecalculateValue();
            OnInventoryChanged?.Invoke();
        }

        [Server]
        public bool TryAddItem(string itemId)
        {
            if (_itemIds.Count >= _maxSlots) return false;

            var data = ItemDatabase.Instance.GetLootItem(itemId);
            if (data == null) return false;

            _itemIds.Add(itemId);
            _weight.AddWeight(data.weight);
            return true;
        }

        [Server]
        public bool TryRemoveItem(string itemId)
        {
            int idx = _itemIds.IndexOf(itemId);
            if (idx < 0) return false;

            var data = ItemDatabase.Instance.GetLootItem(itemId);
            _itemIds.RemoveAt(idx);
            if (data != null) _weight.RemoveWeight(data.weight);
            return true;
        }

        [Server]
        public void DropAll(Vector3 dropPosition)
        {
            for (int i = _itemIds.Count - 1; i >= 0; i--)
            {
                string id = _itemIds[i];
                _itemIds.RemoveAt(i);

                var data = ItemDatabase.Instance.GetLootItem(id);
                if (data != null)
                {
                    _weight.RemoveWeight(data.weight);
                    WorldItem.SpawnWorldItem(id, dropPosition + Random.insideUnitSphere * 0.5f);
                }
            }
        }

        public List<string> GetItems() => new(_itemIds);

        public bool Contains(string itemId) => _itemIds.Contains(itemId);

        private void RecalculateValue()
        {
            int total = 0;
            foreach (var id in _itemIds)
            {
                var data = ItemDatabase.Instance.GetLootItem(id);
                if (data != null) total += data.lootValue;
            }
            TotalLootValue = total;
        }
    }
}
