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

namespace IStalk.Runner
{
    public class WorldItem : NetworkBehaviour
    {
        [SerializeField] private MeshRenderer _renderer;
        [SerializeField] private Light _glowLight;
        [SerializeField] private float _bobAmplitude = 0.1f;
        [SerializeField] private float _bobFrequency = 1.5f;

        private readonly SyncVar<string> _itemId = new();
        private Vector3 _basePosition;
        private float _bobPhase;
        private ItemData_SO _cachedData;

        public string ItemId => _itemId.Value;

        public override void OnStartClient()
        {
            base.OnStartClient();
            _basePosition = transform.position;
            _bobPhase = Random.value * Mathf.PI * 2f;
            _itemId.OnChange += OnItemIdChanged;
            ApplyVisuals();
        }

        private void Update()
        {
            float y = _basePosition.y + Mathf.Sin(Time.time * _bobFrequency + _bobPhase) * _bobAmplitude;
            transform.position = new Vector3(_basePosition.x, y, _basePosition.z);
            transform.Rotate(Vector3.up, 45f * Time.deltaTime, Space.World);
        }

        private void OnItemIdChanged(string prev, string next, bool asServer)
        {
            ApplyVisuals();
        }

        private void ApplyVisuals()
        {
            if (string.IsNullOrEmpty(_itemId.Value)) return;
            _cachedData = ItemDatabase.Instance.GetLootItem(_itemId.Value);
            if (_cachedData == null) return;

            if (_glowLight != null)
                _glowLight.color = _cachedData.glowColour;
        }

        [Server]
        public void Initialize(string itemId)
        {
            _itemId.Value = itemId;
        }

        [Server]
        public void PickUp(PlayerInventory inventory)
        {
            if (inventory.TryAddItem(_itemId.Value))
            {
                var data = ItemDatabase.Instance.GetLootItem(_itemId.Value);
                if (data != null && data.pickupSound != null)
                    PlayPickupSoundObservers(data.noiseRadius);

                ServerManager.Despawn(NetworkObject);
            }
        }

        [ObserversRpc]
        private void PlayPickupSoundObservers(float noiseRadius)
        {
            var data = ItemDatabase.Instance.GetLootItem(_itemId.Value);
            if (data?.pickupSound != null)
                AudioSource.PlayClipAtPoint(data.pickupSound, transform.position);
        }

        public static void SpawnWorldItem(string itemId, Vector3 position)
        {
            if (!InstanceFinder.IsServerStarted) return;

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

            var go = Object.Instantiate(data.worldPrefab, position, Quaternion.identity);
            var nob = go.GetComponent<NetworkObject>();
            var worldItem = go.GetComponent<WorldItem>();

            if (nob != null && worldItem != null)
            {
                InstanceFinder.ServerManager.Spawn(nob);
                worldItem.Initialize(itemId);
            }
        }
    }
}
