-- Simple wiper controller
local M = {}

-- State variables
local timer = 0
local wiperMode = 0
local speed = 0
local lastPosition = 0.5
local pauseTimer = 0
local soundTimer = 0
local soundInterval = 0.9  -- Adjust this to match your sound length
local isPaused = false
local centerWaitTime = 0
local wiperSoundLow, wiperSoundMed, wiperSoundHigh
local returningToCenter = false
local returnSpeed = 1.5
local initialized = false
local cyclePhase = 0
local highSpeedActive = false

local function playSound()
    -- Create sound sources if they don't exist
    wiperSoundLow = wiperSoundLow or obj:createSFXSource2("art/sound/wiper_low.mp3", "AudioClosest3D", "wiperSoundLow", 0, 0)
    wiperSoundMed = wiperSoundMed or obj:createSFXSource2("art/sound/wiper_med.mp3", "AudioClosest3D", "wiperSoundMed", 0, 0)
    wiperSoundHigh = wiperSoundHigh or obj:createSFXSource2("art/sound/wiper_high.mp3", "AudioClosest3D", "wiperSoundHigh", 0, 0)
    
    local volume = M.isCamInside() and 1 or 0.5
    
    -- Stop all sounds first
    if wiperSoundLow then obj:cutSFX(wiperSoundLow) end
    if wiperSoundMed then obj:cutSFX(wiperSoundMed) end
    if wiperSoundHigh then obj:cutSFX(wiperSoundHigh) end
    
    -- Play appropriate sound based on speed
    if wiperMode == 1 then
        obj:setVolumePitch(wiperSoundLow, volume, 1)
        obj:playSFX(wiperSoundLow)
    elseif wiperMode == 2 then
        obj:setVolumePitch(wiperSoundMed, volume, 1)
        obj:playSFX(wiperSoundMed)
    elseif wiperMode == 3 then
        obj:setVolumePitch(wiperSoundHigh, volume, 1)
        obj:playSFX(wiperSoundHigh)
    end
end

local function stopAllSounds()
    if wiperSoundLow then obj:cutSFX(wiperSoundLow) end
    if wiperSoundMed then obj:cutSFX(wiperSoundMed) end
    if wiperSoundHigh then obj:cutSFX(wiperSoundHigh) end
    highSpeedActive = false
    soundTimer = 0
end

local function isCamInside()
    local camPos = obj:getCameraPosition()
    local combinedPos = obj:getPosition() + obj:getNodePosition(beamstate.nodeNameMap['driver'] or 0)

    if camPos and combinedPos then
        return camPos:distance(combinedPos) <= 0.6
    end
    return false
end

local function updateGFX(dt)

-- Update wiper stalk position based on mode
    if wiperMode == 0 then
        electrics.values.wiper_stalk = 0  -- Down position
    elseif wiperMode == 1 then
        electrics.values.wiper_stalk = 0.33  -- First click up
    elseif wiperMode == 2 then
        electrics.values.wiper_stalk = 0.66  -- Second click up
    elseif wiperMode == 3 then
        electrics.values.wiper_stalk = 1  -- Full up position
    end

    -- Handle high speed continuous sound
    if wiperMode == 3 and highSpeedActive then
        soundTimer = soundTimer + dt
        if soundTimer >= soundInterval then
            soundTimer = 0
            playSound()
        end
    end

    if not initialized and electrics then
        electrics.values.wiper_position = 0.5
        initialized = true
    end

    if electrics.values.wiperToggle == 1 then 
        wiperMode = (wiperMode + 1) % 4
        electrics.values.wiperToggle = 0
        
        if wiperMode == 0 then
            gui.message("Wipers: Off", 2)
            speed = 0
            centerWaitTime = 0
            returningToCenter = true
            stopAllSounds()
        elseif wiperMode == 1 then
            stopAllSounds()
            returningToCenter = false
            gui.message("Wipers: Low", 2)
            speed = 0.7
            centerWaitTime = 2
            if cyclePhase == 0 then
                playSound()
                cyclePhase = 1
            end
        elseif wiperMode == 2 then
            stopAllSounds()
            returningToCenter = false
            gui.message("Wipers: Medium", 2)
            speed = 1.4
            centerWaitTime = 0.5
            if cyclePhase == 0 then
                playSound()
                cyclePhase = 1
            end
        elseif wiperMode == 3 then
            stopAllSounds()
            returningToCenter = false
            gui.message("Wipers: High", 2)
            speed = 2.1
            centerWaitTime = 0
            highSpeedActive = true
            if cyclePhase == 0 then
                playSound()
                cyclePhase = 1
            end
        end
    end

    if speed > 0 then
        local moveSpeed = speed * dt
        
        -- Phase 1: Center to Left
        if cyclePhase == 1 then
            lastPosition = electrics.values.wiper_position
            electrics.values.wiper_position = electrics.values.wiper_position - moveSpeed
            if electrics.values.wiper_position <= 0 then
                electrics.values.wiper_position = 0
                cyclePhase = 2
            end
        -- Phase 2: Left to Right
        elseif cyclePhase == 2 then
            lastPosition = electrics.values.wiper_position
            electrics.values.wiper_position = electrics.values.wiper_position + moveSpeed
            if electrics.values.wiper_position >= 1 then
                electrics.values.wiper_position = 1
                cyclePhase = 3
            end
        -- Phase 3: Right to Center
        elseif cyclePhase == 3 then
            lastPosition = electrics.values.wiper_position
            electrics.values.wiper_position = electrics.values.wiper_position - moveSpeed
            if electrics.values.wiper_position <= 0.5 then
                electrics.values.wiper_position = 0.5
                cyclePhase = 0
                if centerWaitTime > 0 then
                    isPaused = true
                    pauseTimer = 0
                else
                    if wiperMode < 3 then  -- Only play cyclic sound for low and medium speeds
                        playSound()
                    end
                    cyclePhase = 1
                end
            end
        end
        
        -- Handle pause at center
        if isPaused then
            pauseTimer = pauseTimer + dt
            if pauseTimer >= centerWaitTime then
                isPaused = false
                if wiperMode < 3 then  -- Only play cyclic sound for low and medium speeds
                    playSound()
                end
                cyclePhase = 1
            end
        end
    else
        -- When wipers are off
        if returningToCenter then
            local currentPos = electrics.values.wiper_position
            local distanceToCenter = 0.5 - currentPos
            if math.abs(distanceToCenter) > 0.01 then
                local moveAmount = dt * returnSpeed
                if math.abs(distanceToCenter) < moveAmount then
                    electrics.values.wiper_position = 0.5
                    returningToCenter = false
                    cyclePhase = 0
                else
                    electrics.values.wiper_position = currentPos + (distanceToCenter > 0 and moveAmount or -moveAmount)
                end
            else
                returningToCenter = false
                cyclePhase = 0
            end
        else
            electrics.values.wiper_position = 0.5
            cyclePhase = 0
        end
    end
end

M.updateGFX = updateGFX
M.isCamInside = isCamInside

return M