using UnityEngine;
using FishNet.Object;
using IStalk.Runner;
using IStalk.Core;

namespace IStalk.UI
{
    public class SpectatorCamera : NetworkBehaviour
    {
        [SerializeField] private Camera _spectatorCam;
        [SerializeField] private float _followDistance = 5f;
        [SerializeField] private float _followHeight = 3f;
        [SerializeField] private float _smoothSpeed = 5f;

        private Transform[] _spectateTargets;
        private int _currentTargetIndex;
        private bool _isSpectating;
        private RunnerHealth _health;

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

            _spectatorCam.enabled = false;
            _health = GetComponent<RunnerHealth>();

            if (_health != null)
            {
                _health.OnDowned += EnterSpectator;
                _health.OnRevived += ExitSpectator;
            }

            if (GameManager.Instance != null)
                GameManager.Instance.OnStateChanged += HandleMatchEnd;
        }

        private void EnterSpectator()
        {
            _isSpectating = true;
            _spectatorCam.enabled = true;
            GatherTargets();
        }

        private void ExitSpectator()
        {
            _isSpectating = false;
            _spectatorCam.enabled = false;
        }

        private void HandleMatchEnd(MatchState state)
        {
            if (state == MatchState.RunnersWin || state == MatchState.EyeWins)
            {
                if (!_isSpectating) return;
                _spectatorCam.enabled = true;
            }
        }

        private void GatherTargets()
        {
            var runners = FindObjectsByType<RunnerController>(FindObjectsSortMode.None);
            var alive = new System.Collections.Generic.List<Transform>();
            foreach (var r in runners)
            {
                if (r.gameObject == gameObject) continue;
                var h = r.GetComponent<RunnerHealth>();
                if (h == null || !h.IsDown)
                    alive.Add(r.transform);
            }
            _spectateTargets = alive.ToArray();
            _currentTargetIndex = 0;
        }

        private void Update()
        {
            if (!IsOwner || !_isSpectating) return;

            if (Input.GetKeyDown(KeyCode.Mouse0) || Input.GetKeyDown(KeyCode.RightArrow))
            {
                _currentTargetIndex = (_currentTargetIndex + 1) % Mathf.Max(1, _spectateTargets.Length);
            }
            if (Input.GetKeyDown(KeyCode.Mouse1) || Input.GetKeyDown(KeyCode.LeftArrow))
            {
                _currentTargetIndex--;
                if (_currentTargetIndex < 0) _currentTargetIndex = _spectateTargets.Length - 1;
            }

            FollowTarget();
        }

        private void FollowTarget()
        {
            if (_spectateTargets == null || _spectateTargets.Length == 0) return;
            if (_currentTargetIndex >= _spectateTargets.Length) _currentTargetIndex = 0;

            Transform target = _spectateTargets[_currentTargetIndex];
            if (target == null)
            {
                GatherTargets();
                return;
            }

            Vector3 desiredPos = target.position - target.forward * _followDistance + Vector3.up * _followHeight;
            _spectatorCam.transform.position = Vector3.Lerp(_spectatorCam.transform.position, desiredPos, Time.deltaTime * _smoothSpeed);
            _spectatorCam.transform.LookAt(target.position + Vector3.up);
        }

        private void OnDestroy()
        {
            if (_health != null)
            {
                _health.OnDowned -= EnterSpectator;
                _health.OnRevived -= ExitSpectator;
            }
            if (GameManager.Instance != null)
                GameManager.Instance.OnStateChanged -= HandleMatchEnd;
        }
    }
}
