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

namespace IStalk.Eye
{
    public class EyeTrapPlacer : NetworkBehaviour
    {
        [SerializeField] private LayerMask _placementLayer;

        private DreadEconomy _dread;
        private TrapData_SO _selectedTrap;
        private readonly SyncVar<int> _activeTrapCount = new();
        private float _costMultiplier = 1f;
        private int _maxActiveBonus = 0;

        public void ApplyTypeModifiers(float costMult, int maxActiveBonus)
        {
            _costMultiplier = costMult;
            _maxActiveBonus = maxActiveBonus;
        }

        public override void OnStartClient()
        {
            base.OnStartClient();
            if (!IsOwner)
            {
                enabled = false;
                return;
            }
        }

        public override void OnStartServer()
        {
            base.OnStartServer();
            _dread = GetComponent<DreadEconomy>();
        }

        public void SelectTrap(TrapData_SO trap)
        {
            _selectedTrap = trap;
        }

        private void Update()
        {
            if (!IsOwner) return;
            if (_selectedTrap == null) return;

            if (Input.GetMouseButtonDown(1))
            {
                Vector3 worldPos = GetMouseWorldPosition();
                if (worldPos != Vector3.zero)
                    ServerPlaceTrap(_selectedTrap.trapId, worldPos);
            }
        }

        [ServerRpc]
        private void ServerPlaceTrap(string trapId, Vector3 position)
        {
            var trapData = ItemDatabase.Instance.GetTrap(trapId);
            if (trapData == null) return;

            int maxActive = trapData.maxActivePerMatch + _maxActiveBonus;
            if (maxActive > 0 && _activeTrapCount.Value >= maxActive)
                return;

            int adjustedCost = Mathf.RoundToInt(trapData.dreadCost * _costMultiplier);
            if (!_dread.TrySpend(adjustedCost))
                return;

            if (trapData.placedPrefab == null) return;

            var go = Instantiate(trapData.placedPrefab, position, Quaternion.identity);
            var nob = go.GetComponent<NetworkObject>();
            if (nob == null) return;

            InstanceFinder.ServerManager.Spawn(nob);

            var trapInstance = go.GetComponent<TrapInstance>();
            if (trapInstance != null)
                trapInstance.Initialize(trapId);

            _activeTrapCount.Value++;
            PlayPlacementSoundObservers(position);
        }

        [ObserversRpc]
        private void PlayPlacementSoundObservers(Vector3 position)
        {
            if (_selectedTrap != null && _selectedTrap.placementSound != null)
                AudioSource.PlayClipAtPoint(_selectedTrap.placementSound, position);
        }

        private Vector3 GetMouseWorldPosition()
        {
            Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
            Plane groundPlane = new(Vector3.up, Vector3.zero);
            if (groundPlane.Raycast(ray, out float dist))
                return ray.GetPoint(dist);
            return Vector3.zero;
        }
    }
}
