---@class Scaleform
local Scaleform = {}

-- Constants
local SCALEFORM_TIMEOUT = 5000
local BACKGROUND_COLOR_VALUE = 80
local CONTROL_TYPE = 2
local RENDER_WAIT_TIME = 2

-- Local utility functions
local function setupButton(scaleform, button)
    PushScaleformMovieFunction(scaleform, button.type)

    if button.int then
        PushScaleformMovieFunctionParameterInt(button.int)
    end

    -- Handle key index setup
    if button.keyIndex then
        if type(button.keyIndex) == "table" then
            for _, keyCode in pairs(button.keyIndex) do
                N_0xe83a3e3557a56640(GetControlInstructionalButton(CONTROL_TYPE, keyCode, true))
            end
        else
            ScaleformMovieMethodAddParamPlayerNameString(GetControlInstructionalButton(CONTROL_TYPE, button.keyIndex[1],
                true))
        end
    end

    -- Handle button name setup
    if button.name then
        BeginTextCommandScaleformString("STRING")
        AddTextComponentScaleform(button.name)
        EndTextCommandScaleformString()
    end

    -- Handle background color
    if button.type == 'SET_BACKGROUND_COLOUR' then
        for _ = 1, 4 do
            PushScaleformMovieFunctionParameterInt(BACKGROUND_COLOR_VALUE)
        end
    end

    PopScaleformMovieFunctionVoid()
end

---Creates and sets up a scaleform movie
---@param scaleformName string The name of the scaleform to load
---@param buttons table Array of button configurations
---@return number scaleform The loaded scaleform handle
local function setupScaleform(scaleformName, buttons)
    local scaleform = RequestScaleformMovie(scaleformName)
    local timeout = SCALEFORM_TIMEOUT

    -- Wait for scaleform to load
    while not HasScaleformMovieLoaded(scaleform) and timeout > 0 do
        timeout = timeout - 1
        Wait(0)
    end

    if timeout <= 0 then
        error('Scaleform failed to load: ' .. scaleformName)
    end

    DrawScaleformMovieFullscreen(scaleform, 255, 255, 255, 0, 0)

    -- Setup each button
    for _, button in ipairs(buttons) do
        setupButton(scaleform, button)
    end

    return scaleform
end

---Sets up instructional buttons with default configuration
---@param buttons table Optional custom button configuration
---@return number scaleform The configured instructional buttons scaleform
function Scaleform.SetupInstructionalButtons(buttons)
    buttons = buttons or {
        -- Default button configuration commented out
        -- Uncomment and modify as needed
        -- {type = "CLEAR_ALL"},
        -- {type = "SET_CLEAR_SPACE", int = 200},
        -- {type = "SET_DATA_SLOT", name = config?.place_object?.name or 'Place Object:', keyIndex = config?.place_object?.key or {223}, int = 5},
        -- {type = "SET_DATA_SLOT", name = config?.cancel_placement?.name or 'Cancel Placement:', keyIndex = config?.cancel_placement?.key or {222}, int = 4},
        -- {type = "SET_DATA_SLOT", name = config?.snap_to_ground?.name or 'Snap to Ground:', keyIndex = config?.snap_to_ground?.key or {19}, int = 1},
        -- {type = "SET_DATA_SLOT", name = config?.rotate?.name or 'Rotate:', keyIndex = config?.rotate?.key or {14, 15}, int = 2},
        -- {type = "SET_DATA_SLOT", name = config?.distance?.name or 'Distance:', keyIndex = config?.distance?.key or {14,15,36}, int = 3},
        -- {type = "SET_DATA_SLOT", name = config?.toggle_placement?.name or 'Toggle Placement:', keyIndex = config?.toggle_placement?.key or {199}, int = 0},
        -- {type = "DRAW_INSTRUCTIONAL_BUTTONS"},
        -- {type = "SET_BACKGROUND_COLOUR"},
    }

    return setupScaleform("instructional_buttons", buttons)
end

-- Active scaleform tracking
local activeScaleform = nil

---Runs a scaleform with optional update callback
---@param scaleform number The scaleform handle to run
---@param onUpdate function Optional callback for updates during runtime
function Scaleform.Run(scaleform, onUpdate)
    if activeScaleform then return end
    activeScaleform = scaleform

    CreateThread(function()
        while activeScaleform do
            DrawScaleformMovieFullscreen(scaleform, 255, 255, 255, 255, 0)

            if onUpdate then
                local shouldStop = onUpdate()
                if shouldStop then
                    Scaleform.Stop()
                    break
                end
            end

            Wait(RENDER_WAIT_TIME)
        end
    end)
end

---Stops the currently running scaleform
function Scaleform.Stop()
    activeScaleform = nil
end

exports("Scaleform", Scaleform)
return Scaleform
