#include "Exploits.hpp"
#include "../imgui_helper.hpp"
#include "SetManager.hpp"
#include "../imgui_custom.hpp"
#include "../Menu.hpp"
#include "KeyAuth.h"

#include <Windows.h>
#include <Globals.hpp>

namespace UserInterfaceController {
	Unity::CGameObject* GetMMAvatarPreview();
}

namespace Functions_t {
	namespace Game {
		________________________248_StaticFields* Test();

		void KeyboardShit();

		void SendNoti(std::string text, float time);

		namespace VRChatSDKBasePlayerAPI {
			void TakeOwnership(VRC_SDKBase_VRCPlayerApi_o* Plr, UnityEngine_GameObject_o* Obj);
			void TakeOwnership(VRC_SDKBase_VRCPlayerApi_o* Plr, Unity::CGameObject* Obj);
		}
		namespace VRChatSDKBaseNetworking {
			void SetOwner(VRC_SDKBase_VRCPlayerApi_o* Plr, UnityEngine_GameObject_o* Obj);
			void SetOwner(VRC_SDKBase_VRCPlayerApi_o* Plr, Unity::CGameObject* Obj);
			void RPC(int32_t targetClients, Unity::CGameObject* targetObject, Unity::System_String* methodName, System_Object_array* parameters);
			int32_t GetServerTimeInMilliseconds();
		}

		namespace System {
			System_Byte_array* FromBase64String(Unity::System_String* s);
			void BlockCopy(System_Array_o* src, int32_t srcOffset, System_Array_o* dst, int32_t dstOffset, int32_t count);
			System_Byte_array* get_bytes(int32_t value);
		}

		namespace PhotonLoadBalancingClient {
			void OnEvent(________________________1142_o* client, ExitGames_Client_Photon_EventData_o* data);
		}

		namespace VRChatSDKBaseInputManager {
			void EnableObjectHighlight(Unity::CGameObject* r, bool enable);
		}
	}

	namespace Custom {
		void SendChatboxEvent(std::string text);
	}
}

ExploitsMain::ExploitsMain() : Module(obf("Exploits"), obf("")) {
	ForceClone = &SetManager::i().add(new Set(false, obf("ForceClone"), getName())).getBVal();
	VRCPlusPlus = &SetManager::i().add(new Set(false, obf("VRCPlusPlus"), getName())).getBVal();
	VRCPlusPlusCustom = &SetManager::i().add(new Set(false, obf("VRCPlusPlusCustom"), getName())).getBVal();
	E1Custom = &SetManager::i().add(new Set(false, obf("E1Custom"), getName())).getBVal();
	FPSSpoof = &SetManager::i().add(new Set(false, obf("FPSSpoof"), getName())).getBVal();
	spoofedFPS = &SetManager::i().add(new Set(10.0f, 1.0f, 1000.f, obf("spoofedFPS"), getName())).getVec3f();
	PingSpoof = &SetManager::i().add(new Set(false, obf("PingSpoof"), getName())).getBVal();
	Earrape = &SetManager::i().add(new Set(false, obf("Earrape"), getName())).getBVal();
	spoofedPing = &SetManager::i().add(new Set(10.0f, 1.0f, 9999.f, obf("spoofedPing"), getName())).getVec3f();
	StealLoop = &SetManager::i().add(new Set(false, obf("StealLoop"), getName())).getBVal();
	AntiUdonDrop = &SetManager::i().add(new Set(false, obf("AntiUdonDrop"), getName())).getBVal();
	BringLoop = &SetManager::i().add(new Set(false, obf("BringLoop"), getName())).getBVal();
	TheForce = &SetManager::i().add(new Set(false, obf("TheForce"), getName())).getBVal();
	ItemOrbit = &SetManager::i().add(new Set(false, obf("ItemOrbit"), getName())).getBVal();
	SelfHide = &SetManager::i().add(new Set(false, obf("SelfHide"), getName())).getBVal();
	SpamChatbox = &SetManager::i().add(new Set(false, obf("SpamChatbox"), getName())).getBVal();
	AvatarPrevDisable = &SetManager::i().add(new Set(false, obf("AvatarPrevDisable"), getName())).getBVal();
	EuphoriaE1 = &SetManager::i().add(new Set(false, obf("EuphoriaE1"), getName())).getBVal();
	SpamCamera = &SetManager::i().add(new Set(false, obf("SpamCamera"), getName())).getBVal();
}

void ExploitsMain::renderImGui() {
	if (ImGui::Button(obf("Bring Pickups").c_str()))
	{
		auto LocalFromAPI = APILocalPlayer;
		auto list = Unity::Object::FindObjectsOfType<Unity::CComponent>(obf("VRC.SDK3.Components.VRCPickup").c_str());
		for (int i = 0; i < list->m_uMaxLength; i++)
		{
			if (!list->operator[](i)) {
				continue;
			}

			if (LocalFromAPI != nullptr) {
				auto LPObj = (Unity::CGameObject*)LocalFromAPI->fields.gameObject;
				auto LPPos = LPObj->GetTransform()->GetPosition();
				auto ActualObj = (VRC_SDK3_Components_VRCPickup_o*)list->operator[](i);
				auto GameObj = list->operator[](i)->GetGameObject();

				Functions_t::Game::VRChatSDKBasePlayerAPI::TakeOwnership(LocalFromAPI, GameObj);
				Functions_t::Game::VRChatSDKBaseNetworking::SetOwner(LocalFromAPI, GameObj);
				GameObj->GetTransform()->SetLocalPosition(Unity::Vector3(LPPos.x, LPPos.y + 0.5f, LPPos.z));
				GameObj->GetTransform()->SetPosition(Unity::Vector3(LPPos.x, LPPos.y + 0.5f, LPPos.z));
			}
		}
	}

	if (ImGui::Button(obf("Steal Pickups").c_str()))
	{
		auto list = Unity::Object::FindObjectsOfType<Unity::CComponent>(obf("VRC.SDK3.Components.VRCPickup").c_str());
		for (int i = 0; i < list->m_uMaxLength; i++)
		{
			if (!list->operator[](i)) {
				continue;
			}

			auto ActualObj = (VRC_SDK3_Components_VRCPickup_o*)list->operator[](i);

			ActualObj->fields.DisallowTheft = false; // allow stealing niggas shit
			ActualObj->fields.pickupable = true;
			ActualObj->fields.allowManipulationWhenEquipped = true;
		}
	}

	ImGui::SameLine();
	ImGui::Checkbox_(obf("Loop##loopsteal").c_str(), StealLoop);

	// ImGui::Checkbox_(obf("Force Clone").c_str(), ForceClone);

	ImGui::Checkbox_(obf("Anti Udon Drop Pickups").c_str(), AntiUdonDrop);

	ImGui::Checkbox_(obf("VRCPlusPlus").c_str(), VRCPlusPlus);
	if (ImGui::IsItemHovered())
		ImGui::SetTooltip(obf("Spoofs you as a World Owner/Patreon (This is over Udon, not for other players.)").c_str());
	ImGui::SameLine();
	ImGui::Checkbox_(obf("Custom##vrc").c_str(), VRCPlusPlusCustom);
	if (ImGui::IsItemHovered())
		ImGui::SetTooltip(obf("Type a custom name to spoof").c_str());
	if (*VRCPlusPlusCustom)
	{
		ImGui::SetNextItemWidth(150.0f);
		ImGui::SameLine();
		ImGui::InputText(obf("##namespoofinput").c_str(), CustomSpoofName, 256);
	}


	ImGui::Checkbox_(obf("FPS Spoofer").c_str(), FPSSpoof);
	ImGui::SameLine();
	ImGui::PushItemWidth(Menu::elementSize);
	ImGui::SliderFloat_(obf("##newfps").c_str(), &spoofedFPS->x, spoofedFPS->y, spoofedFPS->z, obf("FPS: %.0f").c_str());
	ImGui::PopItemWidth();

	ImGui::Checkbox_(obf("Ping Spoofer").c_str(), PingSpoof);
	ImGui::SameLine();
	ImGui::PushItemWidth(Menu::elementSize);
	ImGui::SliderFloat_(obf("##newping").c_str(), &spoofedPing->x, spoofedPing->y, spoofedPing->z, obf("Ping: %.0f").c_str());
	ImGui::PopItemWidth();
	ImGui::Text(obf("Warning: Default E1 is safe, Use Others at your own risk.").c_str());
	ImGui::Checkbox_(obf("E1").c_str(), Earrape);
	ImGui::SameLine();
	ImGui::SetNextItemWidth(Menu::elementSize);
	ImGui::Combo(obf("##Selected").c_str(), &SelectedE1, Event1S, IM_ARRAYSIZE(Event1S));
	ImGui::SameLine();
	ImGui::Checkbox_(obf("Custom##E1").c_str(), E1Custom);
	if (ImGui::IsItemHovered())
		ImGui::SetTooltip(obf("Custom E1 Payload in base64 (Malformed payloads will crash your game, don't be dumb.)").c_str());
	if (*E1Custom)
	{
		ImGui::SetNextItemWidth(150.0f);
		ImGui::SameLine();
		ImGui::InputText(obf("##e1custominput").c_str(), CustomE1Data, 256);
	}

	ImGui::Checkbox_(obf("The Force").c_str(), TheForce);

	ImGui::Checkbox(obf("Item Orbit").c_str(), ItemOrbit);

	ImGui::Checkbox(obf("Self Hide").c_str(), SelfHide);

	ImGui::Checkbox(obf("Disable Avatar Preview").c_str(), AvatarPrevDisable);

	ImGui::Checkbox(obf("Chatbox Spam").c_str(), SpamChatbox);

	if (ImGui::Button("Test"))
	{
		Functions_t::Game::Test();
	}

	/*if (ImGui::Button("Test")) {
		cachedPickups = Unity::Object::FindObjectsOfType<Unity::CComponent>(nignog1("VRC.SDK3.Components.VRCPickup"));
		if (cachedPickups != nullptr)
		{
			for (int j = 0; j < cachedPickups->m_uMaxLength; j++)
			{
				if (!cachedPickups->operator[](j))
					continue;

				auto Renderers = cachedPickups->At(j)->GetTransform()->CallMethodSafe<Unity::il2cppArray<UnityEngine_Renderer_o*>*>(nignog1("GetComponentsInChildren"), IL2CPP::Class::GetSystemType(IL2CPP::Class::Find(nignog1("UnityEngine.Renderer"))), true);
				if (Renderers)
				{
					for (int i = 0; i < Renderers->m_uMaxLength; i++)
					{
						if (!Renderers->operator[](i))
							continue;

						Functions_t::Game::VRChatSDKBaseInputManager::EnableObjectHighlight(Renderers->At(i), true);
					}
				}
			}
		}
	}*/

	/*
	if (ImGui::Button("Test")) {
		if (!LocalPlayer)
			return;

		auto FD = LocalPlayer->GetFowardDirection();
		if (FD)
		{
			auto comps = FD->GetComponents(UNITY_COMPONENT_CLASS);
			if (comps)
			{
				for (int i = 0; i < comps->m_uMaxLength; i++)
				{
					auto comp = comps->At(i);
					if (comp)
					{
						printf("[%d] Comp: %s\n", i, comp->CallMethodSafe<Unity::System_String*>("ToString")->ToString().c_str());
					}
				}
			}
		}
	}*/

	/*
	ImGui::Checkbox(obf("Euphoric E1").c_str(), EuphoriaE1);

	if (ImGui::Button(obf("Event Test").c_str()))
	{
		if (EventClient)
		{
			auto EventData = Functions_t::Game::System::FromBase64String(IL2CPP::String::New(obf("AAAAACLp+Lv2GRkA+DrDussssss99wssstssssstttsswwsesQ==")));
			Functions_t::Game::System::BlockCopy((System_Array_o*)Functions_t::Game::System::get_bytes(LocalPlayer->get_photon_id()), 0, (System_Array_o*)EventData, 0, 4);
			Functions_t::Game::System::BlockCopy((System_Array_o*)Functions_t::Game::System::get_bytes(Functions_t::Game::VRChatSDKBaseNetworking::GetServerTimeInMilliseconds()), 0, (System_Array_o*)EventData, 4, 4);

			Unity::il2cppClass* EDC = IL2CPP::Class::Find(obf("ExitGames.Client.Photon.EventData").c_str());
			ExitGames_Client_Photon_EventData_o* ForgedEventData = (ExitGames_Client_Photon_EventData_o*)Unity::Object::New(EDC);
			ForgedEventData->fields.customData = (Il2CppObject*)EventData;
			ForgedEventData->fields.Code = photon_event::uspeak_audio;
			ForgedEventData->fields.sender = 2; // Change This to The Target

			Functions_t::Game::PhotonLoadBalancingClient::OnEvent(EventClient, ForgedEventData);
		}
		else
			printf(obf("EventClient Was Null").c_str());
	}
	*/

	/*;
	ImGui::Checkbox(obf("Spam E6").c_str(), SpamCamera);

	
	if (ImGui::Button(obf("Test Send RPC").c_str())) {
		Functions_t::Game::VRChatSDKBaseNetworking::RPC(RPC_Destination::Others, LocalPlayer->GameObj, IL2CPP::String::New("test"), nullptr);
	}*/
}