-- OE ProTune transient exhaust illumination.
--
-- Vehicle Lua owns the flame physics and sends one short pulse at the actual
-- exhaust-tip world position. GE owns scene lights, so one reusable PointLight
-- per vehicle is kept here and faded over only a few frames.

local M = {}
local lights = {}

local function removeLight(id)
  local state = lights[id]
  if not state then return end
  if state.light then pcall(function() state.light:delete() end) end
  lights[id] = nil
end

function M.pulse(vehicleId, x, y, z, r, g, b, brightness, radius, duration)
  vehicleId = tonumber(vehicleId)
  if not vehicleId then return end
  local state = lights[vehicleId]
  local light = state and state.light
  if not light then
    light = createObject("PointLight")
    if not light then return end
    light.canSave = false
    light.castShadows = false
    light:registerObject("oeProTuneExhaustLight_" .. tostring(vehicleId))
    state = { light = light }
    lights[vehicleId] = state
  end

  local ok = pcall(function()
    light:setPosition(vec3(tonumber(x) or 0, tonumber(y) or 0, tonumber(z) or 0))
    light.color = ColorF(
      math.max(0, math.min(1, tonumber(r) or 1)),
      math.max(0, math.min(1, tonumber(g) or 0.4)),
      math.max(0, math.min(1, tonumber(b) or 0.1)),
      1)
    light.radius = math.max(0.5, math.min(5, tonumber(radius) or 2.5))
    state.peak = math.max(0, math.min(1.2, tonumber(brightness) or 0.4))
    state.total = math.max(0.035, math.min(0.12, tonumber(duration) or 0.07))
    state.left = state.total
    light.brightness = state.peak
    light.isEnabled = true
    light:postApply()
  end)
  if not ok then removeLight(vehicleId) end
end

function M.onUpdate(dtReal, dtSim)
  local dt = math.max(0, tonumber(dtSim) or tonumber(dtReal) or 0)
  for id, state in pairs(lights) do
    if (state.left or 0) > 0 then
      state.left = math.max(0, state.left - dt)
      local k = state.total and state.total > 0 and state.left / state.total or 0
      local ok = pcall(function()
        state.light.brightness = (state.peak or 0) * k * k
        state.light.isEnabled = state.left > 0
        state.light:postApply()
      end)
      if not ok then removeLight(id) end
    end
  end
end

function M.onVehicleDestroyed(vehicleId)
  removeLight(tonumber(vehicleId))
end

function M.onExtensionUnloaded()
  for id in pairs(lights) do removeLight(id) end
end

return M
