local isDown = love.keyboard.isDown

---@type ButtonState
local buttonState = {}

buttonInputSystem = filteredSystem("buttonInput", { canReceiveButtons = T.marker }, function(e, _, system)
    e.buttonState = buttonState
    system.world:addEntity(e)
end)

Mouse = filteredSystem("Mouse", { mouseButtonPress = { position = T.XyPair, button = T.number } })

function MouseJustPressed(button, clear)
    for _, event in pairs(Mouse.entities) do
        if event.mouseButtonPress and event.mouseButtonPress.button == button then
            if clear then
                event.mouseButtonPress = nil
                World:removeEntity(event)
            end
            return true
        end
    end
    return false
end

HeldByCursor = filteredSystem("HeldByCursor", { pickedUpOnClick = T.marker, moveWithCursor = T.marker })

LiveForNFrames = filteredSystem("liveForNFrames", { liveForNFrames = T.number }, function(e, _, system)
    e.liveForNFrames = e.liveForNFrames - 1
    if e.liveForNFrames <= 0 then
        system.world:removeEntity(e)
    end
end)

function buttonInputSystem:preProcess()
    if #self.entities == 0 then
        return
    end
end

function love.keypressed(key, _, _)
    buttonState[key] = true
end

function ClearButtonState()
    for key in pairs(buttonState) do
        buttonState[key] = nil
    end
end

---@type System
local cursorTracking

local mouseX, mouseY = -9999, -9999
local mouseInControl = false

function love.mousemoved(x, y)
    mouseInControl = true
    mouseX, mouseY = x, y
end

function love.mousepressed(x, y, button)
    World:addEntity({
        mouseButtonPress = {
            position = {
                x = x,
                y = y,
            },
            button = button,
        },
        liveForNFrames = 1,
    })
end

local keyDebounceSec = 0.1
local delay = 0

local menuSystem = filteredSystem(
    "menu",
    { canReceiveButtons = T.marker, highlighted = T.marker },
    function(e, dt, system)
        if delay > 0 then
            delay = delay - dt
            return
        end

        local function tryShiftMenu(target, keys)
            if target == nil then
                return false
            end
            for _, key in ipairs(keys) do
                if isDown(key) then
                    e.highlighted = nil
                    e.canReceiveButtons = nil
                    target.canReceiveButtons = T.marker
                    target.highlighted = T.marker
                    system.world:addEntity(e)
                    system.world:addEntity(target)
                    e = target
                    return true
                end
            end
            return false
        end

        local pressed = tryShiftMenu(e.toRight, { "right", "d" })
        pressed = tryShiftMenu(e.toLeft, { "left", "a" }) or pressed
        pressed = tryShiftMenu(e.below, { "down", "s" }) or pressed
        pressed = tryShiftMenu(e.above, { "up", "w" }) or pressed

        if isDown("return") then
            pressed = true
            system.world:addEntity({
                roundState = "active",
            })
        end

        if pressed then
            mouseInControl = false
            mouseX, mouseY = -9999, -9999
            for _, tracker in pairs(cursorTracking.entities) do
                tracker.position.x = -9999
                tracker.position.y = -9999
            end
            delay = keyDebounceSec
        end
    end
)

cursorTracking = filteredSystem("cursorTracking", { moveWithCursor = T.marker, position = T.XyPair }, function(e)
    if mouseInControl then
        local offsetX, offsetY = 0, 0
        if e.size then
            offsetX = e.size.x / 2
            offsetY = e.size.y / 2
        end
        e.position.x = mouseX - offsetX
        e.position.y = mouseY - offsetY
    end
end)

-- local allHighlighted = filteredSystem("allHighlighted", { highlighted = T.marker })

function cursorTracking:postProcess()
    -- if mouseInControl and #Collisions.entities == 0 then
    --     -- If the cursor is not colliding with anything, wipe all highlighted components
    --     for _, highlighted in pairs(allHighlighted.entities) do
    --         highlighted.highlighted = nil
    --         self.world:addEntity(highlighted)
    --     end
    -- end
end