using System;
using System.Reflection;
using HarmonyLib;
using RimWorld;
using Verse;
using UnityEngine;

namespace RDFGenes
{
    // v1.0.4p performance-safe Dollmare alignment.
    // Head seating is handled by RDFGenesHarmonyInit's single shared BaseHeadOffsetAt postfix.
    // This class retains one compile-safe reflective OffsetFor patch for the Horse Tail only.
    [StaticConstructorOnStartup]
    public static class RDFDollmareAlignmentV104p
    {
        static RDFDollmareAlignmentV104p()
        {
            try
            {
                Harmony harmony = new Harmony("rdf.genes.dollmare.alignment.v104p");

                MethodInfo tailTarget = null;
                MethodInfo[] workerMethods = typeof(PawnRenderNodeWorker).GetMethods(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
                for (int i = 0; i < workerMethods.Length; i++)
                {
                    MethodInfo mi = workerMethods[i];
                    if (mi != null && mi.Name == "OffsetFor" && mi.ReturnType == typeof(Vector3))
                    {
                        tailTarget = mi;
                        break;
                    }
                }

                MethodInfo tailPostfix = AccessTools.Method(typeof(RDFDollmareAlignmentV104p), "DollmareTailAnchorPostfix");
                if (tailTarget != null && tailPostfix != null)
                {
                    HarmonyMethod hm = new HarmonyMethod(tailPostfix);
                    hm.priority = Priority.Last;
                    harmony.Patch(tailTarget, postfix: hm);
                    Log.Message("[RDF Genes] Installed consolidated Dollmare Horse Tail anchor patch (v1.0.4p).");
                }
                else
                {
                    Log.Warning("[RDF Genes] Could not find PawnRenderNodeWorker.OffsetFor; Dollmare tail will use its GeneDef placement.");
                }
            }
            catch (Exception ex)
            {
                Log.Warning("[RDF Genes] Dollmare v1.0.4p tail alignment patch failed: " + ex);
            }
        }

        public static void DollmareTailAnchorPostfix(object __instance, object[] __args, ref Vector3 __result)
        {
            if (!(__instance is RDFHorseTailWorker)) return;

            PawnRenderNode node = null;
            Rot4 facing = Rot4.South;
            bool haveFacing = false;

            if (__args != null)
            {
                for (int i = 0; i < __args.Length; i++)
                {
                    object arg = __args[i];
                    if (arg is PawnRenderNode)
                    {
                        node = (PawnRenderNode)arg;
                    }
                    else if (arg != null && arg.GetType() == typeof(PawnDrawParms))
                    {
                        PawnDrawParms parms = (PawnDrawParms)arg;
                        facing = parms.facing;
                        haveFacing = true;
                    }
                    else if (arg != null && arg.GetType() == typeof(Rot4))
                    {
                        facing = (Rot4)arg;
                        haveFacing = true;
                    }
                }
            }

            Pawn pawn = node != null && node.tree != null ? node.tree.pawn : RDFGeneUtility.ExtractPawnFast(__instance);
            if (!RDFGeneUtility.HasDollmareBody(pawn)) return;
            if (!haveFacing && pawn != null) facing = pawn.Rotation;

            // Net result of the previously confirmed v0.9b1 + v0.9j two-pass corrections.
            // Consolidating them into one global postfix preserves the final placement while
            // halving the OffsetFor hook overhead.
            if (facing == Rot4.North)
            {
                __result.x += 0.05f;
                __result.z += 0.05f;
            }
            else if (facing == Rot4.East)
            {
                __result.x -= 0.09f;
                __result.z += 0.10f;
            }
            else if (facing == Rot4.West)
            {
                __result.x += 0.09f;
                __result.z += 0.10f;
            }
            // South's previous -0.05 + 0.05 corrections cancel exactly: no adjustment.
        }
    }
}
