local M = {}
M.type = "auxiliary"

local max = math.max

local lightSteps = nil
local flashingLEDsOn = nil
local flashingLEDsOff = nil
local minSpeed = 0
local maxSpeed = 0
local inputElectricsName = nil
local flashDuration = 0
local flashTimer = 0
local flashSwitch = false
local keepLowerLEDsOn = true
local stallWarningEngine = nil
local hasStallWarning = true

local function updateGFX(dt)
  local speed = electrics.values[inputElectricsName] * 3.6 -- Convert m/s to km/h
  for _, v in ipairs(lightSteps) do
    electrics.values[v.electricsName] = 0
  end
  local isOverMaxSpeed = speed >= maxSpeed

  for _, v in ipairs(lightSteps) do
    if speed >= v.startSpeed and (speed < v.endSpeed or keepLowerLEDsOn) and not isOverMaxSpeed then
      electrics.values[v.electricsName] = 1
    end
  end

  electrics.values.shouldShift = isOverMaxSpeed

  flashTimer = max(flashTimer - dt, 0)
  if isOverMaxSpeed or (hasStallWarning and stallWarningEngine.isStalled) then
    if flashTimer <= 0 then
      flashSwitch = not flashSwitch
      flashTimer = flashDuration
    end

    local flashValue = flashSwitch and 1 or 0
    for _, v in ipairs(flashingLEDsOn) do
      electrics.values[v] = flashValue
    end
    for _, v in ipairs(flashingLEDsOff) do
      electrics.values[v] = 1 - flashValue
    end
  else
    flashSwitch = false
  end
end

local function init(jbeamData)
  flashTimer = 0
  flashSwitch = false
  lightSteps = {}

  maxSpeed = jbeamData.maxSpeed or 250
  local speedRange = jbeamData.speedRange or 250
  hasStallWarning = false

  maxSpeed = jbeamData.maxSpeed or maxSpeed
  minSpeed = maxSpeed - speedRange
  minSpeed = jbeamData.minSpeed or minSpeed

  inputElectricsName = jbeamData.inputElectricsName or "wheelspeed"
  keepLowerLEDsOn = jbeamData.keepLEDsActive == nil and true or jbeamData.keepLEDsActive
  flashDuration = jbeamData.flashDuration or 0.1

  local steps = jbeamData.outputElectrics or {}
  local stepCount = #steps
  local speedStepRange = maxSpeed - minSpeed
  local speedStep = speedStepRange / stepCount
  for i = 1, stepCount do
    local step = steps[i]
    local stepData = {startSpeed = minSpeed + speedStep * (i - 1), endSpeed = minSpeed + speedStep * i, electricsName = step}
    table.insert(lightSteps, stepData)
  end
  flashingLEDsOn = {}
  flashingLEDsOff = {}
  for _, v in pairs(jbeamData.flashingOutputElectrics or {}) do
    table.insert(flashingLEDsOn, v)
  end
  for _, v in pairs(jbeamData.flashingAlternateOutputElectrics or {}) do
    table.insert(flashingLEDsOff, v)
  end
end

M.init = init
M.updateGFX = updateGFX

return M
