local M = {}

-- Configuration
local REQUIRED_REVERSALS = 3   -- Must switch direction 3 times (e.g., Left -> Right -> Left)
local RESET_TIMEOUT = 0.3      -- Fast window: shake must be completed rapidly or it resets
local LOCKOUT_DURATION = 3.0   -- Cooldown duration (seconds) before allowed to trigger again

-- Asymmetrical Thresholds
local SPEED_TO_ENABLE = 115.0  -- Slightly lower: easier to turn ON
local SPEED_TO_DISABLE = 140.0 -- Slightly higher: harder to accidentally turn OFF

-- Focusdim Global Hotkey Configuration from your settings
local FOCUS_DIM_MODS = { "ctrl", "alt", "shift", "cmd" }
local FOCUS_DIM_KEY = "f"

-- Internal state tracking
local jiggleWatcher = nil
local isLocked = false
local isFocusDimActive = false -- Tracks state to apply the correct threshold
local lastXDirection = 0       -- -1 for left, 1 for right, 0 for still
local reversalCount = 0
local lastEventTime = 0

-- Forward declaration for the timer loop
M.start = function() end

local function eventCallback(event)
    if isLocked then return false end

    local now = hs.timer.secondsSinceEpoch()
    
    -- Reset the counter if the movements aren't happening fast enough
    if (now - lastEventTime) > RESET_TIMEOUT then
        reversalCount = 0
        lastXDirection = 0
    end
    
    lastEventTime = now

    -- Extract horizontal movement exclusively
    local dx = event:getProperty(hs.eventtap.event.properties.mouseEventDeltaX)
    
    -- Dynamically choose threshold based on current state
    local currentThreshold = isFocusDimActive and SPEED_TO_DISABLE or SPEED_TO_ENABLE
    
    -- Only evaluate if it's a high-velocity horizontal snap matching the current state's rule
    if math.abs(dx) > currentThreshold then
        local currentDirection = (dx > 0) and 1 or -1
        
        -- Track direction flips
        if lastXDirection ~= 0 and currentDirection ~= lastXDirection then
            reversalCount = reversalCount + 1
            
            -- Trigger only when the full rapid shake sequence completes
            if reversalCount >= REQUIRED_REVERSALS then
                isLocked = true
                reversalCount = 0
                lastXDirection = 0
                
                -- Toggle our internal tracking state
                isFocusDimActive = not isFocusDimActive
                
                -- Instantly detach the listener
                M.stop()
                
                -- Simulate the hotkey press to toggle Focusdim
                hs.eventtap.keyStroke(FOCUS_DIM_MODS, FOCUS_DIM_KEY, 0)
                
                -- Re-enable after the lockout duration
                hs.timer.doAfter(LOCKOUT_DURATION, function()
                    isLocked = false
                    M.start()
                end)
                
                return false
            end
        end
        
        lastXDirection = currentDirection
    end

    return false -- Pass event through to macOS normally
end

function M.start()
    if jiggleWatcher then return end

    jiggleWatcher = hs.eventtap.new({ hs.eventtap.event.types.mouseMoved }, eventCallback)
    jiggleWatcher:start()
end

function M.stop()
    if jiggleWatcher then
        jiggleWatcher:stop()
        jiggleWatcher = nil
    end
end

return M