-- =========================================================
-- Speed Camera BR — Main (carregamento, painel admin, MP sync)
-- =========================================================

SpeedCameraMain = {}
SpeedCameraMain.MOD_DIR = g_currentModDirectory

-- ─── Carrega a classe PmInvoice da Prefeitura no NOSSO ambiente ──
-- Mods têm ambientes Lua separados, então a classe PmInvoice da Prefeitura
-- não é visível pra nós. Solução: localizar a pasta do mod Prefeitura via
-- g_modManager e dar source() no arquivo PmInvoice.lua — assim a classe
-- passa a existir no nosso escopo.
function SpeedCameraMain.loadPmInvoiceClass()
    -- Já carregada?
    if PmInvoice ~= nil then
        print("[SpeedCameraBR] PmInvoice já disponível.")
        return true
    end
    if g_modManager == nil then return false end

    -- Nomes possíveis do mod Prefeitura
    local candidates = {
        "FS25_PrefeituraMunicipal",
        "FS25_Prefeitura_Municipal",
        "PrefeituraMunicipal",
    }

    -- Também varre todos os mods procurando o arquivo (robusto a nome)
    local function tryLoadFrom(modDir)
        if modDir == nil then return false end
        local path = modDir .. "prefeituraInvoices/scripts/PmInvoice.lua"
        if fileExists(path) then
            local ok = pcall(function() source(path) end)
            if ok and PmInvoice ~= nil then
                print("[SpeedCameraBR] PmInvoice carregada de: " .. path)
                return true
            end
        end
        return false
    end

    -- 1) Tenta pelos nomes conhecidos
    for _, name in ipairs(candidates) do
        local mod = g_modManager:getModByName(name)
        if mod ~= nil and mod.modDir ~= nil then
            if tryLoadFrom(mod.modDir) then return true end
        end
    end

    -- 2) Varre todos os mods ativos procurando o arquivo
    if g_modManager.getActiveMods ~= nil then
        local ok, mods = pcall(function() return g_modManager:getActiveMods() end)
        if ok and mods ~= nil then
            for _, mod in pairs(mods) do
                if mod ~= nil and mod.modDir ~= nil then
                    if tryLoadFrom(mod.modDir) then return true end
                end
            end
        end
    end

    print("[SpeedCameraBR] AVISO: não encontrei PmInvoice.lua da Prefeitura.")
    return false
end

-- ─── Carregamento da config no início da partida ─────────
function SpeedCameraMain.loadConfigOnStart()
    if g_currentMission == nil then return end
    -- Carrega a classe PmInvoice (pra integração com a Prefeitura)
    SpeedCameraMain.loadPmInvoiceClass()
    -- Só o servidor carrega do arquivo; clientes recebem via sync.
    if g_currentMission:getIsServer() then
        SpeedCameraConfig.load()
        if SpeedCameraCounter ~= nil then
            SpeedCameraCounter.load()
        end
        if SpeedCameraOwner ~= nil then
            SpeedCameraOwner.load()
        end
    end
end

-- ─── Painel de admin: define a fazenda destino ───────────
-- Usa OptionDialog NATIVO (estável). Só admin abre.
function SpeedCameraMain.openAdminPanel()
    local isAdmin = SpeedCameraConfig.isLocalPlayerAdmin()
    print(string.format("[SpeedCameraBR] openAdminPanel: isAdmin=%s OptionDialog=%s",
        tostring(isAdmin), tostring(OptionDialog ~= nil)))

    if not isAdmin then
        if g_currentMission and g_currentMission.hud and g_currentMission.hud.addSideNotification then
            g_currentMission.hud:addSideNotification(
                {1.0, 0.4, 0.4, 1.0},
                g_i18n:getText("sc_admin_only"))
        end
        return
    end

    if OptionDialog == nil then
        print("[SpeedCameraBR] ERRO: OptionDialog não disponível")
        return
    end

    -- Monta a lista de fazendas disponíveis (+ opção "Nenhuma")
    local options = {}
    local farmIds = {}

    table.insert(options, g_i18n:getText("sc_no_dest_farm"))
    table.insert(farmIds, 0)

    if g_farmManager then
        local farms = g_farmManager:getFarms()
        for _, farm in ipairs(farms or {}) do
            -- Ignora a fazenda "spectator" (id 0/FARM_ID_SPECTATOR)
            if farm.farmId and farm.farmId > 0 then
                local name = (farm.name and farm.name ~= "")
                    and farm.name
                    or string.format("%s %d", g_i18n:getText("sc_farm"), farm.farmId)
                table.insert(options, name)
                table.insert(farmIds, farm.farmId)
            end
        end
    end

    -- Índice atual
    local curIdx = 1
    for i, fid in ipairs(farmIds) do
        if fid == SpeedCameraConfig.destFarmId then curIdx = i break end
    end

    SpeedCameraMain._panelFarmIds = farmIds

    OptionDialog.show(
        SpeedCameraMain.onDestFarmSelected,
        SpeedCameraMain,
        g_i18n:getText("sc_panel_desc"),
        g_i18n:getText("sc_panel_title"),
        options,
        curIdx
    )
end

function SpeedCameraMain.onDestFarmSelected(self, index)
    if index == nil then return end
    local farmIds = SpeedCameraMain._panelFarmIds
    if farmIds == nil then return end
    local chosen = farmIds[index]
    if chosen == nil then return end

    SpeedCameraConfig.destFarmId = chosen
    SpeedCameraConfig.save()

    -- Sincroniza pros clientes
    if SC_ConfigSyncEvent and g_server then
        SC_ConfigSyncEvent.broadcast()
    end

    if g_currentMission and g_currentMission.hud and g_currentMission.hud.addSideNotification then
        local msg = string.format(
            g_i18n:getText("sc_dest_set"),
            SpeedCameraConfig.getDestFarmName())
        g_currentMission.hud:addSideNotification({0.4, 0.8, 1.0, 1.0}, msg)
    end
end

-- ─── Comando de console (alternativa ao Shift+R) ─────────

-- ─── Registro da ação de input (Shift+R) ─────────────────
-- Método canônico do FS25: registra via InputAction, que aparece nas
-- configurações de controle e é MUITO mais confiável que detectar tecla.
function SpeedCameraMain.registerActionEvents()
    if g_inputBinding == nil then return end
    if InputAction == nil or InputAction.SC_ADMIN_PANEL == nil then return end

    -- Registra SEMPRE que o jogo pede (o FS25 limpa e re-registra as actions
    -- ao trocar de contexto; por isso não usamos flag de "já registrado").
    local ok = pcall(function()
        local _, eventId = g_inputBinding:registerActionEvent(
            InputAction.SC_ADMIN_PANEL, SpeedCameraMain,
            SpeedCameraMain.onAdminPanelAction, false, true, false, true)
        if eventId ~= nil then
            g_inputBinding:setActionEventTextVisibility(eventId, false)
            if not SpeedCameraMain._loggedRegister then
                print("[SpeedCameraBR] ✓ Action SC_ADMIN_PANEL ativa (eventId ok)")
                SpeedCameraMain._loggedRegister = true
            end
        end
    end)

    if not ok and not SpeedCameraMain._loggedFail then
        print("[SpeedCameraBR] Falha ao registrar ação SC_ADMIN_PANEL")
        SpeedCameraMain._loggedFail = true
    end
end

function SpeedCameraMain.onAdminPanelAction()
    print("[SpeedCameraBR] Ação Shift+R disparada")
    if g_currentMission ~= nil and g_gui ~= nil and not g_gui:getIsGuiVisible() then
        SpeedCameraMain.openAdminPanel()
    end
end

-- ─── Instalação dos hooks ────────────────────────────────
local function sc_install()
    print("[SpeedCameraBR] sc_install() iniciando...")

    -- Diagnóstico: quais classes existem no momento do install?
    print(string.format("[SpeedCameraBR] DIAG: Player=%s FSBaseMission=%s PlayerInputComponent=%s BasePlayer=%s",
        tostring(Player ~= nil), tostring(FSBaseMission ~= nil),
        tostring(PlayerInputComponent ~= nil), tostring(BasePlayer ~= nil)))

    -- Carrega config + contador quando a partida começa
    pcall(function()
        if Mission00 ~= nil and Mission00.loadMission00Finished ~= nil then
            Mission00.loadMission00Finished = Utils.appendedFunction(
                Mission00.loadMission00Finished,
                function() SpeedCameraMain.loadConfigOnStart() end)
        elseif FSBaseMission ~= nil and FSBaseMission.onFinishedLoading ~= nil then
            FSBaseMission.onFinishedLoading = Utils.appendedFunction(
                FSBaseMission.onFinishedLoading,
                function() SpeedCameraMain.loadConfigOnStart() end)
        end
    end)

    -- Registra a ação de input (Shift+R) enganchando em VÁRIAS classes,
    -- porque no FS25 o nome da classe que registra actions varia.
    pcall(function()
        -- FS25: PlayerInputComponent é quem gerencia input do jogador a pé
        if PlayerInputComponent ~= nil and PlayerInputComponent.registerActionEvents ~= nil then
            PlayerInputComponent.registerActionEvents = Utils.appendedFunction(
                PlayerInputComponent.registerActionEvents,
                function() SpeedCameraMain.registerActionEvents() end)
            print("[SpeedCameraBR] Hook em PlayerInputComponent OK")
        end
        -- Fallback: Player clássico
        if Player ~= nil and Player.registerActionEvents ~= nil then
            Player.registerActionEvents = Utils.appendedFunction(
                Player.registerActionEvents,
                function() SpeedCameraMain.registerActionEvents() end)
            print("[SpeedCameraBR] Hook em Player OK")
        end
    end)

    -- HOOK PRINCIPAL GARANTIDO: registra a action quando a missão inicia,
    -- e re-registra periodicamente via update (à prova de limpeza de contexto).
    pcall(function()
        if FSBaseMission ~= nil then
            FSBaseMission.onStartMission = Utils.appendedFunction(
                FSBaseMission.onStartMission,
                function()
                    print("[SpeedCameraBR] onStartMission → registrando action")
                    SpeedCameraMain.registerActionEvents()
                end)
            -- Update: garante o registro ativo continuamente (a cada ~2s)
            FSBaseMission.update = Utils.appendedFunction(
                FSBaseMission.update,
                function(mission, dt) SpeedCameraMain.onMissionUpdate(dt) end)
        end
    end)

    -- Comando de console (alternativa garantida)
    pcall(function()
        if addConsoleCommand ~= nil then
            addConsoleCommand("scAdmin",
                "Abre o painel de configuracao do Radar (somente admin)",
                "consoleOpenPanel", SpeedCameraMain)
        end
    end)

    print("[SpeedCameraBR] Mod carregado (install completo).")
end

-- Re-registra a action periodicamente (rede de segurança).
SpeedCameraMain._updateTimer = 0
function SpeedCameraMain.onMissionUpdate(dt)
    SpeedCameraMain._updateTimer = SpeedCameraMain._updateTimer + (dt or 0)
    if SpeedCameraMain._updateTimer >= 2000 then  -- a cada 2s
        SpeedCameraMain._updateTimer = 0
        SpeedCameraMain.registerActionEvents()
    end
end

function SpeedCameraMain:consoleOpenPanel()
    SpeedCameraMain.openAdminPanel()
    return "Abrindo painel do Radar..."
end

sc_install()
