--[[
    Ordinary users never need to edit this file. Their settings live in loot_config.lua in the mod's root folder.

    FOR SCANNER RE-RUN SCROLL DOWN A BIT
]]

local VERSION = "1.0"


local function startupMessage(label, message)
    print("[BagLootFramework] " .. label .. ": " .. tostring(message))
end


local function loadModule(name)
    local loaded, moduleOrError = pcall(require, name)

    if not loaded then
        startupMessage("STARTUP ERROR", "Could not load " .. name .. ": "
            .. tostring(moduleOrError))
        return nil
    end

    return moduleOrError
end


local Logger = loadModule("logger")
local Paths = Logger and loadModule("paths")
local ConfigLoader = Paths and loadModule("config_loader")
local ItemDatabase = ConfigLoader and loadModule("item_database")
local ItemResolver = ItemDatabase and loadModule("item_reference_resolver")
local LootBuilder = ItemResolver and loadModule("loot_builder")

if not LootBuilder then
    return
end

-- DEVELOPMENT TOOL -----------------------------------------------------------
-- Remove the two dashes from the next line to rebuild item_catalogue.md once.
-- Put the dashes back afterwards so the scanner stays dormant on normal boots.

--require("scanner").Scan()


local function protected(scope, action)
    local completed, resultOrError = xpcall(action, function(runtimeError)
        if debug and type(debug.traceback) == "function" then
            return debug.traceback(tostring(runtimeError), 2)
        end

        return tostring(runtimeError)
    end)

    if not completed then
        Logger.Error(scope, resultOrError)
        return false
    end

    return true, resultOrError
end


local config = ConfigLoader.Load(Paths.Root("loot_config.lua"))

if not config then
    Logger.Error("STARTUP", "Stopped because loot_config.lua could not be loaded")
    return
end

if next(config) == nil then
    Logger.Info("BagLootFramework v" .. VERSION
        .. " loaded; no valid bag configurations to apply")
    return
end

-- items.json is the runtime bridge from ITEM_IDs to Unreal asset paths.
-- Loading this lookup performs ordinary file work only.
local itemsById = ItemDatabase.Load(Paths.Script("items.json"))

if not itemsById then
    Logger.Error("STARTUP", "Stopped because items.json could not be loaded")
    return
end

if type(ExecuteWithDelay) ~= "function" then
    Logger.Error("STARTUP", "UE4SS ExecuteWithDelay() is unavailable")
    return
end

if type(ExecuteInGameThread) ~= "function" then
    Logger.Error("STARTUP", "UE4SS ExecuteInGameThread() is unavailable")
    return
end

-- Dragonwilds' loot objects are not ready immediately when UE4SS loads Lua.
-- The five-second delay and game-thread execution are the validated live flow.
local scheduled, scheduleError = pcall(ExecuteWithDelay, 5000, function()
    local entered, gameThreadError = pcall(ExecuteInGameThread, function()
        protected("RUNTIME", function()
            local itemReferences = ItemResolver.ResolveConfiguredItems(
                config,
                itemsById
            )
            local summary = LootBuilder.ApplyConfig(config, itemReferences)

            Logger.Info("BagLootFramework v" .. VERSION .. " loaded: changed "
                .. tostring(summary.ChangedBags) .. " of "
                .. tostring(summary.ConfiguredBags) .. " configured bag(s)")
        end)
    end)

    if not entered then
        Logger.Error("RUNTIME", "Could not enter the game thread: "
            .. tostring(gameThreadError))
    end
end)

if not scheduled then
    Logger.Error("STARTUP", "Could not schedule delayed initialization: "
        .. tostring(scheduleError))
end
