local UEHelpers = require("UEHelpers")

local MOD_NAME = "DebugUIToggle"
local TOGGLE_KEY = Key.F2
local TOGGLE_KEY_NAME = "F2"
local TOGGLE_MODIFIERS = {}
local CHEAT_INPUT_CLASS_PATH = "/Game/Blueprints/UI/Cheat/WBP_CheatInput.WBP_CheatInput_C"
local MODAL_LAYER = 3
local CurrentCheatInput = nil

local function Log(Message)
    print(string.format("[%s] %s\n", MOD_NAME, Message))
end

local function IsValid(Object)
    return Object and Object:IsValid()
end

local function GetPlayerController()
    local PlayerController = UEHelpers.GetPlayerController()
    if IsValid(PlayerController) then
        return PlayerController
    end

    PlayerController = FindFirstOf("SN2PlayerController")
    if IsValid(PlayerController) then
        return PlayerController
    end

    return nil
end

local function GetWindowManager(PlayerController)
    local SN2Statics = StaticFindObject("/Script/Subnautica2.Default__SN2Statics")
    if not IsValid(SN2Statics) then
        Log("Could not find SN2Statics")
        return nil
    end

    local WindowManager = SN2Statics:GetWindowManager(PlayerController)
    if not IsValid(WindowManager) then
        Log("Could not find window manager")
        return nil
    end

    return WindowManager
end

local function OpenCheatInputMenu(PlayerController)
    local CheatInputClass = StaticFindObject(CHEAT_INPUT_CLASS_PATH)
    if not IsValid(CheatInputClass) then
        Log("Could not find WBP_CheatInput class")
        return false
    end

    local WindowManager = GetWindowManager(PlayerController)
    if not WindowManager then
        return false
    end

    if WindowManager.Show then
        WindowManager:Show()
    end

    local Widget = WindowManager:PushToLayer(MODAL_LAYER, CheatInputClass)
    if not IsValid(Widget) then
        Log("Window manager did not return a valid cheat input widget")
        return false
    end

    Log("Opened WBP_CheatInput cheat menu")
    CurrentCheatInput = Widget
end

local function CloseCheatInputMenu(WindowManager)
    if IsValid(CurrentCheatInput) then
        WindowManager:Pop(CurrentCheatInput)
        Log("Closed WBP_CheatInput cheat menu")
        CurrentCheatInput = nil
        return true
    end

    local ActiveWidget = WindowManager:GetActiveWidget(MODAL_LAYER)
    if IsValid(ActiveWidget) and ActiveWidget:IsA(CHEAT_INPUT_CLASS_PATH) then
        WindowManager:Pop(ActiveWidget)
        Log("Closed WBP_CheatInput cheat menu")
        CurrentCheatInput = nil
        return true
    end

    return false
end

local function ToggleCheatInput()
    local PlayerController = GetPlayerController()
    if not PlayerController then
        Log("No local player controller found")
        return
    end

    local WindowManager = GetWindowManager(PlayerController)
    if not WindowManager then
        return
    end

    if CloseCheatInputMenu(WindowManager) then
        return
    end

    OpenCheatInputMenu(PlayerController)
end

local KeyBindRegistered = false

if #TOGGLE_MODIFIERS > 0 then
    if not IsKeyBindRegistered(TOGGLE_KEY, TOGGLE_MODIFIERS) then
        RegisterKeyBind(TOGGLE_KEY, TOGGLE_MODIFIERS, function()
            ExecuteInGameThread(ToggleCheatInput)
        end)
        KeyBindRegistered = true
    end
elseif not IsKeyBindRegistered(TOGGLE_KEY) then
    RegisterKeyBind(TOGGLE_KEY, function()
        ExecuteInGameThread(ToggleCheatInput)
    end)
    KeyBindRegistered = true
end

if KeyBindRegistered then
    Log(string.format("Loaded. Press %s to toggle cheat input", TOGGLE_KEY_NAME))
else
    Log(string.format("Loaded, but %s is already registered", TOGGLE_KEY_NAME))
end
