-- Mundo Tibia client background: rotating artworks, no particle FX.
-- Persistent watermark stays visible in login AND in-game.
local background
local watermark
local rotateEvent = nil
local httpBusy = false
local localIndex = 0
local localPool = {}
local ROTATE_MS = 10000
local IMGWEB_NEXT = 'https://mundotibia.com/imgweb/next.php?channel=client'

local function listLocalBackgrounds()
    local pool = {}
    for i = 1, 32 do
        local path = string.format('/images/backgrounds/bg_%02d', i)
        if g_resources.fileExists(path .. '.png') then
            table.insert(pool, path)
        end
    end
    if #pool == 0 then
        table.insert(pool, '/images/background')
    end
    return pool
end

local function loadSeen()
    local node = g_settings.getNode('mt_bg_seen') or {}
    local seen = {}
    if type(node.list) == 'table' then
        for _, v in ipairs(node.list) do
            if type(v) == 'string' and v ~= '' then
                table.insert(seen, v)
            end
        end
    end
    return seen
end

local function saveSeen(seen)
    local list = {}
    for i, v in ipairs(seen or {}) do
        list[i] = v
    end
    g_settings.setNode('mt_bg_seen', { list = list })
end

local function applyImage(path)
    if not background or background:isDestroyed() then
        return
    end
    if not path or path == '' then
        return
    end
    pcall(function()
        background:setImageSource(path)
        background:setImageFixedRatio(false)
    end)
end

local function raiseWatermark()
    if watermark and not watermark:isDestroyed() then
        watermark:show()
        watermark:raise()
    end
end

local function nextLocal()
    if #localPool == 0 then
        localPool = listLocalBackgrounds()
    end
    if #localPool == 0 then
        return
    end
    localIndex = (localIndex % #localPool) + 1
    applyImage(localPool[localIndex])
end

local function applyRemote(url, seen)
    if not url or url == '' then
        nextLocal()
        return
    end
    if not HTTP or not HTTP.downloadImage then
        nextLocal()
        return
    end
    httpBusy = true
    HTTP.downloadImage(url, function(path, err)
        httpBusy = false
        if err or not path then
            nextLocal()
            return
        end
        applyImage(path)
        if type(seen) == 'table' then
            saveSeen(seen)
        end
    end)
end

local function fetchNextRemote()
    if httpBusy then
        return
    end
    if not HTTP or not HTTP.getJSON then
        nextLocal()
        return
    end
    local seen = loadSeen()
    local url = IMGWEB_NEXT
    if #seen > 0 then
        url = url .. '&seen=' .. table.concat(seen, ',')
    end
    httpBusy = true
    HTTP.getJSON(url, function(data, err)
        httpBusy = false
        if err or type(data) ~= 'table' or not data.ok or not data.url then
            nextLocal()
            return
        end
        applyRemote(data.url, data.seen)
    end)
end

local function stopRotate()
    if rotateEvent then
        removeEvent(rotateEvent)
        rotateEvent = nil
    end
end

local function scheduleRotate()
    stopRotate()
    rotateEvent = scheduleEvent(function()
        rotateEvent = nil
        if not background or background:isDestroyed() or not background:isVisible() then
            return
        end
        fetchNextRemote()
        scheduleRotate()
    end, ROTATE_MS)
end

function advanceBackground(forceRemote)
    if forceRemote == false then
        nextLocal()
    else
        fetchNextRemote()
    end
end

local function syncGameBackdrop(path)
    if not modules.game_interface or not modules.game_interface.getRootPanel then
        return
    end
    local root = modules.game_interface.getRootPanel()
    if not root then
        return
    end
    local backdrop = root:getChildById('gameBackdrop')
    if backdrop and path then
        pcall(function()
            backdrop:setImageSource(path)
            backdrop:setImageFixedRatio(false)
        end)
    end
end

-- Hook applyImage to also update in-game backdrop when present.
local _applyImage = applyImage
applyImage = function(path)
    _applyImage(path)
    syncGameBackdrop(path)
end

function init()
    localPool = listLocalBackgrounds()
    background = g_ui.displayUI('background')
    background:lower()

    watermark = g_ui.displayUI('watermark')
    if watermark then
        local version = (APP_DISPLAY_VERSION and tostring(APP_DISPLAY_VERSION)) or '1.0.0'
        version = version:gsub('^v', ''):gsub('^V', '')
        local label = watermark:getChildById('label')
        if label then
            label:setText('MundoTibia V ' .. version .. '  Con amor de Osiann')
        end
        raiseWatermark()
    end

    if #localPool > 0 then
        localIndex = math.random(1, #localPool)
        applyImage(localPool[localIndex])
    else
        applyImage('/images/background')
    end

    addEvent(function()
        fetchNextRemote()
        raiseWatermark()
    end)

    connect(g_game, {
        onGameStart = onGameStart,
        onGameEnd = onGameEnd
    })

    if not g_game.isOnline() then
        scheduleRotate()
    end
end

function terminate()
    disconnect(g_game, {
        onGameStart = onGameStart,
        onGameEnd = onGameEnd
    })
    stopRotate()
    if watermark then
        watermark:destroy()
        watermark = nil
    end
    if background then
        background:destroy()
        background = nil
    end
end

function onGameStart()
    -- Keep login background hidden; in-game uses gameBackdrop.
    if background then
        background:hide()
    end
    stopRotate()
    -- Push current artwork into in-game backdrop and keep watermark.
    if #localPool > 0 then
        syncGameBackdrop(localPool[math.max(localIndex, 1)])
    end
    raiseWatermark()
    -- Change backdrop when entering game too.
    advanceBackground(true)
end

function onGameEnd()
    show()
end

function hide()
    if background then
        background:hide()
    end
    stopRotate()
    raiseWatermark()
end

function show()
    if background then
        background:show()
        background:lower()
    end
    advanceBackground(true)
    scheduleRotate()
    raiseWatermark()
end

function getBackground()
    return background
end

function hideVersionLabel()
end

function setVersionText(text)
    if watermark then
        local label = watermark:getChildById('label')
        if label and text then
            label:setText(tostring(text))
        end
    end
end

function setWatermarkVersion(text)
    setVersionText(text)
end
