-- =============================================================
-- Real Fuel Consumption — RFCSyncEvent.lua
-- Bidirectional network sync of the mod settings.
-- Pattern based on a proven MarketDynamics-style settings event,
-- including the authorization check so only admins/farm managers
-- can change settings on a dedicated server.
--
-- Directions:
--   sendToClients()  server -> all clients (broadcast)
--   sendToClient()   server -> one client (on join)
--   sendToServer()   client -> server (when a client changes a setting)

RFCSyncEvent = {}
local RFCSyncEvent_mt = Class(RFCSyncEvent, Event)
InitEventClass(RFCSyncEvent, "RFCSyncEvent")

function RFCSyncEvent.emptyNew()
    return Event.new(RFCSyncEvent_mt)
end

function RFCSyncEvent.new()
    return RFCSyncEvent.emptyNew()
end

-- =============================================================
-- SEND HELPERS
-- =============================================================
function RFCSyncEvent.sendToClients()
    if g_server ~= nil then
        g_server:broadcastEvent(RFCSyncEvent.new())
    end
end

function RFCSyncEvent.sendToClient(connection)
    if g_server ~= nil and connection ~= nil then
        connection:sendEvent(RFCSyncEvent.new())
    end
end

function RFCSyncEvent.sendToServer()
    if g_server == nil and g_client ~= nil then
        g_client:getServerConnection():sendEvent(RFCSyncEvent.new())
    end
end

-- =============================================================
-- WRITE — serialize the shared settings
-- =============================================================
function RFCSyncEvent:writeStream(streamId, connection)
    local s = RealFuelConsumption.settings

    streamWriteInt8(streamId, s.baseMultiplierIdx or 3)
    streamWriteInt8(streamId, s.loadSensitivityIdx or 3)
    streamWriteBool(streamId, s.workBonusEnabled)
    streamWriteBool(streamId, s.rpmSensitivity)
    streamWriteBool(streamId, s.engineModesEnabled)
    streamWriteBool(streamId, s.notifications)
    streamWriteBool(streamId, s.showFuelHud)
    streamWriteBool(streamId, s.showModeHud)
end

-- =============================================================
-- READ — deserialize into temp table, then run()
-- =============================================================
function RFCSyncEvent:readStream(streamId, connection)
    self.data = {
        baseMultiplierIdx  = streamReadInt8(streamId),
        loadSensitivityIdx = streamReadInt8(streamId),
        workBonusEnabled   = streamReadBool(streamId),
        rpmSensitivity     = streamReadBool(streamId),
        engineModesEnabled = streamReadBool(streamId),
        notifications      = streamReadBool(streamId),
        showFuelHud        = streamReadBool(streamId),
        showModeHud        = streamReadBool(streamId),
    }
    self:run(connection)
end

-- =============================================================
-- APPLY received data locally
-- =============================================================
local function applyData(data)
    local s = RealFuelConsumption.settings

    s.baseMultiplierIdx  = data.baseMultiplierIdx
    s.loadSensitivityIdx = data.loadSensitivityIdx
    s.workBonusEnabled   = data.workBonusEnabled
    s.rpmSensitivity     = data.rpmSensitivity
    s.engineModesEnabled = data.engineModesEnabled
    s.notifications      = data.notifications
    s.showFuelHud        = data.showFuelHud
    s.showModeHud        = data.showModeHud

    -- Clamp indices to valid range (safety)
    local maxB = #RealFuelConsumption.BASE_MULT_VALUES
    if s.baseMultiplierIdx  < 1 or s.baseMultiplierIdx  > maxB then s.baseMultiplierIdx  = RealFuelConsumption.BASE_MULT_DEFAULT end
    if s.loadSensitivityIdx < 1 or s.loadSensitivityIdx > 4    then s.loadSensitivityIdx = RealFuelConsumption.LOAD_DEFAULT      end
end

-- =============================================================
-- RUN — server validates & rebroadcasts; client just applies
-- =============================================================
function RFCSyncEvent:run(connection)
    if RealFuelConsumption == nil or self.data == nil then return end

    if g_server ~= nil and connection ~= nil then
        -- Received on SERVER from a CLIENT: authorize before applying
        local isAuthorized = AAIntegration ~= nil
            and AAIntegration.isAuthorizedSettingsConnection ~= nil
            and AAIntegration.isAuthorizedSettingsConnection(connection)

        if isAuthorized then
            applyData(self.data)
            RealFuelConsumption.saveSettings()
            g_server:broadcastEvent(self, false, connection)
        else
            RFCSyncEvent.sendToClient(connection)
        end
    else
        -- Received on CLIENT from SERVER: just apply
        applyData(self.data)
    end
end
