using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using EFT;
using EFT.Interactive;
using EFT.UI;
using stupid.solutions.Features;
using stupid.solutions.Features.ESP;
using UnityEngine;

namespace stupid.solutions;

internal class LocationsFixerV2 : MonoBehaviour
{
	private static List<object> cachedLocations = new List<object>();

	public static TarkovApplication _tarkovApplication;

	private static TestHook hookGetBoolForProfile;

	private bool hookedpveonline;

	private bool exfilfixtoggle;

	public static List<TransitPoint> transitPoints = new List<TransitPoint>();

	private bool foundtransitpoints;

	private string infoText;

	public static dynamic clientapp;

	public static bool fixlocations = false;

	private static TestHook TransitDataHook;

	private static bool isTransitDataHooked = false;

	private static object transitHandlerInstance;

	private static readonly HashSet<string> loggedDictionaries = new HashSet<string>();

	private bool monitortransit;

	private static List<string> onlinelocationids = new List<string>();

	public bool updatep = true;

	private void Start()
	{
	}

	private void Update()
	{
		if (updatep)
		{
			_ = monitortransit;
			Input.GetKeyDown(KeyCode.Home);
			FixTransitsAndLocations();
			_ = hookedpveonline;
			if (Main.GameWorld != null && transitPoints.Count <= 0 && Main.GameWorld.LocationId != "Labyrinth")
			{
				GetTransitPoints();
			}
			if (Main.GameWorld == null && transitPoints.Count > 0)
			{
				transitPoints.Clear();
			}
		}
	}

	public void SetRaidSettings()
	{
		foreach (_E6CC.Location value in UnityEngine.Object.FindObjectOfType<TarkovApplication>().GetClientBackEndSession().LocationSettings.locations.Values)
		{
			value.ForceOnlineRaidInPVE = false;
			value.EscapeTimeLimit = 9999;
			ConsoleScreen.Log("Updated Settings For Location " + value.Id);
		}
	}

	private void FixTransitsAndLocations()
	{
		if (!TarkovApplication.Exist(out var tarkovApplication) || tarkovApplication == null)
		{
			return;
		}
		_tarkovApplication = tarkovApplication;
		_EA29 clientBackEndSession = tarkovApplication.GetClientBackEndSession();
		if (clientBackEndSession?.LocationSettings == null)
		{
			return;
		}
		foreach (_E6CC.Location value in clientBackEndSession.LocationSettings.locations.Values)
		{
			if (value.ForceOnlineRaidInPVE)
			{
				value.ForceOnlineRaidInPVE = false;
				ConsoleScreen.Log("[Fix] Patched Location " + value.Name + " → ForceOnlineRaidInPVE = false");
				if (!onlinelocationids.Contains(value.Id))
				{
					onlinelocationids.Add(value.Id);
					ConsoleScreen.Log(value.Name + " Added to ID list (ID : " + value.Id + ")");
				}
			}
		}
		_ = _tarkovApplication.CurrentRaidSettings;
	}

	public void GetTransitPoints()
	{
		transitPoints.Clear();
		infoText = "";
		TransitPoint[] array = UnityEngine.Object.FindObjectsOfType<TransitPoint>();
		if (array != null && array.Length != 0)
		{
			TransitPoint[] array2 = array;
			foreach (TransitPoint transitPoint in array2)
			{
				transitPoints.Add(transitPoint);
				string text = "Transit Point Information:\nID: " + transitPoint.parameters.id.ToString().Trim() + "\nTransit Point Name: " + transitPoint.name.Transliterate() + "\n---------------------------";
				ConsoleScreen.Log(text);
				infoText = infoText + text + "\n";
			}
		}
	}

	private void LogTransitPoints()
	{
		if (transitPoints == null || transitPoints.Count <= 0)
		{
			return;
		}
		Debug.Log($"TransitPoints Count: {transitPoints.Count}");
		foreach (TransitPoint transitPoint in transitPoints)
		{
			if (transitPoint == null)
			{
				Debug.LogWarning("Null TransitPoint found in list.");
				continue;
			}
			Debug.Log("TransitPoint Instance: " + transitPoint.name);
			if (transitPoint.Controller != null && transitPoint.Controller.alreadyTransits != null && transitPoint.Controller.alreadyTransits.Count > 0)
			{
				Debug.Log($"alreadyTransits Count: {transitPoint.Controller.alreadyTransits.Count}");
				foreach (KeyValuePair<string, _E98D> alreadyTransit in transitPoint.Controller.alreadyTransits)
				{
					Debug.Log($"alreadyTransits Key: {alreadyTransit.Key}, Value: {alreadyTransit.Value}");
				}
			}
			else
			{
				Debug.Log("alreadyTransits is empty or null.");
			}
		}
		if (_tarkovApplication != null)
		{
			_E869 transitionStatus = _tarkovApplication.transitionStatus;
			if (transitionStatus.InTransition)
			{
				Debug.Log("--- TarkovApplication.transitionStatus (InTransition == true) ---");
				Debug.Log($"InTransition: {transitionStatus.InTransition}");
				Debug.Log("Location: " + transitionStatus.Location);
				Debug.Log($"Training: {transitionStatus.Training}");
				Debug.Log($"Side: {transitionStatus.Side}");
				Debug.Log($"Mode: {transitionStatus.Mode}");
				Debug.Log($"Time: {transitionStatus.Time}");
				Debug.Log("-----------------------------------------");
			}
			else
			{
				Debug.Log("transitionStatus.InTransition is false. Skipping detailed log.");
			}
		}
		else
		{
			Debug.LogWarning("_tarkovApplication is null!");
		}
	}

	public static void StartTransitByID(int transitId)
	{
		if (Main.LocalPlayer == null)
		{
			ConsoleScreen.Log("[ERROR] Local player is null.");
			return;
		}
		if (transitPoints == null || transitPoints.Count == 0)
		{
			ConsoleScreen.Log("[ERROR] No cached transit points. Did you call GetTransitPoints()?");
			return;
		}
		TransitPoint transitPoint = transitPoints.FirstOrDefault((TransitPoint tp) => tp.parameters.id == transitId);
		if (transitPoint == null || transitPoint.Controller == null)
		{
			ConsoleScreen.Log($"[ERROR] Invalid Transit Point ID or missing controller: {transitId}");
			return;
		}
		ConsoleScreen.Log($"[TRANSIT] Starting Transit -> ID: {transitPoint.parameters.id} | Name: {transitPoint.name.Transliterate()}");
		int playersCount = 1;
		string hash = GenerateTransitHash(transitPoint);
		Dictionary<string, ProfileKey> profileKeys = GetProfileKeys(Main.LocalPlayer.ProfileId);
		transitPoint.Controller.Transit(transitPoint, playersCount, hash, profileKeys, Main.LocalPlayer);
		transitPoints.Clear();
		Main.GamePlayers.Clear();
		ItemESP._gameLootItems.Clear();
		CorpseEsp.Corpses.Clear();
		Main.LocalPlayer = null;
		Main.LocalPlayerWeapon = null;
		Main.GameWorld = null;
		Main.MainCamera = null;
	}

	private static string GenerateTransitHash(TransitPoint transitPoint)
	{
		return $"{transitPoint.parameters.id}_{DateTime.Now.Ticks}";
	}

	private static Dictionary<string, ProfileKey> GetProfileKeys(string profileId)
	{
		return new Dictionary<string, ProfileKey>();
	}

	public static void TransferItemsFromTempStash(int transitid)
	{
		TransitPoint transitPoint = transitPoints.FirstOrDefault((TransitPoint tp) => tp.parameters.id == transitid);
		if (!(transitPoint == null) && transitPoint.Controller?.TransferItemsController != null)
		{
			ConsoleScreen.Log("Sending Items To Stash for Transit Point " + transitPoint.name);
			transitPoint.Controller.TransferItemsController.MoveItemsFromTempStashToTransferStash(Main.LocalPlayer);
		}
	}

	public static void StopTransitCountdown()
	{
		if (transitPoints == null || transitPoints.Count == 0)
		{
			ConsoleScreen.Log("No Transit Points Available To Stop.");
			return;
		}
		foreach (TransitPoint transitPoint in transitPoints)
		{
			if (transitPoint.Controller != null)
			{
				transitPoint.Controller.transitPlayers.Clear();
				ConsoleScreen.Log("Stopped Transit Countdown For: " + transitPoint.name.Localized());
			}
			else
			{
				ConsoleScreen.Log("Transit Controller Is Null For: " + transitPoint.name.Localized());
			}
		}
	}

	public static bool GetBoolForProfile_Hook(string variable, bool defaultValue)
	{
		foreach (string onlinelocationid in onlinelocationids)
		{
			if (variable.Contains(onlinelocationid))
			{
				ConsoleScreen.Log("[Hook] Blocking online requirement for location ID: " + onlinelocationid + " in variable '" + variable + "'");
				return false;
			}
		}
		return (bool)hookGetBoolForProfile.OriginalMethod.Invoke(null, new object[2] { variable, defaultValue });
	}

	private void HookGetBoolForProfile()
	{
		if (hookedpveonline)
		{
			return;
		}
		try
		{
			ConsoleScreen.Log("[Hook] Attempting to hook GetBoolForProfile...");
			Type type = Aimbot.Find("\ue984");
			if (type == null)
			{
				ConsoleScreen.Log("[Hook Error] Type '\ue984' not found.");
				return;
			}
			ConsoleScreen.Log("[Hook] Found type: " + type.FullName);
			MethodInfo method = type.GetMethod("GetBoolForProfile", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
			MethodInfo method2 = typeof(LocationsFixerV2).GetMethod("GetBoolForProfile_Hook", BindingFlags.Static | BindingFlags.Public);
			if (method == null)
			{
				ConsoleScreen.Log("[Hook Error] Method 'GetBoolForProfile' not found in " + type.FullName + ".");
				return;
			}
			if (method2 == null)
			{
				ConsoleScreen.Log("[Hook Error] Hook method 'GetBoolForProfile_Hook' not found.");
				return;
			}
			hookGetBoolForProfile = new TestHook();
			hookGetBoolForProfile.Init(method, method2);
			hookGetBoolForProfile.Hook();
			hookedpveonline = true;
			ConsoleScreen.Log("[Hook] Successfully hooked GetBoolForProfile.");
		}
		catch (Exception ex)
		{
			ConsoleScreen.Log("[Hook Error] " + ex.Message + "\n" + ex.StackTrace);
		}
	}
}
