-- sh_sdf_system_init.lua — Chargement ordonné de l'addon sdf_system.
-- Exécuté par GMod des deux côtés (CLIENT et SERVER) depuis autorun/.

SDFSystem = SDFSystem or {}

-- ─── Config shared (models, durées, loot table, skill-check, etc.) ────────
if SERVER then
    AddCSLuaFile("sdf_system/sh_config.lua")
end
include("sdf_system/sh_config.lua")

-- ─── Config serveur (permissions, rate-limits) ────────────────────────────
-- sv_config.lua n'est JAMAIS transmis au client.
if SERVER then
    include("sdf_system/sv_config.lua")
end

-- ─── Fichiers client ───────────────────────────────────────────────────────
if SERVER then
    AddCSLuaFile("autorun/client/cl_sdf_system_net.lua")
    AddCSLuaFile("autorun/client/cl_sdf_system_ui.lua")
    AddCSLuaFile("autorun/client/cl_sdf_system_keys.lua")
end

-- ─── Précache models ──────────────────────────────────────────────────────
for _, mdl in ipairs(SDFSystem.Config.Models) do
    util.PrecacheModel(mdl)
end

-- ─── Précache sons (shared : server et client en ont besoin) ──────────────
if SDFSystem.Config.Immersion then
    util.PrecacheSound(SDFSystem.Config.Immersion.SearchSound or "")
end
if SDFSystem.Config.Outcomes then
    util.PrecacheSound(SDFSystem.Config.Outcomes.RatSound or "")
end
if SDFSystem.Config.Jackpot then
    util.PrecacheSound(SDFSystem.Config.Jackpot.Sound or "")
end

-- ─── Helper partagé : ce joueur fouille-t-il une poubelle ? ───────────────
-- Basé sur la NetworkVar Searcher (répliquée) → résultat identique client et
-- serveur, donc utilisable dans SetupMove sans désync de prédiction.
function SDFSystem.IsSearching(ply)
    if not IsValid(ply) then return false, nil end
    local now = CurTime()
    for _, ent in ipairs(ents.FindByClass("sdf_trash")) do
        -- Garde-fou : juste après création/réplication, l'entité est IsValid mais
        -- sa table scriptée (accesseurs NetworkVar) n'est pas encore attachée.
        if IsValid(ent) and ent.GetSearcher and ent:GetSearcher() == ply then
            local se = ent.GetSearchEnd and ent:GetSearchEnd() or 0
            if se and se > 0 and now < se then return true, ent end
        end
    end
    return false, nil
end

-- ─── Accroupissement pendant la fouille ───────────────────────────────────
-- Animation fiable et visible (1re ET 3e personne) : on force IN_DUCK des deux
-- côtés tant que le joueur fouille. SetupMove tourne côté serveur (tous les
-- joueurs) et côté client (LocalPlayer, prédiction) → cohérent, sans saccade.
-- Perf : côté serveur on lit le flag ply.sdfSearching (posé par le SENT) ; côté
-- client on met en cache l'état (0.15s) pour éviter un FindByClass par tick.
local _scNext, _scVal = 0, false
hook.Add("SetupMove", "SDFSystem.CrouchWhileSearching", function(ply, mv, _)
    local imm = SDFSystem.Config and SDFSystem.Config.Immersion
    if not imm or not imm.CrouchWhileSearching then return end

    local searching
    if SERVER then
        searching = (ply.sdfSearching == true)
    else
        local now = CurTime()
        if now > _scNext then
            _scNext = now + 0.15
            _scVal  = SDFSystem.IsSearching(ply)
        end
        searching = _scVal
    end

    if searching then
        mv:SetButtons(bit.bor(mv:GetButtons(), IN_DUCK))
    end
end)

if SERVER and SDFSystem.SvConfig and SDFSystem.SvConfig.Debug then
    print("[SDFSystem] sh_sdf_system_init.lua chargé (SERVER)")
end
