-- sv_sdf_system_net.lua — net.Receive handlers serveur + déclaration des net strings.
-- NE PAS AddCSLuaFile ce fichier.

SDFSystem = SDFSystem or {}

-- ─── Déclaration des net strings ─────────────────────────────────────────
util.AddNetworkString("SDFSystem.OpenMenu")
util.AddNetworkString("SDFSystem.RequestMenuSync")
util.AddNetworkString("SDFSystem.MenuSync")
util.AddNetworkString("SDFSystem.RequestSpawn")
util.AddNetworkString("SDFSystem.RequestRemove")
util.AddNetworkString("SDFSystem.RequestTeleport")
util.AddNetworkString("SDFSystem.SearchComplete")   -- S→C : résultat fouille
util.AddNetworkString("SDFSystem.SearchCancelled")  -- S→C : fouille annulée
util.AddNetworkString("SDFSystem.SpawnResult")      -- S→C : résultat spawn admin
util.AddNetworkString("SDFSystem.Jackpot")          -- S→C : overlay jackpot

-- ─── C→S : Sync du menu ──────────────────────────────────────────────────
net.Receive("SDFSystem.RequestMenuSync", function(_, ply)
    if not IsValid(ply) then return end
    if not SDFSystem.SvConfig.CanManage(ply) then return end
    SDFSystem.SendMenuSync(ply)
end)

-- ─── C→S : Spawn d'une poubelle ───────────────────────────────────────────
net.Receive("SDFSystem.RequestSpawn", function(_, ply)
    if not IsValid(ply) then return end

    local now = CurTime()
    if (ply.sdfNextAdminAction or 0) > now then
        net.Start("SDFSystem.SpawnResult")
            net.WriteBool(false)
            net.WriteString("Trop vite — attends un instant.")
        net.Send(ply)
        return
    end
    ply.sdfNextAdminAction = now + SDFSystem.SvConfig.AdminActionCooldown

    if not SDFSystem.SvConfig.CanManage(ply) then
        net.Start("SDFSystem.SpawnResult")
            net.WriteBool(false)
            net.WriteString("Accès refusé.")
        net.Send(ply)
        return
    end

    local modelIdx = net.ReadUInt(SDFSystem.MODEL_INDEX_BITS)
    if modelIdx < 1 or modelIdx > #SDFSystem.Config.Models then
        net.Start("SDFSystem.SpawnResult")
            net.WriteBool(false)
            net.WriteString("Index model invalide.")
        net.Send(ply)
        return
    end

    local tr = ply:GetEyeTrace()
    if not tr or not tr.Hit then
        net.Start("SDFSystem.SpawnResult")
            net.WriteBool(false)
            net.WriteString("Impossible de déterminer la position.")
        net.Send(ply)
        return
    end

    local ent = SDFSystem.SpawnTrash(modelIdx, tr.HitPos, Angle(0, ply:EyeAngles().y, 0))
    if not IsValid(ent) then
        net.Start("SDFSystem.SpawnResult")
            net.WriteBool(false)
            net.WriteString("Erreur de création de l'entité.")
        net.Send(ply)
        return
    end

    net.Start("SDFSystem.SpawnResult")
        net.WriteBool(true)
        net.WriteString("Poubelle placée ! (id=" .. tostring(ent.dbId) .. ")")
    net.Send(ply)

    SDFSystem.SendMenuSync(ply)
end)

-- ─── C→S : Suppression d'une poubelle ─────────────────────────────────────
net.Receive("SDFSystem.RequestRemove", function(_, ply)
    if not IsValid(ply) then return end

    local now = CurTime()
    if (ply.sdfNextAdminAction or 0) > now then return end
    ply.sdfNextAdminAction = now + SDFSystem.SvConfig.AdminActionCooldown

    if not SDFSystem.SvConfig.CanManage(ply) then return end

    local dbId = net.ReadUInt(SDFSystem.DB_ID_BITS)
    if dbId <= 0 then return end

    SDFSystem.RemoveTrash(dbId)
    SDFSystem.SendMenuSync(ply)
end)

-- ─── C→S : Téléport vers une poubelle ────────────────────────────────────
net.Receive("SDFSystem.RequestTeleport", function(_, ply)
    if not IsValid(ply) then return end

    local now = CurTime()
    if (ply.sdfNextAdminAction or 0) > now then return end
    ply.sdfNextAdminAction = now + SDFSystem.SvConfig.AdminActionCooldown

    if not SDFSystem.SvConfig.CanManage(ply) then return end

    local dbId = net.ReadUInt(SDFSystem.DB_ID_BITS)
    if dbId <= 0 then return end

    for _, ent in ipairs(ents.FindByClass("sdf_trash")) do
        if IsValid(ent) and ent.dbId == dbId then
            ply:SetPos(ent:GetPos() + Vector(0, 0, 72))
            DarkRP.notify(ply, 0, 3, "Téléporté vers la poubelle #" .. dbId)
            return
        end
    end

    DarkRP.notify(ply, 1, 3, "Poubelle introuvable dans le monde.")
end)
