BladW = BladW or {}
BladW.Announcement = BladW.Announcement or {}

-- pour que les clients téléchargent le son
resource.AddFile("sound/announce.mp3")

-- coupe une chaîne à maxChars caractères (propre avec les accents)
local function LimitChars(str, maxChars)
    str = tostring(str or "")
    local n = utf8.len(str)
    if not n or n <= maxChars then return str end
    local endByte = utf8.offset(str, maxChars + 1)
    return endByte and string.sub(str, 1, endByte - 1) or str
end

-- ouvre le menu pour le joueur
concommand.Add("bladw_amenu", function(ply, cmd)
    if not IsValid(ply) then return end

    net.Start("bladWOpenAnnouncementMenu")
    net.Send(ply)
end)

-- /bannonce (ou !bannonce) dans le chat = ouvre le menu
hook.Add("PlayerSay", "BladW:AnnouncementChatCmd", function(ply, text)
    local cmd = string.lower(string.Trim(text))
    if cmd ~= "/bannonce" and cmd ~= "!bannonce" then return end
    if not IsValid(ply) then return end

    net.Start("bladWOpenAnnouncementMenu")
    net.Send(ply)

    return "" -- pour pas laisser la commande dans le chat
end)

-- reconstruit l'annonce finale : le preset sert de base, title/text passent devant
function BladW.Announcement.Resolve(entry)
    local presets = BladW.Announcement.Presets or {}
    local base    = (entry.preset and presets[entry.preset]) or {}

    return {
        title    = (entry.title and entry.title ~= "" and entry.title) or base.title or "Annonce",
        text     = (entry.text  and entry.text  ~= "" and entry.text ) or base.text  or "",
        style    = entry.style or base.style or "",
        duration = tonumber(entry.duration) or tonumber(base.duration) or 0,
    }
end

-- envoie l'annonce à tout le monde. false si y'a rien à envoyer
function BladW.Announcement.Broadcast(entry)
    local a = BladW.Announcement.Resolve(entry)
    if a.text == "" then return false end

    local maxLen = tonumber((BladW.Announcement.Conf or {}).announcement_max_length) or 120

    net.Start("bladWShowAnnouncement")
        net.WriteString(LimitChars(a.title, 64))
        net.WriteString(LimitChars(a.text, maxLen))
        net.WriteString(a.style or "")
        net.WriteUInt(math.Clamp(a.duration, 0, 65535), 16)
    net.Broadcast()

    return true
end

-- un admin veut poster une annonce -> je la diffuse
net.Receive("bladWSendAnnouncement", function(len, ply)
    if not IsValid(ply) or not ply:IsAdmin() then return end

    local preset = net.ReadString()
    local title  = net.ReadString()
    local text   = net.ReadString()

    BladW.Announcement.Broadcast({
        preset = preset ~= "" and preset or nil,
        title  = title,
        text   = text,
    })
end)
