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

namespace DustlandDelivery {
    [HarmonyPatch]
    public class Patches {
        [HarmonyPrefix]
        [HarmonyPatch(typeof(MarketManager), "Pay")]
        static void SellMultiplier(ref int city, ref int goodId, ref int amount, ref float price, ref bool IsBuy,
            ref float BarginRate) {
            if (!IsBuy) {
                price *= Main.SellPriceMultiplier.Value;
            }
        }

        [HarmonyPrefix]
        [HarmonyPatch(typeof(PeopleUpgradeManager), "GetExp")]
        static void XPMultiplier1(ref Personal p, ref int value, ref bool NeedDialog, ref string Text) {
            value = (int)(value * Main.XPMultiplier.Value);
        }

        [HarmonyPrefix]
        [HarmonyPatch(typeof(PeopleUpgradeManager), "GetExpAll")]
        static void XPMultiplier2(ref int value) {
            value = (int)(value * Main.XPMultiplier.Value);
        }

        [HarmonyPostfix]
        [HarmonyPatch(typeof(PeopleUpgradeManager), "GetUpgradeBookUse")]
        static void BookCostMultiplier(ref int __result) {
            __result = (int)(__result * Main.BookCostMultiplier.Value);
        }

        [HarmonyPatch(typeof(PeopleUpgradeManager), "CheckLevelUp")]
        public static class ManyPointPatch {
            static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions) {
                var codes = new List<CodeInstruction>(instructions);

                for (var i = 0; i < 50; i++) {
                    if (codes[i].opcode == OpCodes.Ldfld) {
                        if (codes[i].operand.ToString().Contains("SpecialPoint")) {
                            Console.WriteLine("Found SpecialPoint");
                            codes[i+1].opcode = OpCodes.Ldc_I4_8;
                            break;
                        }
                    }
                }

                return codes.AsEnumerable();
            }
        }

        [HarmonyPatch(typeof(PeopleUpgradeManager), "UseBuffToGetPoint")]
        public static class ManyTraitPatch {
            static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions) {
                var codes = new List<CodeInstruction>(instructions);

                for (var i = 0; i < 100; i++) {
                    if (codes[i].opcode == OpCodes.Ldc_I4_8) {
                        Console.WriteLine("Found Ldc_I4_8");
                        codes[i].opcode = OpCodes.Ldc_I4;
                        codes[i].operand = 32;
                        Console.WriteLine("Changed to Ldc_I4 32");
                        break;
                    }
                }

                return codes.AsEnumerable();
            }
        }

        [HarmonyPatch(typeof(PeopleUpgradeManager), "UsePointToGetBuff")]
        public static class ManyTraitPatch2 {
            static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions) {
                var codes = new List<CodeInstruction>(instructions);

                for (var i = 0; i < 100; i++) {
                    if (codes[i].opcode == OpCodes.Ldc_I4_8) {
                        Console.WriteLine("Found Ldc_I4_8");
                        codes[i].opcode = OpCodes.Ldc_I4;
                        codes[i].operand = 32;
                        Console.WriteLine("Changed to Ldc_I4 32");
                        break;
                    }
                }

                return codes.AsEnumerable();
            }
        }

        [HarmonyPatch(typeof(HardCode), "Get_People_Fatigue_Max")]
        public static class MoreFatigue {
            static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions) {
                var codes = new List<CodeInstruction>(instructions);

                for (var i = 0; i < 10; i++) {
                    if (codes[i].opcode == OpCodes.Ldc_I4_S) {
                        Console.WriteLine("Found Ldc_I4_S");
                        codes[i].opcode = OpCodes.Ldc_I4;
                        codes[i].operand = 300;
                        Console.WriteLine("Changed to Ldc_I4 300");
                        break;
                    }
                }

                return codes.AsEnumerable();
            }
        }
    }
}
