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

namespace IStalk.Props
{
    public class IncarnationProp : PropBase
    {
        [SerializeField] private float _incarnationDreadCost = 20f;
        [SerializeField] private float _moveDreadCostPerSecond = 5f;
        [SerializeField] private float _moveSpeed = 3f;
        [SerializeField] private AudioClip _incarnateSound;

        private readonly SyncVar<bool> _isIncarnated = new();
        private DreadEconomy _dread;

        public bool IsIncarnated => _isIncarnated.Value;

        public override void OnStartClient()
        {
            base.OnStartClient();
            _isIncarnated.OnChange += OnIncarnatedChanged;
        }

        [Server]
        public bool TryIncarnate(DreadEconomy dread)
        {
            if (_isIncarnated.Value) return false;
            if (!dread.TrySpend(_incarnationDreadCost)) return false;

            _dread = dread;
            _isIncarnated.Value = true;
            PlayIncarnateSoundObservers();
            return true;
        }

        [Server]
        public void MoveIncarnated(Vector3 direction)
        {
            if (!_isIncarnated.Value || _dread == null) return;

            float cost = _moveDreadCostPerSecond * Time.deltaTime;
            if (!_dread.TrySpend(cost))
            {
                EndIncarnation();
                return;
            }

            transform.position += direction.normalized * _moveSpeed * Time.deltaTime;
        }

        [Server]
        public void EndIncarnation()
        {
            _isIncarnated.Value = false;
            _dread = null;
        }

        [ObserversRpc]
        private void PlayIncarnateSoundObservers()
        {
            if (_incarnateSound != null)
                AudioSource.PlayClipAtPoint(_incarnateSound, transform.position);
        }

        private static readonly int EmissionIntensity = Shader.PropertyToID("_EmissionIntensity");
        private static MaterialPropertyBlock _propBlock;

        private void OnIncarnatedChanged(bool prev, bool next, bool asServer)
        {
            if (_renderer == null) return;
            _propBlock ??= new MaterialPropertyBlock();
            _renderer.GetPropertyBlock(_propBlock);
            _propBlock.SetFloat(EmissionIntensity, next ? 2f : 0f);
            _renderer.SetPropertyBlock(_propBlock);
        }
    }
}
