using GameDev.CoreSystems;
using UnityEngine;
using UnityEngine.Serialization;

namespace AsteroidGame.Entities
{
    public class Targeter : MonoBehaviour
    {
        [SerializeField] private SoTargeterConfig _targeterConfig;

        [SerializeField] private float _range;

        [Header("Config Debug")]
        [SerializeField] private SoTargeterConfig.TargetStrategy _targetStrategy;
        [SerializeField] private SoTargetableRuntimeSet _activeTargetable;
        [SerializeField] private Targetable _targeterParent;
        [field: SerializeField] public Targetable TargetEntity { get; set; }

        private void OnEnable()
        {
            SetConfig(_targeterConfig);
        }

        public void SetParent(Targetable newParent) => _targeterParent = newParent;

        public void SetConfig(SoTargeterConfig config)
        {
            _range = config._maxRange;
            _targetStrategy = config._selectedTargetStrategy;
            _activeTargetable = config._activeEntities;
        }

        public Targetable GetTarget()
        {
            return TargetEntity;
        }

        public bool FoundTarget()
        {
            if (_activeTargetable == null || _activeTargetable.Count == 0) return false;

            var currentBestValue = Mathf.Infinity;
            var targetFound = false;

            foreach (var targetEntity in _activeTargetable)
            {
                var distanceToTarget =
                    Vector3.Magnitude(targetEntity.GetCenterPosition() - _targeterParent.GetCenterPosition());

                var withinRange = distanceToTarget < _range;
                if (withinRange)
                {
                    switch (_targetStrategy)
                    {
                        case SoTargeterConfig.TargetStrategy.LowestRange:
                        {
                            var isClosest = distanceToTarget < currentBestValue;
                            if (isClosest)
                            {
                                targetFound = true;
                                currentBestValue = distanceToTarget;
                                TargetEntity = targetEntity;
                            }

                            break;
                        }
                        case SoTargeterConfig.TargetStrategy.LowestHealth:
                        {
                            float enemyHealth = targetEntity.Damageable.GetCurrentHealth();

                            var isLowestHealth = enemyHealth < currentBestValue;
                            if (isLowestHealth)
                            {
                                targetFound = true;
                                currentBestValue = enemyHealth;
                                TargetEntity = targetEntity;
                            }

                            break;
                        }
                    }
                }
            }

            return targetFound;
        }
    }
}