using Microsoft.Xna.Framework;
using MonoGame.FourEngine;
using MonoGame.FourEngine.Raycast;
using System;
using System.Collections.Generic;
using System.Linq;

namespace Raycast.Win32.Entities
{
    public partial class Player
    {
        public IRaycastObject AimedAt { get; private set; }

        public Vector2 AutoAimDirection
        {
            get
            {
                var direction = AimedAt.Position - Position;
                direction.Normalize();
                return direction;
            }
        }

        private readonly HashSet<Enemy> _autoAimPretendents = new HashSet<Enemy>();
        
        private int _autoAimLeft;
        private int _autoAimRight;

        public void InitAutoAim(int width)
        {
            _autoAimLeft = (width / 2) - (int)(width * Configuration.AutoAimAmount);
            _autoAimRight = (width / 2) + (int)(width * Configuration.AutoAimAmount);
        }

        public void ResetAutoAim()
        {
            _autoAimPretendents.Clear();
        }

        public void OnPossibleAutoAimPretendent(Enemy enemy, Rectangle destinationRect, RaycastWallLayer layer)
        {
            if (!_autoAimPretendents.Contains(enemy) && enemy.State != Enemy.EnemyState.Death)
            {
                if (!(destinationRect.Left < _autoAimLeft && destinationRect.Right < _autoAimLeft) &&
                    !(destinationRect.Left > _autoAimRight && destinationRect.Right > _autoAimRight))
                {
                    var isVisible = false;

                    var left = Math.Max(destinationRect.Left, _autoAimLeft);
                    var right = Math.Min(destinationRect.Right, _autoAimRight);

                    for (var x = left; x < right; x++)
                    {
                        if (layer.DestinationRect[x].Height < destinationRect.Height)
                        {
                            isVisible = true;
                            break;
                        }
                    }

                    if (isVisible) _autoAimPretendents.Add(enemy);
                }
            }
        }

        private void AutoAim(UpdateEventArgs args)
        {
            if (_scene == null) return;

            var pretendents = _autoAimPretendents;

            AimedAt = pretendents
                .OrderBy(x => Math.Abs((Position - x.Position).LengthSquared()))
                .FirstOrDefault();
        }
    }
}