using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection.Emit;
using HarmonyLib;

namespace DavesPhatStore {
	[HarmonyPatch]
	public class PlayerFaking {
		[HarmonyTranspiler]
		[HarmonyPatch(typeof(GameData), "UserCode_CmdOpenSupermarket")]
		static IEnumerable<CodeInstruction> TranspilerOpenMarket(IEnumerable<CodeInstruction> instructions) {
			var codes = new List<CodeInstruction>(instructions);

			// foreach (var codeInstruction in codes) {
			// 	Console.WriteLine(codeInstruction);
			// }

			CodeInstruction previous = codes[0];
			for (int i = 1; i < codes.Count; i++) {
				if (previous.opcode == OpCodes.Ldsfld && codes[i].opcode == OpCodes.Callvirt) {
					Console.WriteLine("Found Ldsfld and Callvirt");
					Console.WriteLine(previous);
					Console.WriteLine(codes[i]);
					codes.Insert(i + 1,
						new CodeInstruction(OpCodes.Ldsfld, AccessTools.Field(typeof(Main), "playersAdded")));
					codes.Insert(i + 2,
						new CodeInstruction(OpCodes.Call,
							AccessTools.PropertyGetter(typeof(Main).GetField("playersAdded").FieldType, "Value")));
					codes.Insert(i + 3, new CodeInstruction(OpCodes.Add));
				}

				previous = codes[i];
			}

			// foreach (var codeInstruction in codes) {
			// 	Console.WriteLine(codeInstruction);
			// }

			return codes.AsEnumerable();
		}

		[HarmonyTranspiler]
		[HarmonyPatch(typeof(NPC_Manager), "SpawnCustomerNCP")]
		static IEnumerable<CodeInstruction> TranspilerSpawnNPC(IEnumerable<CodeInstruction> instructions) {
			var codes = new List<CodeInstruction>(instructions);

			// foreach (var codeInstruction in codes) {
			// 	Console.WriteLine(codeInstruction);
			// }

			CodeInstruction previous = codes[0];
			for (int i = 1; i < codes.Count; i++) {
				if (previous.opcode == OpCodes.Ldsfld && codes[i].opcode == OpCodes.Callvirt) {
					Console.WriteLine("Found Ldsfld and Callvirt:");
					Console.WriteLine(previous);
					Console.WriteLine(codes[i]);
					codes.Insert(i + 1,
						new CodeInstruction(OpCodes.Ldsfld, AccessTools.Field(typeof(Main), "playersAdded")));
					codes.Insert(i + 2,
						new CodeInstruction(OpCodes.Call,
							AccessTools.PropertyGetter(typeof(Main).GetField("playersAdded").FieldType, "Value")));
					codes.Insert(i + 3, new CodeInstruction(OpCodes.Add));
				}

				previous = codes[i];
			}

			// foreach (var codeInstruction in codes) {
			// 	Console.WriteLine(codeInstruction);
			// }

			return codes.AsEnumerable();
		}
	}
}