-- =========================================================
-- FS25 Fertilizer Depot - Entry Point
-- =========================================================
-- Load order matters: constants first, then logger, then all
-- subsystems, then network events, then UI.

local modDir = g_currentModDirectory

-- Phase 1: Config
source(modDir .. "src/config/Constants.lua")
source(modDir .. "src/config/DepotSettings.lua")
source(modDir .. "src/DepotLogger.lua")

-- Phase 2: Core systems
source(modDir .. "src/CoopState.lua")
source(modDir .. "src/TransactionLog.lua")
source(modDir .. "src/integrations/SoilFertilizerBridge.lua")
source(modDir .. "src/DepotPricing.lua")
source(modDir .. "src/DepotSystem.lua")
source(modDir .. "src/delivery/DeliverySystem.lua")
source(modDir .. "src/DepotManager.lua")

-- Phase 3: Network
source(modDir .. "src/network/DepotPurchaseEvent.lua")
source(modDir .. "src/network/DepotSellEvent.lua")
source(modDir .. "src/network/DepotSiloFillEvent.lua")
source(modDir .. "src/network/DepotSyncEvent.lua")
source(modDir .. "src/network/CoopOwnerSyncEvent.lua")
source(modDir .. "src/network/CoopTransactionEvent.lua")
source(modDir .. "src/network/DepotSellAllEvent.lua")
source(modDir .. "src/network/DepotSellItemEvent.lua")
source(modDir .. "src/network/DepotSettingsEvent.lua")
source(modDir .. "src/network/DepotProductOrderEvent.lua")
source(modDir .. "src/network/DepotDeliverySyncEvent.lua")
source(modDir .. "src/network/DepotDeliveryOrderEvent.lua")
source(modDir .. "src/network/DepotDeliveryPickupEvent.lua")
source(modDir .. "src/network/DepotDeliveryCompleteEvent.lua")
source(modDir .. "src/network/DepotDeliveryCancelEvent.lua")

-- Phase 4: Placeables
source(modDir .. "src/placeable/PlaceableDepot.lua")
source(modDir .. "src/placeable/PlaceableSilo.lua")
source(modDir .. "src/placeable/PlaceableDepotPickup.lua")

-- Phase 5: UI (lazy-loaded on first open, but class must be defined)
source(modDir .. "src/ui/DepotDialog.lua")
source(modDir .. "src/ui/DepotSettingsDialog.lua")
source(modDir .. "src/ui/DepotHUD.lua")

-- ─── Mission00 Lifecycle Hooks ───────────────────────────

local function onMissionLoad(mission, ...)
    print("[CoopAgr] >>> onMissionLoad disparado")
    getfenv(0).g_DepotManager = DepotManager.new()
    print("[CoopAgr] >>> DepotManager.new() OK")
    g_DepotManager:initialize()
    print("[CoopAgr] >>> g_DepotManager:initialize() OK")

    -- Load settings from our own XML file (same pattern as FuelCosts, SoilFertilizer).
    -- FSCareerMissionInfo.loadFromXMLFile fires before g_DepotManager exists, so we
    -- read directly here where the manager is guaranteed to be present.
    local missionInfo = mission and mission.missionInfo
    if missionInfo and missionInfo.savegameDirectory then
        local path = missionInfo.savegameDirectory .. "/FS25_CooperativaAgricola.xml"
        if fileExists(path) then
            local xmlFile = XMLFile.load("depotSettingsLoad", path)
            if xmlFile then
                g_DepotManager.settings:loadFromXML(xmlFile, "fertilizerDepot.settings")
                DepotLogger._debug = g_DepotManager.settings.debugLogging
                xmlFile:delete()
                DepotLogger.info("Settings loaded from savegame")
            end
        else
            DepotLogger.info("No saved cooperative settings found; using defaults")
        end
    end
    -- (debug desligado para release)
    DepotLogger.info(">>> Mission load complete — debug=%s", tostring(DepotLogger._debug))
end

local function onMissionLoadFinished(mission, ...)
    if not g_DepotManager then return end
    -- SF global is now available if installed
    g_DepotManager.sfBridge:invalidateCache()
    DepotLogger.info("Post-load: SF installed: %s",
        tostring(g_DepotManager.sfBridge:isInstalled()))

    -- Configurações (Shift+M) NÃO usa mais action mapeável do FS25.
    -- Motivo: o jogo salva o mapeamento no perfil do jogador, e mapeamentos
    -- antigos (ex: Shift+D de versões anteriores) sobreviviam mesmo após trocar
    -- o modDesc. Agora Shift+M é detectado 100% via keyEvent (onMissionKeyEvent),
    -- sem nenhuma action registrada — assim não há perfil salvo nem entrada no
    -- menu de Controles pra "grudar" numa tecla antiga.
end

local function onMissionUpdate(mission, dt)
    if g_DepotManager then
        g_DepotManager:update(dt)
    end
end

local function onMissionDraw(mission)
    if g_DepotManager then
        g_DepotManager:drawHUD()
    end
end

local function onMissionMouseEvent(mission, posX, posY, isDown, isUp, button, ...)
    if g_DepotManager and g_DepotManager.hud then
        g_DepotManager.hud:onMouseEvent(posX, posY, isDown, isUp, button)
    end
end

-- ============================================================
-- Fallback: detecção direta de Shift+M via keyEvent
-- ============================================================
-- O sistema de inputBinding do FS25 só ativa o atalho depois que o
-- jogador entra em Opções > Controles e confirma o mapeamento.
-- Pra garantir que Shift+M funcione de cara, fazemos detecção direta
-- via keyEvent (que recebe TODO input do teclado em jogo).

local _coopKeyState = { shift = false }
local KEY_LSHIFT = 304  -- SDL keysym
local KEY_RSHIFT = 303
local KEY_M      = 109

local function onMissionKeyEvent(mission, unicode, sym, modifier, isDown)
    -- Tenta usar Input.KEY_* se disponível (FS25 expõe esses)
    if Input ~= nil then
        KEY_LSHIFT = Input.KEY_lshift or KEY_LSHIFT
        KEY_RSHIFT = Input.KEY_rshift or KEY_RSHIFT
        KEY_M      = Input.KEY_m      or KEY_M
    end

    -- Log de QUALQUER tecla pressionada (debug)
    if isDown and sym == KEY_M then
        print(string.format(
            "[CoopAgr] >>> KEY_M pressionado (sym=%d, shift=%s, modifier=%s)",
            sym, tostring(_coopKeyState.shift), tostring(modifier)))
    end

    -- Rastreia estado do shift
    if sym == KEY_LSHIFT or sym == KEY_RSHIFT then
        _coopKeyState.shift = isDown
        return
    end

    -- Detecta M pressionado com shift segurado OU modifier=2 (mask de shift)
    local shiftDown = _coopKeyState.shift or (modifier and modifier == 2) or (modifier and modifier == 1)
    if isDown and sym == KEY_M and shiftDown then
        if g_DepotManager and g_DepotManager.openSettingsDialog then
            print("[CoopAgr] >>> Shift+M detectado (fallback keyEvent) — abrindo configurações")
            local ok, err = pcall(function() g_DepotManager:openSettingsDialog() end)
            if not ok then
                print("[CoopAgr] ERROR ao abrir settings: " .. tostring(err))
            end
        else
            print("[CoopAgr] >>> Shift+M detectado mas g_DepotManager n/d")
        end
    end
end

local function onMissionDelete(mission, ...)
    if g_DepotManager then
        g_DepotManager:delete()
        getfenv(0).g_DepotManager = nil
    end
end

-- Save settings to our own XML file (same pattern as FuelCosts / SoilFertilizer).
-- The xmlFile argument from FSCareerMissionInfo.saveToXMLFile is always nil for mods;
-- we write directly to savegameDirectory instead.
local function onSaveToXML(missionInfo, xmlFile, ...)
    if not g_DepotManager then return end
    if not missionInfo or not missionInfo.savegameDirectory then
        DepotLogger.warning("onSaveToXML: savegameDirectory not available — skipping")
        return
    end
    local path = missionInfo.savegameDirectory .. "/FS25_CooperativaAgricola.xml"
    local outFile = XMLFile.create("depotSettingsSave", path, "fertilizerDepot")
    if not outFile then
        DepotLogger.warning("onSaveToXML: could not create XML file")
        return
    end
    g_DepotManager.settings:saveToXML(outFile, "fertilizerDepot.settings")
    outFile:save()
    outFile:delete()
    DepotLogger.info("Settings saved to %s", path)
end

-- Send settings + delivery state to a joining client
local function onSendInitialClientState(mission, connection, ...)
    if not g_DepotManager then return end
    DepotSettingsSyncEvent.sendToClient(connection)
    -- Sync active deliveries so the ORDER tab is correct for joining players
    if g_DepotManager.deliverySystem then
        for depotId in pairs(g_DepotManager.depots) do
            DepotDeliverySyncEvent.sendToClient(connection, depotId)
        end
    end
end

-- PREPEND so g_DepotManager exists before Mission00.load loads savegame placeables.
-- appendedFunction would create it AFTER onPostFinalizePlacement fires → depotId never set.
Mission00.load                        = Utils.prependedFunction(Mission00.load,                        onMissionLoad)
Mission00.loadMission00Finished       = Utils.appendedFunction(Mission00.loadMission00Finished,       onMissionLoadFinished)
FSBaseMission.update                  = Utils.appendedFunction(FSBaseMission.update,                  onMissionUpdate)
FSBaseMission.draw                    = Utils.appendedFunction(FSBaseMission.draw,                    onMissionDraw)
FSBaseMission.mouseEvent              = Utils.prependedFunction(FSBaseMission.mouseEvent,             onMissionMouseEvent)
FSBaseMission.keyEvent                = Utils.appendedFunction(FSBaseMission.keyEvent,                onMissionKeyEvent)
FSBaseMission.delete                  = Utils.appendedFunction(FSBaseMission.delete,                  onMissionDelete)
FSBaseMission.sendInitialClientState  = Utils.appendedFunction(FSBaseMission.sendInitialClientState,  onSendInitialClientState)
FSCareerMissionInfo.saveToXMLFile     = Utils.appendedFunction(FSCareerMissionInfo.saveToXMLFile,     onSaveToXML)

-- Console commands are registered as methods on DepotManager in DepotManager.lua
-- using `self` as the target, following the FS25 addConsoleCommand pattern.
