using System;
using System.Collections.Generic;
using System.Linq;
using EFT;
using EFT.InventoryLogic;
using EFT.NextObservedPlayer;
using stupid.solutions;
using stupid.solutions.Utils;
using UnityEngine;

namespace stupid.solutions.stupid.solutions.Data;

public class OnlineGamePlayer
{
	public enum PlayerType
	{
		Scav,
		USEC,
		BEAR,
		Boss,
		Zombie,
		Teammate,
		PlayerScav,
		Cultist,
		Rogue,
		Raider,
		Guard,
		BTR,
		undefined
	}

	public delegate void WildSpawnTypeDelegate(WildSpawnType role);

	private WildSpawnTypeDelegate _originalWildSpawnType;

	private Vector3 screenPosition;

	private Vector3 headScreenPosition;

	public ObservedPlayerView Player { get; }

	public Vector3 ScreenPosition => screenPosition;

	public Vector3 HeadScreenPosition => headScreenPosition;

	public bool IsOnScreen { get; private set; }

	public bool IsVisible { get; private set; }

	public bool teamassigned { get; private set; }

	public float Distance { get; private set; }

	public bool IsAI { get; private set; }

	public bool ItemInit { get; private set; }

	public float DistanceFromCenter { get; set; }

	public string FormattedDistance => $"{(int)Math.Round(Distance)}m";

	public string profileid { get; set; }

	public bool IsTeammate { get; set; }

	public string team { get; set; }

	public PlayerType role { get; set; }

	private int teamcount { get; set; }

	public List<ContainerItem> LootItems { get; private set; }

	public int? totalinventoryprice { get; private set; }

	public bool gotprofileinfo { get; private set; }

	public int timeplayed { get; private set; }

	public double kd { get; private set; }

	public int level { get; private set; }

	public int membertype { get; private set; }

	public string NickName { get; private set; }

	public WildSpawnType? wst { get; set; }

	public bool gotwst { get; set; }

	public OnlineGamePlayer(ObservedPlayerView player)
	{
		if (player == null)
		{
			throw new ArgumentNullException("player");
		}
		Player = player;
		screenPosition = default;
		headScreenPosition = default;
		IsOnScreen = false;
		Distance = 0f;
		LootItems = new List<ContainerItem>();
		ItemInit = false;
		totalinventoryprice = null;
		IsAI = false;
		role = PlayerType.undefined;
		IsTeammate = false;
		gotprofileinfo = false;
		teamassigned = false;
		team = "";
		timeplayed = 0;
		kd = 0.0;
		level = 0;
		membertype = 0;
		NickName = "Unknown Name";
		wst = WildSpawnType.marksman;
		gotwst = false;
	}

	public void RefreshItems()
	{
		LootItems.Clear();
		foreach (Item allItem in Player.ObservedPlayerController.EquipmentViewController.Equipment.GetAllItems())
		{
			if (allItem == null)
			{
				continue;
			}
			ContainerItem lootItem = new ContainerItem(allItem);
			lootItem.RecalculateDynamics();
			lootItem.SetItemCat();
			ContainerItem containerItem = LootItems.FirstOrDefault((i) => i.ItemID == lootItem.ItemID);
			if (containerItem != null)
			{
				if (lootItem.Item.StackObjectsCount <= lootItem.Item.StackMaxSize && 100 >= lootItem.Item.StackObjectsCount)
				{
					containerItem.Count += lootItem.Count + (lootItem.Item.StackObjectsCount - 1);
				}
			}
			else if (lootItem.Item.StackObjectsCount <= lootItem.Item.StackMaxSize && 100 >= lootItem.Item.StackObjectsCount)
			{
				if (lootItem.Item.StackObjectsCount > 1)
				{
					lootItem.Count += lootItem.Item.StackObjectsCount - 1;
				}
				LootItems.Add(lootItem);
			}
		}
		foreach (ContainerItem lootItem2 in LootItems)
		{
			lootItem2.CalculateItemPrice();
		}
		totalinventoryprice = LootItems.Sum((item) => item.itemprice);
		ItemInit = true;
	}

	public void RecalculateDynamics()
	{
		if (!GameUtils.IsOPlayerValid(Player))
		{
			return;
		}
		if (Main.LocalPlayer.TeamId != null && Player.TeamId == Main.LocalPlayer.TeamId)
		{
			IsTeammate = true;
		}
		if (Player.TeamId != null && !IsTeammate && team == "")
		{
			if (!teamassigned)
			{
				teamassigned = true;
				if (!Main.teams.ContainsKey(Player.TeamId))
				{
					int value = !Main.teams.Values.Any() ? 1 : Main.teams.Values.Max() + 1;
					Main.teams[Player.TeamId] = value;
					Main.teamPlayerCount[Player.TeamId] = 1;
				}
				else
				{
					Main.teamPlayerCount[Player.TeamId]++;
				}
			}
			int num = Main.teams[Player.TeamId];
			team = $" Team : {num} ";
		}
		if (!gotprofileinfo && !Player.IsAI)
		{
			GetPlayerInfo();
		}
		screenPosition = GameUtils.WorldPointToScreenPoint(Player.Transform.position);
		if (role == PlayerType.undefined && gotwst)
		{
			role = GetPlayerType(this);
		}
		if (Player.PlayerBones != null)
		{
			headScreenPosition = GameUtils.WorldPointToScreenPoint(Player.PlayerBones.Head.position);
		}
		IsAI = Player.IsAI;
		IsOnScreen = GameUtils.IsScreenPointVisible(screenPosition);
		Distance = Vector3.Distance(Main.MainCamera.transform.position, Player.Transform.position);
	}

	private async void GetPlayerInfo()
	{
		gotprofileinfo = true;
	}

	private PlayerType GetPlayerType(OnlineGamePlayer gamePlayer)
	{
		EPlayerSide side = gamePlayer.Player.ObservedPlayerController.InfoContainer.Side;
		if (gamePlayer.Player.IsAI)
		{
			bool flag = Main.IsBoss(wst);
			if (flag)
			{
				return PlayerType.Boss;
			}
			if (wst == WildSpawnType.pmcBot)
			{
				return PlayerType.Raider;
			}
			if (!flag && wst.ToString().Contains("follower") || wst == WildSpawnType.bossBoarSniper)
			{
				return PlayerType.Guard;
			}
			if (wst == WildSpawnType.sectactPriestEvent || wst == WildSpawnType.sectantPriest || wst == WildSpawnType.sectantWarrior)
			{
				return PlayerType.Cultist;
			}
			if (wst == WildSpawnType.exUsec)
			{
				return PlayerType.Rogue;
			}
			if (gamePlayer.Player.UsedSimplifiedSkeleton)
			{
				return PlayerType.Zombie;
			}
			if (gamePlayer.Player.ObservedPlayerController.HandsController.ItemInHands.ShortName.Localized().Contains("PKTM"))
			{
				return PlayerType.BTR;
			}
			return PlayerType.Scav;
		}
		if (gamePlayer.IsTeammate)
		{
			return PlayerType.Teammate;
		}
		return side switch
		{
			EPlayerSide.Usec => PlayerType.USEC, 
			EPlayerSide.Savage => PlayerType.PlayerScav, 
			_ => PlayerType.BEAR, 
		};
	}
}
