rednet.open("back")

local w, h = term.getSize()

-- ==== helper: button zeichnen + klick-treffer prüfen ====
local function drawButton(x, y, width, height, text, bg, fg)
    paintutils.drawFilledBox(x, y, x + width - 1, y + height - 1, bg)
    term.setBackgroundColor(bg)
    term.setTextColor(fg or colors.white)
    local tx = x + math.floor((width - #text) / 2)
    term.setCursorPos(math.max(x, tx), y + math.floor(height / 2))
    term.write(text)
    return {x = x, y = y, w = width, h = height}
end

local function hit(mx, my, b)
    return mx >= b.x and mx < b.x + b.w and my >= b.y and my < b.y + b.h
end

local function typeInfo(info)
    if info.type == "redstone" then
        return (info.state and colors.green or colors.red), "R"
    elseif info.type == "energy" then
        return colors.yellow, "E"
    elseif info.type == "inventory" then
        return colors.purple, "I"
    end
    return colors.gray, "?"
end

-- ==== geräte scannen ====
local function discoverDevices()
    rednet.broadcast("discover", "device_discovery")
    local devices = {}
    local timer = os.startTimer(1)
    while true do
        local event, p1, p2, p3 = os.pullEvent()
        if event == "rednet_message" and p3 == "device_discovery" and type(p2) == "table" then
            devices[p1] = p2
        elseif event == "timer" and p1 == timer then
            break
        end
    end
    local list = {}
    for id, info in pairs(devices) do
        table.insert(list, {id = id, info = info})
    end
    table.sort(list, function(a, b) return a.info.name < b.info.name end)
    return list
end

-- ==== hauptmenü mit pagination ====
local function mainMenu()
    local devices = discoverDevices()
    local page = 1
    local buttonHeight = 3
    local perPage = math.floor((h - 5) / buttonHeight)
    local maxPage = math.max(1, math.ceil(#devices / perPage))

    while true do
        term.setBackgroundColor(colors.black)
        term.clear()
        term.setCursorPos(1, 1)
        term.setTextColor(colors.white)
        term.write("Geraete (" .. page .. "/" .. maxPage .. ")")

        local buttons = {}
        local startIdx = (page - 1) * perPage + 1
        local y = 3
        for i = startIdx, math.min(startIdx + perPage - 1, #devices) do
            local d = devices[i]
            local color, tag = typeInfo(d.info)
            local b = drawButton(1, y, w, buttonHeight - 1, "[" .. tag .. "] " .. d.info.name, color, colors.black)
            b.device = d
            table.insert(buttons, b)
            y = y + buttonHeight
        end

        local prevBtn = drawButton(1, h - 1, math.floor(w/3), 1, "< zurueck", colors.gray, colors.white)
        local rescanBtn = drawButton(math.floor(w/3)+1, h - 1, math.floor(w/3), 1, "neu scan", colors.gray, colors.white)
        local nextBtn = drawButton(math.floor(w/3)*2+1, h - 1, w - math.floor(w/3)*2, 1, "weiter >", colors.gray, colors.white)

        local _, _, mx, my = os.pullEvent("mouse_click")

        if hit(mx, my, prevBtn) and page > 1 then
            page = page - 1
        elseif hit(mx, my, nextBtn) and page < maxPage then
            page = page + 1
        elseif hit(mx, my, rescanBtn) then
            devices = discoverDevices()
            maxPage = math.max(1, math.ceil(#devices / perPage))
            page = 1
        else
            for _, b in ipairs(buttons) do
                if hit(mx, my, b) then
                    openDevice(b.device)
                end
            end
        end
    end
end

-- ==== redstone unterseite ====
function redstonePage(d)
    while true do
        term.setBackgroundColor(colors.black)
        term.clear()
        term.setCursorPos(1, 1)
        term.setTextColor(colors.white)
        term.write(d.info.name)

        local onColor = d.info.state and colors.green or colors.gray
        local offColor = (not d.info.state) and colors.red or colors.gray

        local onBtn = drawButton(1, 4, w, 4, "AN", onColor, colors.black)
        local offBtn = drawButton(1, 9, w, 4, "AUS", offColor, colors.white)
        local backBtn = drawButton(1, h, w, 1, "< zurueck", colors.gray, colors.white)

        local _, _, mx, my = os.pullEvent("mouse_click")

        if hit(mx, my, backBtn) then
            return
        elseif hit(mx, my, onBtn) then
            rednet.send(d.id, {cmd = "on"}, "device_command")
            local _, resp = rednet.receive("device_command", 2)
            if resp then d.info.state = resp.state end
        elseif hit(mx, my, offBtn) then
            rednet.send(d.id, {cmd = "off"}, "device_command")
            local _, resp = rednet.receive("device_command", 2)
            if resp then d.info.state = resp.state end
        end
    end
end

-- ==== energie unterseite mit balken, auto-refresh ====
function energyPage(d)
    while true do
        rednet.send(d.id, {cmd = "get"}, "device_command")
        local _, response = rednet.receive("device_command", 2)

        term.setBackgroundColor(colors.black)
        term.clear()
        term.setCursorPos(1, 1)
        term.setTextColor(colors.white)
        term.write(d.info.name)

        if response then
            local percent = math.floor((response.stored / response.max) * 100)
            term.setCursorPos(1, 3)
            term.write(response.stored .. " / " .. response.max .. " FE")

            local barW = w - 2
            local filled = math.floor(barW * percent / 100)
            paintutils.drawFilledBox(2, 5, w - 1, 6, colors.gray)
            if filled > 0 then
                paintutils.drawFilledBox(2, 5, 1 + filled, 6, colors.green)
            end
            term.setCursorPos(1, 8)
            term.write(percent .. "%")
        else
            term.setCursorPos(1, 3)
            term.write("keine antwort...")
        end

        local backBtn = drawButton(1, h, w, 1, "< zurueck", colors.gray, colors.white)

        local timer = os.startTimer(3)
        while true do
            local event, p1, p2, p3 = os.pullEvent()
            if event == "timer" and p1 == timer then break
            elseif event == "mouse_click" and hit(p2, p3, backBtn) then return end
        end
    end
end

-- ==== inventar unterseite mit pagination ====
function inventoryPage(d)
    rednet.send(d.id, {cmd = "get"}, "device_command")
    local _, response = rednet.receive("device_command", 2)
    local items = response and response.items or {}

    local perPage = h - 4
    local page = 1
    local maxPage = math.max(1, math.ceil(#items / perPage))

    while true do
        term.setBackgroundColor(colors.black)
        term.clear()
        term.setCursorPos(1, 1)
        term.setTextColor(colors.white)
        term.write(d.info.name .. " (" .. page .. "/" .. maxPage .. ")")

        local startIdx = (page - 1) * perPage + 1
        local y = 3
        for i = startIdx, math.min(startIdx + perPage - 1, #items) do
            term.setCursorPos(1, y)
            term.write(items[i].name .. " x" .. items[i].count)
            y = y + 1
        end

        local prevBtn = drawButton(1, h, math.floor(w/3), 1, "< prev", colors.gray, colors.white)
        local backBtn = drawButton(math.floor(w/3)+1, h, math.floor(w/3), 1, "zurueck", colors.gray, colors.white)
        local nextBtn = drawButton(math.floor(w/3)*2+1, h, w - math.floor(w/3)*2, 1, "next >", colors.gray, colors.white)

        local _, _, mx, my = os.pullEvent("mouse_click")
        if hit(mx, my, backBtn) then return
        elseif hit(mx, my, prevBtn) and page > 1 then page = page - 1
        elseif hit(mx, my, nextBtn) and page < maxPage then page = page + 1
        end
    end
end

-- ==== router ====
function openDevice(d)
    if d.info.type == "redstone" then redstonePage(d)
    elseif d.info.type == "energy" then energyPage(d)
    elseif d.info.type == "inventory" then inventoryPage(d)
    end
end

mainMenu()