using UnityEngine;

namespace Shooter.Gameplay
{
    /// <summary>
    /// Базовый враг. Хранит общие данные (здоровье через <see cref="DamageControl"/>,
    /// точки огня, выпадающий лут) и общую логику: поворот корпуса, «тряску» от
    /// попаданий, гибель с эффектом и дропом, пробуждение при появлении в кадре.
    /// Конкретные враги наследуются и задают своё поведение в собственных Update/корутинах.
    /// </summary>
    public class Enemy : MonoBehaviour
    {
        protected DamageControl m_DamageControl;

        [Header("Эффекты")]
        [SerializeField] protected GameObject m_DeathParticlePrefab;
        [SerializeField] protected GameObject m_SpawnParticlePrefab;

        [Header("Узлы и точки")]
        public Transform ShakeBase;
        public Transform m_RotationBase;
        public Transform m_FirePoint;

        [Header("Лут")]
        public GameObject[] m_ItemPrefabs;
        [Tooltip("Сколько предметов выпадает при гибели")]
        public int m_ItemDropCount = 1;

        [Header("Поведение")]
        public bool m_StartAttack = false;
        [Tooltip("Насколько враг проходит вперёд при выходе на позицию")]
        public float m_StartWalkDistance = 10;
        public Animator m_Animator;

        [HideInInspector] public EnemyGroup MyGroup;
        [HideInInspector] public Vector3 MoveDirection;
        [HideInInspector] public Vector3 InitPosition;
        [HideInInspector] public bool m_FacePlayer = false;
        [HideInInspector] public bool m_IsDead = false;
        [HideInInspector] public bool m_Alerted = false;

        // Внутренние флаги ИИ.
        bool m_CanChangeTargetPosition = true;
        bool m_FrontClear = true;
        bool m_CanDamage = true;

        protected virtual void Awake()
        {
            // Кешируем здоровье один раз (раньше GetComponent звался каждый кадр в HandleDeath).
            m_DamageControl = GetComponent<DamageControl>();
        }

        void Start()
        {
            m_CanDamage = true;
            InitPosition = transform.position;

            GameObject obj = Instantiate(m_SpawnParticlePrefab);
            obj.transform.position = InitPosition;
            Destroy(obj, 3);
        }

        void Update()
        {
            // Базовый враг разворачивается к центру арены (продольная ось уровня).
            Vector3 forward = Vector3.zero - transform.position;
            forward.y = 0;
            transform.rotation = Quaternion.Lerp(transform.rotation, Quaternion.LookRotation(forward), 10 * Time.deltaTime);

            // Подёргивание модели от попадания (данные берёт DamageControl).
            Vector3 axis = Quaternion.Euler(0, 30 * m_DamageControl.DamageShakeAngle, 0) * Vector3.right;
            ShakeBase.transform.localRotation = Quaternion.AngleAxis(-30 * m_DamageControl.DamageShakeAmount, axis);

            HandleDeath();
            CheckAlert();
        }

        public virtual void HandleDeath()
        {
            // Гибель по нулю прочности: эффект, дроп лута, удаление.
            if (m_DamageControl.Damage <= 0)
            {
                GameObject obj = Instantiate(m_DeathParticlePrefab);
                obj.transform.position = transform.position;
                Destroy(obj, 3);

                DropItem(m_ItemDropCount);
                Destroy(gameObject);
            }

            // Улетел за нижнюю границу экрана — убираем.
            if (transform.position.z < CameraControl.m_Current.m_CameraBottomPosition.z - 5)
                Destroy(gameObject);
        }

        public virtual void HandleFacePlayer()
        {
            if (m_FacePlayer)
            {
                Vector3 dir = PlayerChar.m_Current.transform.position - transform.position;
                dir.y = 0;
                dir.Normalize();
                m_RotationBase.rotation = Quaternion.Lerp(m_RotationBase.rotation, Quaternion.LookRotation(dir), 10 * Time.deltaTime);
            }
        }

        public virtual void DropItem(int count)
        {
            for (int i = 0; i < count; i++)
            {
                GameObject obj1 = Instantiate(m_ItemPrefabs[0]);
                obj1.transform.position = transform.position;
                obj1.GetComponent<Rigidbody>().linearVelocity = new Vector3(Random.Range(-5, 5), Random.Range(10, 20), Random.Range(-5, 5));
                obj1.GetComponent<Rigidbody>().angularVelocity = new Vector3(Random.Range(-20, 20), Random.Range(-20, 20), Random.Range(-20, 20));
            }
        }

        public virtual void CheckAlert()
        {
            // Просыпаемся, когда верхняя граница экрана подходит к врагу.
            if (!m_Alerted && CameraControl.m_Current.m_CameraTopPosition.z > transform.position.z - 5f)
                StartAlert();
        }

        public virtual void StartAlert()
        {
            m_Alerted = true;
        }

        public void AllowDamage()
        {
            m_CanDamage = true;
        }

        public virtual void EnableEnemy()
        {
        }
    }
}
