using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using EFT;
using EFT.Ballistics;
using EFT.InventoryLogic;
using EFT.UI;
using stupid.solutions.Data;
using stupid.solutions.stupid.solutions.Data;
using stupid.solutions.Utils;
using UnityEngine;

namespace stupid.solutions.Features;

internal class Aimbot : MonoBehaviour
{
	public static bool NotHooked = true;

	private bool isBulletMovementHooked;

	public static TestHook CreateShotHook;

	public static TestHook BulletMovementHook;

	public static GamePlayer Target;

	public static OnlineGamePlayer OTarget;

	public static List<GameUtils.Tracer> TracerList = new List<GameUtils.Tracer>();

	public static List<GameUtils.HitMarker> HitList = new List<GameUtils.HitMarker>();

	public static int zombiebone = 31;

	public void Update()
	{
		switch (Settings.Aimbone)
		{
		case 133:
			zombiebone = 31;
			break;
		case 132:
			zombiebone = 30;
			break;
		case 36:
			zombiebone = 15;
			break;
		case 35:
			zombiebone = 14;
			break;
		}
		if (!(Main.GameWorld != null) || !(Main.ActiveCamera != null))
		{
			return;
		}
		if (Settings.Aimbot)
		{
			Aim();
		}
		if (Settings.SilentAim)
		{
			if (Main.OnlineGamePlayers.Count > 0)
			{
				GetTargetO();
			}
			else
			{
				GetTarget();
			}
		}
		if (Input.GetKeyDown(KeyCode.Mouse2) && Settings.artillery && !Settings.allinputdisabled)
		{
			_ = Vector3.zero;
			Exploits.TestShelling(GameUtils.GetBonePosByID(Target.Player, Settings.Aimbone));
		}
		if (Input.GetKeyDown(KeyCode.Escape) && !Settings.allinputdisabled)
		{
			Main.GameWorld.ServerShellingController.StopShelling();
		}
		if (Settings.MagicBullet && Main.OnlineGamePlayers.Count < 1 && !isBulletMovementHooked)
		{
			MethodInfo method = Find("\uf16a").GetMethod("\ue014", BindingFlags.Instance | BindingFlags.NonPublic);
			BulletMovementHook = new TestHook();
			BulletMovementHook.Init(method, typeof(BulletMovement).GetMethod("MagicBullet_Hook"));
			BulletMovementHook.Hook();
			isBulletMovementHooked = true;
		}
		try
		{
			if (Main.GameWorld != null && Main.LocalPlayer.HandsController.Item is Weapon)
			{
				if (Settings.SilentAim && NotHooked)
				{
					CreateShotHook = new TestHook();
					CreateShotHook.Init(typeof(BallisticsCalculator).GetMethod("CreateShot"), typeof(HookObject).GetMethod("SilentAimHook"));
					CreateShotHook.Hook();
					NotHooked = false;
					ConsoleScreen.Log("Silent Aim Hooked");
				}
				if (Main.OnlineGamePlayers.Count > 0)
				{
					OTarget = GetTargetO();
				}
				else
				{
					Target = GetTarget();
				}
			}
		}
		catch (Exception)
		{
		}
	}

	public static bool VisCheck(GameObject obj, Vector3 Pos, Vector3 Position, out RaycastHit raycastHit)
	{
		if (Physics.Linecast(Pos, Position, out raycastHit, -2142957568) && (bool)raycastHit.collider)
		{
			return raycastHit.collider.gameObject.transform.root.gameObject == obj.transform.root.gameObject;
		}
		return false;
	}

	private GamePlayer GetTarget()
	{
		Dictionary<GamePlayer, int> dictionary = new Dictionary<GamePlayer, int>();
		foreach (GamePlayer gamePlayer in Main.GamePlayers)
		{
			if (gamePlayer != null && !gamePlayer.Player.IsYourPlayer && gamePlayer.Player.HealthController.IsAlive)
			{
				Vector3 zero = Vector3.zero;
				WildSpawnType role = gamePlayer.Player.Profile.Info.Settings.Role;
				zero = ((role == WildSpawnType.infectedAssault || role == WildSpawnType.infectedCivil || role == WildSpawnType.infectedLaborant || role == WildSpawnType.infectedPmc) ? GameUtils.GetBonePosByID(gamePlayer.Player, zombiebone) : GameUtils.GetBonePosByID(gamePlayer.Player, Settings.Aimbone));
				Vector3.Distance(Main.MainCamera.transform.position, gamePlayer.Player.Transform.position);
				Vector3 rhs = gamePlayer.Player.Transform.position - Main.MainCamera.transform.position;
				if (gamePlayer.Distance <= Settings.DrawPlayersDistance && CaulculateInFov(zero) <= Settings.AimbotFOV && Vector3.Dot(Main.MainCamera.transform.TransformDirection(Vector3.forward), rhs) > 0f && (!Settings.CheckVisible || VisCheck(gamePlayer.Player.gameObject, Main.LocalPlayer.Fireport.position, zero, out var _)))
				{
					dictionary.Add(gamePlayer, (int)gamePlayer.DistanceFromCenter);
				}
			}
		}
		if (dictionary.Count > 0)
		{
			dictionary = dictionary.OrderBy(delegate(KeyValuePair<GamePlayer, int> pair)
			{
				KeyValuePair<GamePlayer, int> keyValuePair = pair;
				return keyValuePair.Value;
			}).ToDictionary((KeyValuePair<GamePlayer, int> pair) => pair.Key, (KeyValuePair<GamePlayer, int> pair) => pair.Value);
			return dictionary.Keys.First();
		}
		return null;
	}

	private OnlineGamePlayer GetTargetO()
	{
		Dictionary<OnlineGamePlayer, int> dictionary = new Dictionary<OnlineGamePlayer, int>();
		foreach (OnlineGamePlayer onlineGamePlayer in Main.OnlineGamePlayers)
		{
			if (onlineGamePlayer != null && !onlineGamePlayer.Player.IsYourPlayer && onlineGamePlayer.Player.HealthController.IsAlive && onlineGamePlayer.role != OnlineGamePlayer.PlayerType.Teammate)
			{
				Vector3 zero = Vector3.zero;
				WildSpawnType wildSpawnType = WildSpawnType.pmcUSEC;
				zero = ((wildSpawnType == WildSpawnType.infectedAssault || wildSpawnType == WildSpawnType.infectedCivil || wildSpawnType == WildSpawnType.infectedLaborant || wildSpawnType == WildSpawnType.infectedPmc) ? GameUtils.GetBonePosByIDO(onlineGamePlayer.Player, zombiebone) : GameUtils.GetBonePosByIDO(onlineGamePlayer.Player, Settings.Aimbone));
				Vector3.Distance(Main.MainCamera.transform.position, onlineGamePlayer.Player.Transform.position);
				Vector3 rhs = onlineGamePlayer.Player.Transform.position - Main.MainCamera.transform.position;
				if (onlineGamePlayer.Distance <= Settings.DrawPlayersDistance && CaulculateInFov(zero) <= Settings.AimbotFOV && Vector3.Dot(Main.MainCamera.transform.TransformDirection(Vector3.forward), rhs) > 0f && (!Settings.CheckVisible || VisCheck(onlineGamePlayer.Player.gameObject, Main.LocalPlayer.Fireport.position, zero, out var _)))
				{
					dictionary.Add(onlineGamePlayer, (int)onlineGamePlayer.DistanceFromCenter);
				}
			}
		}
		if (dictionary.Count > 0)
		{
			dictionary = dictionary.OrderBy(delegate(KeyValuePair<OnlineGamePlayer, int> pair)
			{
				KeyValuePair<OnlineGamePlayer, int> keyValuePair = pair;
				return keyValuePair.Value;
			}).ToDictionary((KeyValuePair<OnlineGamePlayer, int> pair) => pair.Key, (KeyValuePair<OnlineGamePlayer, int> pair) => pair.Value);
			return dictionary.Keys.First();
		}
		return null;
	}

	private void Aim()
	{
		if (!Input.GetKey(Settings.AimbotKey))
		{
			return;
		}
		Vector3 vector = Vector3.zero;
		float num = 9999f;
		if (Main.OnlineGamePlayers.Count > 0)
		{
			foreach (OnlineGamePlayer onlineGamePlayer in Main.OnlineGamePlayers)
			{
				if (onlineGamePlayer == null || onlineGamePlayer.Player.IsYourPlayer || !onlineGamePlayer.Player.HealthController.IsAlive || onlineGamePlayer.role == OnlineGamePlayer.PlayerType.Teammate)
				{
					continue;
				}
				Vector3 zero = Vector3.zero;
				zero = ((onlineGamePlayer.role == OnlineGamePlayer.PlayerType.Zombie) ? GameUtils.GetBonePosByIDO(onlineGamePlayer.Player, zombiebone) : GameUtils.GetBonePosByIDO(onlineGamePlayer.Player, Settings.Aimbone));
				float num2 = Vector3.Distance(Main.MainCamera.transform.position, onlineGamePlayer.Player.Transform.position);
				Weapon localPlayerWeapon = Main.LocalPlayerWeapon;
				if (!(zero != Vector3.zero) || !(CaulculateInFov(zero) <= Settings.AimbotFOV) || (Settings.CheckVisible && !VisCheck(onlineGamePlayer.Player.gameObject, Main.LocalPlayer.Fireport.position, zero, out var _)) || !(num > num2))
				{
					continue;
				}
				num = num2;
				if (localPlayerWeapon != null)
				{
					if (Main.LocalPlayerWeapon.CurrentAmmoTemplate != null)
					{
						float num3 = onlineGamePlayer.Distance / Main.LocalPlayerWeapon.CurrentAmmoTemplate.InitialSpeed;
						zero += onlineGamePlayer.Player.Velocity * num3;
						zero -= Main.LocalPlayer.Velocity * Time.deltaTime;
						if (num2 > 100f)
						{
							zero += Vector3.up * BulletDrop(Main.LocalPlayer.Fireport.position, zero, Main.LocalPlayerWeapon.CurrentAmmoTemplate.InitialSpeed);
						}
					}
					vector = zero;
				}
				vector = zero;
			}
		}
		else
		{
			foreach (GamePlayer gamePlayer in Main.GamePlayers)
			{
				if (gamePlayer == null || gamePlayer.Player.IsYourPlayer || !gamePlayer.Player.HealthController.IsAlive)
				{
					continue;
				}
				Vector3 zero2 = Vector3.zero;
				WildSpawnType role = gamePlayer.Player.Profile.Info.Settings.Role;
				zero2 = ((role == WildSpawnType.infectedAssault || role == WildSpawnType.infectedCivil || role == WildSpawnType.infectedLaborant || role == WildSpawnType.infectedPmc) ? GameUtils.GetBonePosByID(gamePlayer.Player, zombiebone) : GameUtils.GetBonePosByID(gamePlayer.Player, Settings.Aimbone));
				float num4 = Vector3.Distance(Main.MainCamera.transform.position, gamePlayer.Player.Transform.position);
				Weapon localPlayerWeapon2 = Main.LocalPlayerWeapon;
				if (!(zero2 != Vector3.zero) || !(CaulculateInFov(zero2) <= Settings.AimbotFOV) || (Settings.CheckVisible && !VisCheck(gamePlayer.Player.gameObject, Main.LocalPlayer.Fireport.position, zero2, out var _)) || !(num > num4))
				{
					continue;
				}
				num = num4;
				if (localPlayerWeapon2 != null)
				{
					if (Main.LocalPlayerWeapon.CurrentAmmoTemplate != null)
					{
						float num5 = gamePlayer.Distance / Main.LocalPlayerWeapon.CurrentAmmoTemplate.InitialSpeed;
						zero2 += gamePlayer.Player.Velocity * num5;
						zero2 -= Main.LocalPlayer.Velocity * Time.deltaTime;
						if (num4 > 100f)
						{
							zero2 += Vector3.up * BulletDrop(Main.LocalPlayer.Fireport.position, zero2, Main.LocalPlayerWeapon.CurrentAmmoTemplate.InitialSpeed);
						}
					}
					vector = zero2;
				}
				vector = zero2;
			}
		}
		if (vector != Vector3.zero)
		{
			AimAtPos(vector);
		}
	}

	public static Vector2 GetAngleToTarget(Vector3 origin, Vector3 target)
	{
		Vector3 normalized = (target - origin).normalized;
		float y = Mathf.Asin(normalized.y) * 57.29578f;
		return new Vector2(Mathf.Atan2(normalized.x, normalized.z) * 57.29578f, y);
	}

	private static Vector2 GetSmoothAngle(Vector2 fromAngle, Vector2 toAngle, float smoothness)
	{
		float x = Mathf.LerpAngle(fromAngle.x, toAngle.x, smoothness * Time.deltaTime);
		float y = Mathf.LerpAngle(fromAngle.y, toAngle.y, smoothness * Time.deltaTime);
		return new Vector2(x, y);
	}

	public void OnGUI()
	{
		if (Settings.SilentTargetLines && (Settings.SilentAim || Settings.MagicBullet) && Main.GameWorld != null && Main.LocalPlayerWeapon != null && Target != null && Main.GamePlayers.Count > 0)
		{
			Vector3 zero = Vector3.zero;
			WildSpawnType role = Target.Player.Profile.Info.Settings.Role;
			zero = ((role == WildSpawnType.infectedAssault || role == WildSpawnType.infectedCivil || role == WildSpawnType.infectedLaborant || role == WildSpawnType.infectedPmc) ? GameUtils.GetBonePosByID(Target.Player, zombiebone) : GameUtils.GetBonePosByID(Target.Player, Settings.Aimbone));
			Vector3 vector = Camera.main.WorldToScreenPoint(zero);
			vector.y = (float)Screen.height - vector.y;
			Render.DrawLine(GameUtils.ScreenCenter, vector, 1f, Settings.TargetSnaplineColor);
		}
	}

	public static float CaulculateInFov(Vector3 position1)
	{
		Vector3 position2 = Main.MainCamera.transform.position;
		Vector3 forward = Main.MainCamera.transform.forward;
		Vector3 normalized = (position1 - position2).normalized;
		return Mathf.Acos(Mathf.Clamp(Vector3.Dot(forward, normalized), -1f, 1f)) * 57.29578f;
	}

	public static float CaulculateInFov2(Vector3 worldPosition)
	{
		Vector3 normalized = (worldPosition - Main.MainCamera.transform.position).normalized;
		return Vector3.Angle(Main.MainCamera.transform.forward, normalized);
	}

	public static void AimAtPos(Vector3 position)
	{
		Vector3 vector = Main.LocalPlayer.Fireport.position - Main.LocalPlayer.Fireport.up * 1f;
		Vector3 eulerAngles = Quaternion.LookRotation((position - vector).normalized).eulerAngles;
		if (eulerAngles.x > 180f)
		{
			eulerAngles.x -= 360f;
		}
		Main.LocalPlayer.MovementContext.Rotation = new Vector2(eulerAngles.y, eulerAngles.x);
	}

	public static float BulletDrop(Vector3 startVector, Vector3 endVector, float BulletSpeed)
	{
		float num = Vector3.Distance(startVector, endVector);
		if (num >= 50f)
		{
			float num2 = num / BulletSpeed;
			return (float)(4.905 * (double)num2 * (double)num2);
		}
		return 0f;
	}

	public static Type Find(string type)
	{
		Type[] types = AppDomain.CurrentDomain.GetAssemblies().FirstOrDefault((Assembly a) => a.GetName().Name == "Assembly-CSharp").GetTypes();
		foreach (Type type2 in types)
		{
			if (type == type2.Name || type == type2.FullName)
			{
				return type2;
			}
		}
		return null;
	}
}
