using System.Reflection;
using ABI_RC.Core.Player;
using ABI_RC.Core.Util;
using HarmonyLib;
using MelonLoader;
using UnityEngine;

namespace NAK.DropPropTweak;

public class DropPropTweakMod : MelonMod
{
    public override void OnInitializeMelon()
    {
        HarmonyInstance.Patch( // make drop prop actually usable
            typeof(PlayerSetup).GetMethod(nameof(PlayerSetup.DropProp),
                BindingFlags.Public | BindingFlags.Instance),
            prefix: new HarmonyMethod(typeof(DropPropTweakMod).GetMethod(nameof(OnDropProp),
                BindingFlags.NonPublic | BindingFlags.Static))
        );
    }
    
    private static bool OnDropProp(string propGuid, ref PlayerSetup __instance)
    {
        Vector3 position = __instance.activeCam.transform.position + __instance.GetPlayerForward() * 1.5f; // 1f -> 1.5f

        if (Physics.Raycast(position,
                __instance.CharacterController.GetGravityDirection(), // align with gravity, not player up
                out RaycastHit raycastHit, 4f, __instance.dropPlacementMask))
        {
            // native method passes false, so DropProp doesn't align with gravity :)
            CVRSyncHelper.SpawnProp(propGuid, raycastHit.point.x, raycastHit.point.y, raycastHit.point.z, true);
            return false;
        }

        // unlike original, we will still spawn prop even if raycast fails, giving the method actual utility :3

        // hack- we want to align with *our* rotation, not affecting gravity
        Vector3 ogGravity = __instance.CharacterController.GetGravityDirection();
        __instance.CharacterController.gravity = -__instance.transform.up; // align with our rotation

        // spawn prop with useTargetLocationGravity false, so it pulls our gravity dir we've modified
        CVRSyncHelper.SpawnProp(propGuid, position.x, position.y, position.z, false);

        __instance.CharacterController.gravity = ogGravity; // restore gravity
        return false;
    }


}