using System;
using System.Collections.Generic;
using System.Linq;
using EFT;
using EFT.Counters;
using EFT.Interactive;
using EFT.InventoryLogic;
using EFT.Quests;
using EFT.UI;
using stupid.solutions.Data;
using stupid.solutions.Features;
using stupid.solutions.Features.ESP;
using stupid.solutions.stupid.solutions.Data;
using stupid.solutions.Utils;
using UnityEngine;

namespace stupid.solutions;

public class QuestESP : MonoBehaviour
{
	public struct QuestItemsSearched
	{
		public string ID { get; set; }
	}

	private List<PointOfInterest> poiList = new List<PointOfInterest>();

	private List<dynamic> startedQuests = new List<object>();

	private bool shouldRefreshData = true;

	public static List<string> QuestItemIds = new List<string>();

	private List<PlaceItemTrigger> placeItemTriggers = new List<PlaceItemTrigger>();

	private List<ExperienceTrigger> experienceTrigger = new List<ExperienceTrigger>();

	private bool gettriggers = true;

	private bool getquestitems = true;

	private float _nextQuestCacheTime;

	private static readonly float _cacheQuestInterval = 5f;

	public Color Color { get; set; } = Color.magenta;

	private void Update()
	{
		if (Settings.QuestESP && Time.time >= _nextQuestCacheTime)
		{
			if (Main.GameWorld != null && Main.LocalPlayer != null && Main.MainCamera != null)
			{
				try
				{
					poiList.Clear();
					RefreshData(poiList);
					shouldRefreshData = false;
				}
				catch (Exception ex)
				{
					ConsoleScreen.Log("Error refreshing data: " + ex.Message);
				}
			}
			_nextQuestCacheTime = Time.time + _cacheQuestInterval;
		}
		if (gettriggers && Main.GameWorld != null && Main.LocalPlayer != null && Main.MainCamera != null)
		{
			GetTriggers();
		}
		if (Main.GameWorld == null)
		{
			gettriggers = true;
			getquestitems = true;
			poiList.Clear();
			QuestItemIds.Clear();
			placeItemTriggers.Clear();
			experienceTrigger.Clear();
		}
	}

	public void GetTriggers()
	{
		if (placeItemTriggers == null)
		{
			placeItemTriggers = new List<PlaceItemTrigger>();
		}
		if (experienceTrigger == null)
		{
			experienceTrigger = new List<ExperienceTrigger>();
		}
		gettriggers = false;
		placeItemTriggers.Clear();
		experienceTrigger.Clear();
		placeItemTriggers = UnityEngine.Object.FindObjectsOfType<PlaceItemTrigger>().ToList();
		experienceTrigger = UnityEngine.Object.FindObjectsOfType<ExperienceTrigger>().ToList();
		ConsoleScreen.Log($"Got Triggers + {experienceTrigger.Count + placeItemTriggers.Count}");
	}

	public void RefreshData(List<PointOfInterest> data)
	{
		GameWorld gameWorld = Main.GameWorld;
		if (gameWorld == null)
		{
			return;
		}
		Player localPlayer = Main.LocalPlayer;
		if (localPlayer == null || Main.MainCamera == null)
		{
			return;
		}
		Profile profile = localPlayer.Profile;
		if (profile == null)
		{
			return;
		}
		try
		{
			List<_F286> questsData = profile.QuestsData;
			startedQuests.Clear();
			foreach (_F286 item in questsData)
			{
				if (item.Template != null && item.Template.Conditions != null && profile.Stats != null && profile.Stats.Eft != null && profile.Stats.Eft.OverallCounters != null && item.Status == EQuestStatus.Started)
				{
					startedQuests.Add(item);
				}
			}
			if (startedQuests.Any())
			{
				RefreshVisitPlaceLocations(startedQuests, profile, data);
				RefreshFindItemLocations(startedQuests, gameWorld, data);
				RefreshPlaceOrRepairItemLocations(startedQuests, profile, data);
				if (getquestitems)
				{
					RefreshNonStaticQuestItems(startedQuests, gameWorld, data);
					getquestitems = false;
				}
			}
		}
		catch (Exception)
		{
		}
	}

	private void RefreshVisitPlaceLocations(List<dynamic> startedQuests, Profile profile, List<PointOfInterest> records)
	{
		try
		{
			List<ExperienceTrigger> source = this.experienceTrigger.ToList();
			foreach (dynamic startedQuest in startedQuests)
			{
				dynamic val = startedQuest.Template?.Conditions[EQuestStatus.AvailableForFinish];
				if (val == null)
				{
					continue;
				}
				foreach (dynamic item in val)
				{
					try
					{
						if ((startedQuest.CompletedConditions.Contains(item.id)) || !(item is ConditionCounterCreator conditionCounterCreator))
						{
							continue;
						}
						foreach (Condition condition in conditionCounterCreator.Conditions)
						{
							if (condition is ConditionVisitPlace conditionVisitPlace)
							{
								string expectedTriggerId = conditionVisitPlace.target;
								ExperienceTrigger experienceTrigger = source.FirstOrDefault((ExperienceTrigger t) => t.Id == expectedTriggerId);
								if (!(experienceTrigger == null) && profile.Stats.Eft.OverallCounters.GetInt(CounterTag.TriggerVisited, experienceTrigger.Id) <= 0)
								{
									Vector3 position = experienceTrigger.transform.position;
									AddQuestRecord(records, conditionCounterCreator, startedQuest, position, Color.cyan);
									break;
								}
							}
						}
					}
					catch (Exception ex)
					{
						ConsoleScreen.Log($"Error processing condition {(object)item?.id}: {ex.Message}");
					}
				}
			}
		}
		catch (Exception)
		{
		}
	}

	private bool IsQuestConditionAvailableForFinish(dynamic quest)
	{
		dynamic val = quest.Template?.Conditions[EQuestStatus.AvailableForFinish];
		return val != null && !quest.CompletedConditions.Contains(val.id);
	}

	private void RefreshFindItemLocations(List<dynamic> startedQuests, GameWorld world, List<PointOfInterest> records)
	{
		try
		{
			_E3D7<int, LootItem> lootItems = world.LootItems;
			for (int i = 0; i < lootItems.Count; i++)
			{
				try
				{
					LootItem byIndex = lootItems.GetByIndex(i);
					if (!GameUtils.IsLootItemValid(byIndex))
					{
						continue;
					}
					bool flag = false;
					foreach (dynamic startedQuest in startedQuests)
					{
						dynamic val = startedQuest.Template?.Conditions[EQuestStatus.AvailableForFinish];
						if (val == null)
						{
							continue;
						}
						foreach (object item in val)
						{
							if (!(item is ConditionFindItem conditionFindItem))
							{
								continue;
							}
							string text = conditionFindItem.target.FirstOrDefault()?.ToString();
							bool flag2 = text == null || !text.Contains(byIndex.Item.TemplateId.ToString());
							if (!flag2 && !((flag2 | startedQuest.CompletedConditions.Contains(conditionFindItem.id)) ? true : false))
							{
								if (!byIndex.Item.QuestItem && !flag)
								{
									QuestItemIds.Add(byIndex.Item.LocalizedName());
									flag = true;
								}
								else
								{
									Vector3 position = byIndex.transform.position;
									AddQuestRecord(records, conditionFindItem, startedQuest, position, Color.yellow);
								}
							}
						}
					}
				}
				catch (Exception)
				{
				}
			}
		}
		catch (Exception)
		{
		}
	}

	private void RefreshNonStaticQuestItems(List<dynamic> startedQuests, GameWorld world, List<PointOfInterest> records)
	{
		try
		{
			foreach (GameLootContainer gameLootContainer in LootableContainerESP._gameLootContainers)
			{
				if (!GameUtils.IsLootableContainerValid(gameLootContainer.LootableContainer))
				{
					continue;
				}
				foreach (Item allItem in gameLootContainer.LootableContainer.ItemOwner.RootItem.GetAllItems())
				{
					foreach (dynamic startedQuest in startedQuests)
					{
						dynamic val = startedQuest.Template?.Conditions[EQuestStatus.AvailableForFinish];
						if (val == null)
						{
							continue;
						}
						bool flag = false;
						foreach (object item in val)
						{
							if (item is ConditionFindItem conditionFindItem)
							{
								string text = conditionFindItem.target.FirstOrDefault()?.ToString();
								bool flag2 = text == null || !text.Contains(allItem.TemplateId.ToString());
								if (!flag2 && !((flag2 | startedQuest.CompletedConditions.Contains(conditionFindItem.id)) ? true : false) && !allItem.QuestItem && !flag)
								{
									QuestItemIds.Add(allItem.LocalizedName());
									flag = true;
								}
							}
						}
					}
				}
			}
			if (Main.OnlineGamePlayers.Count > 0)
			{
				foreach (OnlineGamePlayer onlineGamePlayer in Main.OnlineGamePlayers)
				{
					IEnumerator<Item> enumerator6 = onlineGamePlayer.Player.ObservedPlayerController.EquipmentViewController.Equipment.GetAllItems().GetEnumerator();
					while (enumerator6.MoveNext())
					{
						if (enumerator6.Current != null)
						{
							foreach (Item allItem2 in enumerator6.Current.GetAllItems())
							{
								foreach (dynamic startedQuest2 in startedQuests)
								{
									dynamic val2 = startedQuest2.Template?.Conditions[EQuestStatus.AvailableForFinish];
									if (!((val2 == null) ? true : false))
									{
										bool flag3 = false;
										foreach (object item2 in val2)
										{
											if (item2 is ConditionFindItem conditionFindItem2)
											{
												string text2 = conditionFindItem2.target.FirstOrDefault()?.ToString();
												bool flag2 = text2 == null || !text2.Contains(allItem2.TemplateId.ToString());
												if (!flag2 && !((flag2 | startedQuest2.CompletedConditions.Contains(conditionFindItem2.id)) ? true : false) && !allItem2.QuestItem && !flag3)
												{
													QuestItemIds.Add(allItem2.LocalizedName());
													flag3 = true;
												}
											}
										}
									}
								}
							}
						}
					}
				}
				return;
			}
			foreach (GamePlayer gamePlayer in Main.GamePlayers)
			{
				IEnumerator<Item> enumerator8 = gamePlayer.Player.Profile.Inventory.Equipment.GetAllItems().GetEnumerator();
				while (enumerator8.MoveNext())
				{
					if (enumerator8.Current == null)
					{
						continue;
					}
					foreach (Item allItem3 in enumerator8.Current.GetAllItems())
					{
						foreach (dynamic startedQuest3 in startedQuests)
						{
							dynamic val3 = startedQuest3.Template?.Conditions[EQuestStatus.AvailableForFinish];
							if (val3 == null)
							{
								continue;
							}
							bool flag4 = false;
							foreach (object item3 in val3)
							{
								if (item3 is ConditionFindItem conditionFindItem3)
								{
									string text3 = conditionFindItem3.target.FirstOrDefault()?.ToString();
									bool flag2 = text3 == null || !text3.Contains(allItem3.TemplateId.ToString());
									if (!flag2 && !((flag2 | startedQuest3.CompletedConditions.Contains(conditionFindItem3.id)) ? true : false) && !allItem3.QuestItem && !flag4)
									{
										QuestItemIds.Add(allItem3.LocalizedName());
										flag4 = true;
									}
								}
							}
						}
					}
				}
			}
		}
		catch (Exception)
		{
		}
	}

	private void RefreshPlaceOrRepairItemLocations(List<dynamic> startedQuests, Profile profile, List<PointOfInterest> records)
	{
		try
		{
			Item[] source = profile.Inventory.GetPlayerItems()?.ToArray();
			List<PlaceItemTrigger> source2 = placeItemTriggers;
			foreach (dynamic startedQuest in startedQuests)
			{
				try
				{
					dynamic val = startedQuest.Template?.Conditions[EQuestStatus.AvailableForFinish];
					if (val == null)
					{
						continue;
					}
					foreach (object item in val)
					{
						ConditionZone zoneCondition = item as ConditionZone;
						if (zoneCondition == null)
						{
							continue;
						}
						if (startedQuest.CompletedConditions.Contains(zoneCondition.id))
						{
							continue;
						}
						string zoneconditionstring = zoneCondition.target.FirstOrDefault()?.ToString();
						if (zoneconditionstring != null && source.FirstOrDefault((Item x) => zoneconditionstring.Contains(x.TemplateId.ToString())) != null)
						{
							PlaceItemTrigger placeItemTrigger = source2.FirstOrDefault((PlaceItemTrigger t) => t.Id == zoneCondition.zoneId);
							if (!(placeItemTrigger == null))
							{
								Vector3 position = placeItemTrigger.transform.position;
								AddQuestRecord(records, zoneCondition, startedQuest, position, Color);
								break;
							}
						}
					}
				}
				catch (Exception)
				{
				}
			}
		}
		catch (Exception)
		{
		}
	}

	private void AddQuestRecord(List<PointOfInterest> records, dynamic condition, dynamic quest, Vector3 position, Color color)
	{
		PointOfInterest item = new PointOfInterest
		{
			Name = $" {(object)quest.Template.Name} ",
			Description = $" {(object)condition.FormattedDescription} ",
			Position = position,
			Color = color,
			Quest = quest
		};
		records.Add(item);
	}

	public void OnGUI()
	{
		if (!(Main.GameWorld != null) || !Settings.QuestESP)
		{
			return;
		}
		foreach (var item in (from poi in poiList
			group poi by new { poi.Position, poi.Name }).ToDictionary(g => g.Key, g => g.ToList()))
		{
			List<PointOfInterest> value = item.Value;
			Vector3 position = item.Key.Position;
			Vector3 vector = GameUtils.WorldPointToScreenPoint(position);
			float num = Vector3.Distance(Main.MainCamera.transform.position, position);
			bool num2 = vector.z > 0f && vector.x > 0f && vector.x < (float)Screen.width && vector.y > 0f && vector.y < (float)Screen.height;
			bool flag = Aimbot.CaulculateInFov2(position) <= Settings.SimpleStringsFOV;
			if (!num2)
			{
				continue;
			}
			if (Settings.DrawSimpleStrings)
			{
				string label = (flag ? $"{item.Key.Name} [{num:F0}m]" : "[Q]");
				Render.DrawString(new Vector2(vector.x - 50f, vector.y), label, value[0].Color);
				if (!flag || !Settings.DrawDescription)
				{
					continue;
				}
				float num3 = 15f;
				foreach (PointOfInterest item2 in value)
				{
					Render.DrawString(new Vector2(vector.x - 50f, vector.y + num3), item2.Description, Color.white);
					num3 += 15f;
				}
				continue;
			}
			string label2 = $"{item.Key.Name} [{num:F0}m]";
			Render.DrawString(new Vector2(vector.x - 50f, vector.y), label2, value[0].Color);
			if (!Settings.DrawDescription)
			{
				continue;
			}
			float num4 = 15f;
			foreach (PointOfInterest item3 in value)
			{
				Render.DrawString(new Vector2(vector.x - 50f, vector.y + num4), item3.Description, Color.white);
				num4 += 15f;
			}
		}
	}
}
