using System;
using Core.Ports;
using UnityEngine;
using KBCore.Refs;

namespace Infrastructure.Unity
{
    [RequireComponent(typeof(Rigidbody))]
    public class HunterNpcController : MonoBehaviour
    {
        [SerializeField] private float moveSpeed = 7f;
        [SerializeField] private LayerMask tileLayer;
        
        [Self] [SerializeField] private Rigidbody rb;
        
        private PlayerController _target;
        private Action _onCaughtCallback;
        private Func<float> _timeDilationProvider;
        
        public void Initialize(PlayerController target, Action onCaughtCallback, Func<float> timeDilationProvider)
        {
            _target = target;
            _onCaughtCallback = onCaughtCallback;
            _timeDilationProvider = timeDilationProvider;
        }

        private void FixedUpdate()
        {
            if (!_target) return;
            
            var dilation = _timeDilationProvider?.Invoke() ?? 1f;
            
            var direction = (_target.transform.position - transform.position).normalized;
            direction.y = 0; 
            direction.Normalize();
                
            rb.MovePosition(rb.position + direction * (moveSpeed * dilation * Time.fixedDeltaTime));
            
            if (Physics.Raycast(transform.position, Vector3.down, out var hit, 2f, tileLayer))
            {
                if (hit.collider.TryGetComponent<ITileView>(out var tileView))
                {
                    tileView.StepOn();
                }
            }
        }
        
        private bool IsGrounded()
        {
            return Physics.Raycast(transform.position, Vector3.down, out var hit, 2f, tileLayer);
        }
        
        private void OnDrawGizmos()
        {
            if (!_target) return;
            
            Gizmos.color = Color.red;
            Gizmos.DrawLine(transform.position, _target.transform.position);
        }

        private void OnCollisionEnter(Collision other)
        {
            if (!_target) return;
            
            if (other.gameObject == _target.gameObject)
            {
                _onCaughtCallback?.Invoke();
                Destroy(gameObject);
            }
        }
    }
}
