using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection.Emit;
using BepInEx;
using BepInEx.Configuration;
using HarmonyLib;
using HarmonyLib.Tools;

namespace DavesPhatStore {
	[BepInPlugin(pluginGuid, pluginName, pluginVersion)]
	public class Main : BaseUnityPlugin {
		private const string pluginGuid = "DavesPhatStore";
		private const string pluginName = "DavesPhatStore";
		private const string pluginVersion = "1.0.0";

		public static ConfigEntry<int> playersAdded;
		public static ConfigEntry<int> employeePerPerk;
		public static ConfigEntry<float> employeeSpeedPerk;
		public static ConfigEntry<float> employeeExtraMoneyPerk;
		public static ConfigEntry<float> productCheckoutWait;
		public static ConfigEntry<float> productItemPlaceWait;
		public static ConfigEntry<float> employeeItemPlaceWait;
		public static ConfigEntry<float> experienceMultiplier;
		public static ConfigEntry<float> setPriceMultiplier;
		
		public void Awake() {
			playersAdded = Config.Bind("General", "PlayersAdded", 0);
			employeePerPerk = Config.Bind("General", "EmployeePerPerk", 1);
			employeeSpeedPerk = Config.Bind("General", "EmployeeSpeedPerk", 0.2f);
			employeeExtraMoneyPerk = Config.Bind("General", "EmployeeExtraMoneyPerk", 0.1f);
			productCheckoutWait = Config.Bind("General", "ProductCheckoutWait", 0.75f);
			productItemPlaceWait = Config.Bind("General", "ProductItemPlaceWait", 0.5f);
			employeeItemPlaceWait = Config.Bind("General", "EmployeeItemPlaceWait", 0.2f);	
			experienceMultiplier = Config.Bind("General", "ExperienceMultiplier", 0.2f);
			setPriceMultiplier = Config.Bind("General", "SetPriceMultiplier", 2f);

			WaitTimes wt = gameObject.AddComponent<WaitTimes>();
			wt.init();

			Logger.LogInfo("Cyka mod loaded");
			HarmonyFileLog.Enabled = true;
			Harmony harmony = new Harmony(pluginGuid);
			harmony.PatchAll();
			var originalMethods = harmony.GetPatchedMethods();
			Logger.LogInfo("Patched " + originalMethods.Count() + " methods");
			foreach (var method in originalMethods) {
				Logger.LogInfo("Patched " + method.Name);
			}
		}
	}

	[HarmonyPatch(typeof(GameData), "UserCode_CmdAlterFunds__Single")]
	public static class ExperiencePatch {
		static IEnumerable<CodeInstruction> Transpiler(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.Mul && codes[i].opcode == OpCodes.Sub) {
					Console.WriteLine("Found Mul and Sub:");
					Console.WriteLine(previous);
					Console.WriteLine(codes[i]);
					
					codes.Insert(i + 1,
						new CodeInstruction(OpCodes.Ldsfld, AccessTools.Field(typeof(Main), "experienceMultiplier")));
					codes.Insert(i + 2,
						new CodeInstruction(OpCodes.Call,
							AccessTools.PropertyGetter(typeof(Main).GetField("experienceMultiplier").FieldType, "Value")));
					codes.Insert(i + 3, new CodeInstruction(OpCodes.Add));
				}

				previous = codes[i];
			}

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

			return codes.AsEnumerable();
		}
	}

	[HarmonyPatch(typeof(GameData), "UserCode_CmdOpenSupermarket")]
	public static class Debug {
		static void Postfix(GameData __instance) {
			Console.WriteLine("Called UserCode_CmdOpenSupermarket");
			Console.WriteLine($"timeFactor: {__instance.timeFactor}");
			Console.WriteLine($"maxProductsCustomersToBuy: {__instance.maxProductsCustomersToBuy}");
			Console.WriteLine($"maxCustomersNPCs: {__instance.maxCustomersNPCs}");
		}
	}
}