-- ## Author: LSP ## Version: 2.0  ## SavedVariables: ChatDanmakuDB
-- 聊天弹幕插件 （修正层级遮挡 + 修复自己消息过滤 + 自定义频道开关 + 修复大秘境秘密值报错 + 名字固定职业颜色）
-- 效果：区分队长/团长前缀 | 顶部Y-25位置  | 修复层级遮挡 | 中英文前缀自动切换 | 频道自定义+开关 | 兼容大秘境秘密值 | 非战网频道名字固定职业颜色

local _, ns = ...
local B, C, L, DB = unpack(ns)
--local module = B:GetModule("Chat")
local ChatDanmaku = {}
local frame = CreateFrame("Frame")
frame:RegisterEvent("ADDON_LOADED")
frame:RegisterEvent("UI_SCALE_CHANGED")
frame:RegisterEvent("PLAYER_ENTERING_WORLD")

local config = {
    anchorPoint = "TOPLEFT",       -- 核心修正：改为左上角锚点
    xOffset = 0,                    -- 严格X0滚入起点
    yOffset = -36,                  -- 屏幕顶部下移25像素（核心修正）
    speed = 280,                    -- 默认速度300
    lifetime = 12,                  -- 显示时长
    fontSize = 28,                  -- 字体大小
    fontOutline = "OUTLINE",        -- 默认轮廓
    fontShadow = true,              -- 阴影开启
    shadowOffsetX = 1,              -- 阴影X1
    shadowOffsetY = -1,             -- 阴影Y-1
    
    scrollWidth = UIParent:GetWidth(),  -- 自适应屏幕宽度
    scrollHeight = 520,                 -- 修正：仅容纳15条弹幕（避免覆盖中间）
    maxDanmaku = 12,                   -- 默认最大15条
    monitorChat = true,                -- 监控聊天
    monitorSelfChat = true,            -- 监控自己消息（修复：默认开启，可通过命令关闭）
    frameStrata = "MEDIUM",            -- 核心修改：降低显示层级
    frameLevel = 10,                   -- 同层级内的显示优先级（默认10，数值越大越靠前）
    
    -- 前缀语言配置：auto=自动判断，cn=强制中文，en=强制英文
    prefixLang = "auto",
    
    -- 【核心修改】频道配置（带开关，可自定义添加）
    chatChannels = {
        ["PARTY"] =          { enable = true,  nameCN = "小队",        nameEN = "Party" },
        ["PARTY_LEADER"] =   { enable = true,  nameCN = "队长",        nameEN = "Leader" },
        ["RAID"] =           { enable = true,  nameCN = "团队",        nameEN = "Raid" },
        ["RAID_LEADER"] =    { enable = true,  nameCN = "团长",        nameEN = "RaidLead" },
        ["WHISPER"] =        { enable = true,  nameCN = "私聊",        nameEN = "Whisper" },
        ["RAID_WARNING"] =   { enable = true,  nameCN = "通知",        nameEN = "Warning" },
        ["BATTLEGROUND"] =   { enable = true,  nameCN = "副本",        nameEN = "BG" },
        ["BNET_WHISPER"] =   { enable = true, nameCN = "战网",        nameEN = "BNet" },
        ["GUILD"] =          { enable = false, nameCN = "公会",        nameEN = "Guild" },
        ["SAY"] =            { enable = false, nameCN = "说",          nameEN = "Say" },
        ["YELL"] =           { enable = false, nameCN = "大喊",        nameEN = "Yell" },
    },
    
    -- 中文前缀（区分队长/团长，新增公会/说/大喊）
    chatPrefixCN = {
        ["PARTY"] = "[小队]",
        ["PARTY_LEADER"] = "[队长]",  -- 小队队长单独前缀
        ["RAID"] = "[团队]",
        ["RAID_LEADER"] = "[团长]",  -- 团队团长单独前缀
        ["WHISPER"] = "[私聊]",
        ["BNET_WHISPER"] = "[战网]",
        ["RAID_WARNING"] = "[通知]",
        ["BATTLEGROUND"] = "[副本]",
        ["GUILD"] = "[公会]",
        ["SAY"] = "[说]",
        ["YELL"] = "[大喊]",
        ["SYSTEM"] = "[系统]"
    },
    
    -- 英文前缀（对应中文版本，新增公会/说/大喊）
    chatPrefixEN = {
        ["PARTY"] = "[Party]",
        ["PARTY_LEADER"] = "[Leader]",  -- 小队队长
        ["RAID"] = "[Raid]",
        ["RAID_LEADER"] = "[RaidLead]", -- 团队团长
        ["WHISPER"] = "[Whisper]",
        ["BNET_WHISPER"] = "[BNet]",
        ["RAID_WARNING"] = "[Warning]",
        ["BATTLEGROUND"] = "[BG]",
        ["GUILD"] = "[Guild]",
        ["SAY"] = "[Say]",
        ["YELL"] = "[Yell]",
        ["SYSTEM"] = "[System]"
    },
    -- 自定义颜色（战网+兜底，BNET频道固定使用此配色，不触发职业颜色）
    customColors = {
        ["BNET_WHISPER"] = { r = 0.2, g = 0.9, b = 1 }, -- 荧光蓝
        ["SYSTEM"] = { r = 1, g = 1, b = 0 }, -- 黄色
        ["BATTLEGROUND"] = { r = 1, g = 0.6, b = 0 }, -- 橙色（副本/战场）
    },
    -- 过滤关键字
    filterKeywords = {
        "接受任务", "大脚任务", "(任务完成)", "持续了","任务：", "]->",
        "在海岛探险中收集","特别任务","Wind","→",
    }
}

-- 弹幕对象池
local danmakuPool = {}
local activeDanmakus = {}

-- 【核心优化】获取玩家职业颜色函数（增强私聊职业颜色查询，BNET频道不调用此函数）
local function getClassColor(playerName, chatType, senderGUID)
    -- 处理跨服名称（去掉服务器后缀）
    local nameWithoutRealm = playerName
    local hyphenPos = string.find(playerName, "-")
    if hyphenPos and hyphenPos > 1 then
        nameWithoutRealm = string.sub(playerName, 1, hyphenPos - 1)
    end
    
    -- 优先从团队中获取职业信息
    local classFilename
    for i = 1, GetNumGroupMembers() do
        local unit = "raid" .. i
        if UnitExists(unit) then
            local unitName = UnitName(unit)
            if unitName == nameWithoutRealm then
                classFilename = select(2, UnitClass(unit))
                break
            end
        end
    end
    
    -- 团队未获取到，从小队中获取职业信息
    if not classFilename then
        for i = 1, 4 do
            local unit = "party" .. i
            if UnitExists(unit) then
                local unitName = UnitName(unit)
                if unitName == nameWithoutRealm then
                    classFilename = select(2, UnitClass(unit))
                    break
                end
            end
        end
    end
    
    -- 未获取到，检查是否是玩家自己
    if not classFilename then
        local myName = UnitName("player")
        if nameWithoutRealm == myName then
            classFilename = select(2, UnitClass("player"))
        end
    end
    
    -- 【核心新增】私聊专用查询逻辑（原生聊天栏的核心机制）
    if not classFilename and chatType == "WHISPER" then
        -- 尝试通过GUID获取职业信息（最准确）
        if senderGUID and senderGUID ~= "" then
            local _, _, _, _, _, classID = GetPlayerInfoByGUID(senderGUID)
            if classID then
                classFilename = LOCALIZED_CLASS_NAMES_MALE[GetClassInfo(classID)]
            end
        end
        
        -- 如果GUID获取失败，尝试通过单位ID查询（适用于同服/同场景玩家）
        if not classFilename then
            -- 尝试直接查询玩家单位
            local unitID
            -- 检查是否是目标
            if UnitName("target") == nameWithoutRealm then
                unitID = "target"
            end
            -- 检查是否是焦点
            if not unitID and UnitName("focus") == nameWithoutRealm then
                unitID = "focus"
            end
            
            if unitID then
                classFilename = select(2, UnitClass(unitID))
            end
        end
        
        -- 最后尝试通过好友列表查询
        if not classFilename then
            -- 遍历战网好友
            for i = 1, BNGetNumFriends() do
                local _, _, battleTag, _, _, _, _, _, _, toonName, toonRealm = BNGetFriendInfo(i)
                if toonName and toonName == nameWithoutRealm then
                    -- 处理跨服
                    local fullRealm = GetRealmName()
                    if not toonRealm or toonRealm == fullRealm then
                        local _, class = BNGetToonInfo(BNGetFriendInfo(i))
                        if class then
                            classFilename = class
                            break
                        end
                    end
                end
            end
            
            -- 遍历游戏内好友
            if not classFilename then
                for i = 1, C_FriendList.GetNumFriends() do
                    local friendInfo = C_FriendList.GetFriendInfoByIndex(i)
                    if friendInfo and friendInfo.name == nameWithoutRealm then
                        classFilename = friendInfo.className
                        break
                    end
                end
            end
        end
    end
    
    -- 成功获取职业，返回魔兽原生职业色值
    if classFilename then
        local color = RAID_CLASS_COLORS[classFilename]
        if color then
            return string.format("|cff%02x%02x%02x", color.r*255, color.g*255, color.b*255)
        end
    end
    
    -- 无法获取职业时，兜底返回白色
    return "|cffffffff"
end

-- 检测秘密值函数（改为复用暴雪原生函数，和WhisperPop保持一致）
local function isSecretValue(text)
    -- 防御性检查：先判断原生函数是否存在，再调用
    if issecretvalue then
        return issecretvalue(text)
    end
    return false
end

-- 自动判断语言的核心函数
local function getAutoPrefixLang(msg)
    -- 优先根据游戏客户端语言判断
    local clientLang = GetLocale()
    if clientLang == "zhCN" or clientLang == "zhTW" then
        return "cn"
    else
        return "en"
    end
end

-- 获取最终要显示的前缀（自动/手动切换）
local function getChatPrefix(chatType)
    -- 确定使用的语言
    local useLang = config.prefixLang
    if useLang == "auto" then
        useLang = getAutoPrefixLang()
    end
    
    -- 根据语言返回对应前缀
    if useLang == "cn" then
        return config.chatPrefixCN[chatType] or "[未知]"
    else
        return config.chatPrefixEN[chatType] or "[Unknown]"
    end
end

-- 获取聊天颜色（优先自定义，再内置，BNET频道固定走自定义颜色）
local function getChatColor(chatType)
    if config.customColors[chatType] then
        return config.customColors[chatType]
    end
    return ChatTypeInfo[chatType] or config.customColors["SYSTEM"]
end

-- 弹幕重排函数（抽离重复逻辑）
local function repositionDanmakus()
    local spacing = config.fontSize + 5
    for i, dm in ipairs(activeDanmakus) do
        dm.y = config.yOffset - (i-1) * spacing
        dm.frame:SetPoint("TOPLEFT", UIParent, "TOPLEFT", math.floor(dm.x + 0.5), dm.y)
    end
end

-- 事件与频道的映射表
local eventToChatType = {
    ["CHAT_MSG_PARTY"] = "PARTY",
    ["CHAT_MSG_PARTY_LEADER"] = "PARTY_LEADER",
    ["CHAT_MSG_RAID"] = "RAID",
    ["CHAT_MSG_RAID_LEADER"] = "RAID_LEADER",
    ["CHAT_MSG_WHISPER"] = "WHISPER",
    ["CHAT_MSG_WHISPER_INFORM"] = "WHISPER",
    ["CHAT_MSG_BN_WHISPER"] = "BNET_WHISPER",
    ["CHAT_MSG_BN_WHISPER_INFORM"] = "BNET_WHISPER",
    ["CHAT_MSG_RAID_WARNING"] = "RAID_WARNING",
    ["CHAT_MSG_INSTANCE_CHAT"] = "BATTLEGROUND",
    ["CHAT_MSG_INSTANCE_CHAT_LEADER"] = "BATTLEGROUND",
    ["CHAT_MSG_GUILD"] = "GUILD",
    ["CHAT_MSG_SAY"] = "SAY",
    ["CHAT_MSG_YELL"] = "YELL",
}

-- ==================== 场景难度判断工具函数 ====================
local function IsInMythicPlus()
    local inInstance, instanceType = IsInInstance()
    if not inInstance or instanceType ~= "party" then return false end
    local _, _, difficultyID = GetInstanceInfo()
    return difficultyID == 8
end

local function IsInBossEncounter()
    return UnitExists("boss1") or IsEncounterInProgress()
end

local function ShouldDisableDanmaku()
    if IsInMythicPlus() then
        return true
    end
    if IsInBossEncounter() then
        return true
    end
    return false
end

-- 初始化函数
local function init()
    -- 主容器：严格X0 Y-25定位（顶部下移25像素）
    ChatDanmaku.mainFrame = CreateFrame("Frame", "ChatDanmakuMainFrame", UIParent)
    ChatDanmaku.mainFrame:SetPoint(config.anchorPoint, UIParent, config.anchorPoint, config.xOffset, config.yOffset)
    ChatDanmaku.mainFrame:SetSize(config.scrollWidth, config.scrollHeight)
    ChatDanmaku.mainFrame:SetScale(1)
    ChatDanmaku.mainFrame:SetFrameStrata(config.frameStrata)
    ChatDanmaku.mainFrame:SetFrameLevel(config.frameLevel)
    
    -- 平滑滚动基础设置
    ChatDanmaku.mainFrame:SetResizeBounds(1,1)
    ChatDanmaku.mainFrame:SetClampedToScreen(false)

    -- 动态注册聊天事件（根据频道开关）
    if config.monitorChat then
        -- 先取消所有已注册的聊天事件（避免重复）
        frame:UnregisterAllEvents()
        -- 重新注册基础事件
        frame:RegisterEvent("ADDON_LOADED")
        frame:RegisterEvent("UI_SCALE_CHANGED")
        frame:RegisterEvent("PLAYER_ENTERING_WORLD")
        
        -- 只注册开启的频道事件
        for event, chatType in pairs(eventToChatType) do
            if config.chatChannels[chatType] and config.chatChannels[chatType].enable then
                frame:RegisterEvent(event)
            end
        end
    end

    -- 核心滚动逻辑
    ChatDanmaku.mainFrame:SetScript("OnUpdate", function(self, elapsed)
        local now = GetTime()
        local removeIndices = {}

        for i, dm in ipairs(activeDanmakus) do
            -- 平滑移动：像素对齐
            dm.x = dm.x - (config.speed * elapsed)
            dm.frame:SetPoint("TOPLEFT", UIParent, "TOPLEFT", math.floor(dm.x + 0.5), dm.y)

            -- 滚出判定：文字完全滚出屏幕
            if now > dm.expireTime or dm.x < -dm.textWidth then
                table.insert(removeIndices, i)
            end
        end

        -- 移除过期弹幕
        for i = #removeIndices, 1, -1 do
            local idx = removeIndices[i]
            local dm = activeDanmakus[idx]
            dm.frame:Hide()
            table.insert(danmakuPool, dm)
            table.remove(activeDanmakus, idx)
        end
        
        -- 实时重排（仅在移除弹幕时重排，优化性能）
        if #removeIndices > 0 then
            repositionDanmakus()
        end
    end)
    
    -- 自适应屏幕分辨率
    ChatDanmaku.mainFrame:SetScript("OnSizeChanged", function(self)
        config.scrollWidth = UIParent:GetWidth()
        self:SetSize(config.scrollWidth, config.scrollHeight)
    end)
end

-- 字体样式（清晰+左对齐+阴影+轮廓）
local function updateFontStyle(text)
    text:SetFont(STANDARD_TEXT_FONT, config.fontSize, config.fontOutline)
    -- 阴影设置
    if config.fontShadow then
        text:SetShadowOffset(config.shadowOffsetX, config.shadowOffsetY)
    else
        text:SetShadowOffset(0, 0)
    end
    text:SetJustifyH("LEFT")
    text:SetJustifyV("MIDDLE")
    text:SetWordWrap(false)
    text:SetMaxLines(1)
end

-- 关键字过滤函数
local function isFilteredMessage(msg)
    if not msg or msg == "" then return true end
    for _, keyword in ipairs(config.filterKeywords) do
        if string.find(msg, keyword) then
            return true
        end
    end
    return false
end

-- 创建/获取弹幕对象
local function getDanmaku()
    if #danmakuPool > 0 then
        local dm = table.remove(danmakuPool)
        updateFontStyle(dm.text)
        -- 自适应文字宽度
        dm.frame:SetSize(dm.text:GetStringWidth() or config.fontSize * 5, config.fontSize + 10)
        return dm
    end

    -- 新建弹幕框架
    local dmFrame = CreateFrame("Frame", nil, UIParent)
    dmFrame:SetResizable(false)
    dmFrame:SetFrameStrata(config.frameStrata)
    dmFrame:SetFrameLevel(config.frameLevel)
    
    -- 文字控件
    local text = dmFrame:CreateFontString(nil, "OVERLAY")
    text:SetAllPoints(dmFrame)
    updateFontStyle(text)

    return {
        frame = dmFrame,
        text = text,
        x = 0,
        y = 0,
        textWidth = 0,
        expireTime = 0
    }
end

-- 核心：发送弹幕
local function sendDanmaku(content, chatType)
    -- 场景禁用：大秘境全程 / 其他BOSS战 不显示弹幕
    if ShouldDisableDanmaku() then
        return
    end

    -- 秘密值双重检测
    if isSecretValue(content) then
        return
    end
    
    -- 超过最大数时，移除最旧的弹幕
    if #activeDanmakus >= config.maxDanmaku then
        local oldestDm = table.remove(activeDanmakus, 1)
        oldestDm.frame:Hide()
        table.insert(danmakuPool, oldestDm)
    end

    local dm = getDanmaku()
    dm.text:SetText(content)
    
    -- 获取文字宽度（用于滚入计算）
    dm.textWidth = dm.text:GetStringWidth()
    -- 弹幕框架尺寸自适应文字宽度
    dm.frame:SetSize(dm.textWidth, config.fontSize + 10)

    -- 聊天频道颜色（BNET频道固定使用自定义荧光蓝）
    local chatColor = getChatColor(chatType)
    dm.text:SetTextColor(chatColor.r, chatColor.g, chatColor.b)

    -- 起始位置与过期时间
    dm.x = UIParent:GetWidth()
    dm.y = config.yOffset - (#activeDanmakus) * (config.fontSize + 5)
    dm.expireTime = GetTime() + config.lifetime

    -- 锚点定位与显示
    dm.frame:SetPoint("TOPLEFT", UIParent, "TOPLEFT", math.floor(dm.x + 0.5), dm.y)
    dm.frame:Show()

    -- 加入活跃列表并重排
    table.insert(activeDanmakus, dm)
    repositionDanmakus()
end

-- 事件处理（核心优化：BNET频道隔离职业颜色逻辑）
frame:SetScript("OnEvent", function(self, event, ...)
    if not C.db["Chat"]["ChatDanmu"] then return end
    local args = {...}
    
    if event == "ADDON_LOADED" then
        local loadedAddon = args[1]
        if loadedAddon == "OrzUI" then
            init()
            self:UnregisterEvent("ADDON_LOADED")
        end
        return
    elseif event == "UI_SCALE_CHANGED" or event == "PLAYER_ENTERING_WORLD" then
        -- 适配屏幕分辨率变化
        config.scrollWidth = UIParent:GetWidth()
        if ChatDanmaku.mainFrame then
            ChatDanmaku.mainFrame:SetSize(config.scrollWidth, config.scrollHeight)
        end
        return
    end

    -- 聊天事件处理
    if string.find(event, "CHAT_MSG_") then
        -- 全局场景屏蔽，彻底杜绝报错
        if ShouldDisableDanmaku() then
            return
        end

        local msg = args[1]

        -- 秘密值优先检测，避免报错
        if isSecretValue(msg) then
            return
        end
        
        local author = args[2]
        local _, _, _, _, _, _, _, _, _, _, _, playerNameWithRealm, senderGUID = ... -- 【核心新增】获取senderGUID
        local myName = UnitName("player")
        local myFullName = UnitName("player") .. "-" .. GetRealmName()

        -- 关键字过滤
        if isFilteredMessage(msg) then return end

        -- 自己消息过滤逻辑
        if not config.monitorSelfChat then
            local authorWithoutRealm = author
            local hyphenPos = string.find(author, "-")
            if hyphenPos and hyphenPos > 1 then
                authorWithoutRealm = string.sub(author, 1, hyphenPos - 1)
            end

            -- 精准匹配自己的消息
            local isSelfMsg = (authorWithoutRealm == myName) 
                or (author == myFullName) 
                or (playerNameWithRealm == myFullName)
            
            if isSelfMsg then return end
        end

        -- 事件映射频道类型+频道开关校验
        local chatType = eventToChatType[event]
        if not chatType or not config.chatChannels[chatType] or not config.chatChannels[chatType].enable then
            return
        end

        -- 处理显示名称（去掉服务器后缀）
        local displayName = author or "未知/Unknown"
        local hyphenPos = string.find(displayName, "-")
        if hyphenPos and hyphenPos > 1 then
            displayName = string.sub(displayName, 1, hyphenPos - 1)
        end

        -- 【核心隔离】BNET战网频道不使用职业颜色，保持原生显示逻辑
        local finalName = displayName
        if chatType ~= "BNET_WHISPER" then
            -- 非BNET频道，统一添加职业颜色（【核心修改】传入chatType和senderGUID）
            local classColor = getClassColor(author, chatType, senderGUID)
            finalName = classColor .. displayName .. "|r"
        end

        -- 获取频道前缀
        local prefix = getChatPrefix(chatType)

        -- 发送弹幕
        sendDanmaku(string.format("%s %s: %s", prefix, finalName, msg), chatType)
    end
end)

--[[ ==================== 辅助函数：显示过滤列表 ====================
local function showFilterList()
    print("|cff00ff00=====================================|r")
    print("|cff00ff00当前过滤关键字列表 | Current Filter Keywords|r")
    print("|cff00ff00=====================================|r")
    
    if #config.filterKeywords == 0 then
        print("|cff00ff00- 暂无过滤关键字 | No filter keywords|r")
    else
        for i, keyword in ipairs(config.filterKeywords) do
            print(string.format("|cff00ff00%d. %s|r", i, keyword))
        end
    end
    
    print("|cff00ff00=====================================|r")
    print("|cff00ff00使用 /danmaku filter add 关键字 增加过滤词|r")
    print("|cff00ff00使用 /danmaku filter del 关键字 删除过滤词|r")
end

-- ==================== 辅助函数：显示频道列表 ====================
local function showChannelList()
    print("|cff00ff00=====================================|r")
    print("|cff00ff00当前频道开关状态 | Current Channel Status|r")
    print("|cff00ff00=====================================|r")
    for chatType, info in pairs(config.chatChannels) do
        local status = info.enable and "|cff00ff00开启|r" or "|cffff0000关闭|r"
        local name = GetLocale():find("zh") and info.nameCN or info.nameEN
        print(string.format("|cffffff00%s|r (%s): %s", name, chatType, status))
    end
    print("|cff00ff00=====================================|r")
    print("|cff00ff00使用 /danmaku channel [频道类型] on/off 切换开关|r")
    print("|cff00ff00示例：/danmaku channel GUILD on|r")
end

-- ==================== 完整命令行（已移除职业颜色相关命令） ====================
SLASH_DANMAKU1 = "/danmaku"
SLASH_DANMAKU2 = "/dm"
SlashCmdList["DANMAKU"] = function(cmd)
    cmd = string.trim(string.lower(cmd))

    if cmd == "clear" then
        -- 清空所有弹幕
        for i, dm in ipairs(activeDanmakus) do
            dm.frame:Hide()
            table.insert(danmakuPool, dm)
        end
        activeDanmakus = {}
        print("已清空所有弹幕 / Cleared all danmaku")

    elseif cmd == "test" then
        -- 发送测试弹幕
        local testLang = config.prefixLang == "auto" and getAutoPrefixLang() or config.prefixLang
        -- 获取自己的职业颜色用于测试
        local myClassColor = getClassColor(UnitName("player"), "WHISPER", UnitGUID("player"))
        local myColoredName = myClassColor .. UnitName("player") .. "|r"
        
        if testLang == "cn" then
            sendDanmaku("普通小队消息 - 第一个字从右侧滚入", "PARTY")
            sendDanmaku("小队队长消息 - 专属前缀", "PARTY_LEADER")
            sendDanmaku("普通团队消息 - 顶部Y-25位置", "RAID")
            sendDanmaku("团队团长消息 - 专属前缀", "RAID_LEADER")
            sendDanmaku("战网私聊消息 - 固定自定义荧光蓝", "BNET_WHISPER")
            sendDanmaku("普通私聊消息 - 职业颜色增强测试", "WHISPER")
            print(string.format("已发送测试弹幕：区分小队/队长/团队/团长前缀，非战网名字职业颜色：%s测试|r", myClassColor))
        else
            sendDanmaku("Normal Party Msg - First char scrolls in from right", "PARTY")
            sendDanmaku("Party Leader Msg - Exclusive prefix", "PARTY_LEADER")
            sendDanmaku("Normal Raid Msg - Position at TOP Y-25", "RAID")
            sendDanmaku("Raid Leader Msg - Exclusive prefix", "RAID_LEADER")
            sendDanmaku("BNet Whisper Msg - Fixed custom color", "BNET_WHISPER")
            sendDanmaku("Normal Whisper Msg - Enhanced class color test", "WHISPER")
            print(string.format("Test danmaku sent: Distinguish prefix, non-BNet name with class color: %sTest|r", myClassColor))
        end

    elseif string.find(cmd, "^speed") then
        -- 设置滚动速度
        local newSpeed = tonumber(string.match(cmd, "speed%s+(%d+)"))
        if newSpeed and newSpeed > 0 then
            config.speed = newSpeed
            print(string.format("弹幕速度已设置为: %d 像素/秒 | Danmaku speed set to: %d px/s", newSpeed, newSpeed))
        else
            print(string.format("当前速度: %d 像素/秒 | 使用 /danmaku speed 数字 调整 | Current speed: %d px/s | Use /danmaku speed [number] to adjust", config.speed, config.speed))
        end

    elseif string.find(cmd, "^fontsize") then
        -- 设置字体大小
        local newFontSize = tonumber(string.match(cmd, "fontsize%s+(%d+)"))
        if newFontSize and newFontSize >= 8 and newFontSize <= 40 then
            config.fontSize = newFontSize
            -- 刷新现有弹幕字体
            for _, dm in ipairs(activeDanmakus) do
                updateFontStyle(dm.text)
                dm.frame:SetSize(dm.text:GetStringWidth() or newFontSize * 5, newFontSize + 10)
            end
            -- 重排位置
            repositionDanmakus()
            print(string.format("字体大小已设置为: %d 号 | Font size set to: %d", newFontSize, newFontSize))
        else
            print(string.format("当前字体: %d 号 | 使用 /danmaku fontsize 8-40 调整 | Current font size: %d | Use /danmaku fontsize 8-40 to adjust", config.fontSize, config.fontSize))
        end

    elseif string.find(cmd, "^lifetime") then
        -- 设置显示时长
        local newLifetime = tonumber(string.match(cmd, "lifetime%s+(%d+)"))
        if newLifetime and newLifetime >= 1 and newLifetime <= 60 then
            config.lifetime = newLifetime
            print(string.format("弹幕显示时长已设置为: %d 秒 | Danmaku lifetime set to: %d seconds", newLifetime, newLifetime))
        else
            print(string.format("当前显示时长: %d 秒 | 使用 /danmaku lifetime 1-60 调整 | Current lifetime: %d sec | Use /danmaku lifetime 1-60 to adjust", config.lifetime, config.lifetime))
        end

    elseif string.find(cmd, "^outline") then
        -- 设置字体轮廓
        local newOutline = string.match(cmd, "outline%s+(%a+)")
        local validOutlines = {
            ["none"] = "NONE",
            ["outline"] = "OUTLINE",
            ["thickoutline"] = "THICKOUTLINE"
        }
        if newOutline and validOutlines[newOutline] then
            config.fontOutline = validOutlines[newOutline]
            -- 刷新现有弹幕轮廓
            for _, dm in ipairs(activeDanmakus) do
                updateFontStyle(dm.text)
            end
            print(string.format("字体轮廓已设置为: %s | Font outline set to: %s", config.fontOutline, config.fontOutline))
        else
            print(string.format("当前轮廓: %s | 使用 /danmaku outline none/outline/thickoutline 调整 | Current outline: %s | Use /danmaku outline none/outline/thickoutline to adjust", config.fontOutline, config.fontOutline))
        end

    elseif string.find(cmd, "^shadow") then
        -- 切换字体阴影
        local shadowSwitch = string.match(cmd, "shadow%s+(%a+)")
        if shadowSwitch == "on" then
            config.fontShadow = true
            config.shadowOffsetX = 1
            config.shadowOffsetY = -1
        elseif shadowSwitch == "off" then
            config.fontShadow = false
        else
            local statusCN = config.fontShadow and "开启" or "关闭"
            local statusEN = config.fontShadow and "On" or "Off"
            print(string.format("当前阴影: %s | 使用 /danmaku shadow on/off 切换 | Current shadow: %s | Use /danmaku shadow on/off to toggle", statusCN, statusEN))
            return
        end
        -- 刷新现有弹幕阴影
        for _, dm in ipairs(activeDanmakus) do
            updateFontStyle(dm.text)
        end
        local statusCN = config.fontShadow and "开启" or "关闭"
        local statusEN = config.fontShadow and "enabled" or "disabled"
        print(string.format("字体阴影已%s | Font shadow %s", statusCN, statusEN))
        
    elseif string.find(cmd, "^max") then
        -- 设置最大弹幕数
        local newMax = tonumber(string.match(cmd, "max%s+(%d+)"))
        if newMax and newMax >= 1 and newMax <= 50 then
            config.maxDanmaku = newMax
            -- 超过新最大值时，立即移除多余的旧弹幕
            while #activeDanmakus > newMax do
                local oldestDm = table.remove(activeDanmakus, 1)
                oldestDm.frame:Hide()
                table.insert(danmakuPool, oldestDm)
            end
            -- 重排剩余弹幕
            repositionDanmakus()
            print(string.format("最大显示弹幕数已设置为: %d 条 | Max danmaku count set to: %d", newMax, newMax))
        else
            print(string.format("当前最大弹幕数: %d 条 | 使用 /danmaku max 1-50 调整 | Current max count: %d | Use /danmaku max 1-50 to adjust", config.maxDanmaku, config.maxDanmaku))
        end
        
    elseif string.find(cmd, "^strata") then
        -- 设置显示层级
        local strataPart, levelPart = string.match(cmd, "^strata%s+(%a+)%s*(%d*)$")
        local levelNum = tonumber(levelPart)
        
        -- 设置层级等级
        if string.find(cmd, "^strata level") then
            if levelNum and levelNum >= 1 and levelNum <= 100 then
                config.frameLevel = levelNum
                ChatDanmaku.mainFrame:SetFrameLevel(config.frameLevel)
                -- 更新所有活跃弹幕的层级等级
                for _, dm in ipairs(activeDanmakus) do
                    dm.frame:SetFrameLevel(config.frameLevel)
                end
                print(string.format("弹幕层级等级已设置为: %d (同strata内优先级，数值越大越靠前) | Danmaku frame level set to: %d (higher = more front in same strata)", config.frameLevel, config.frameLevel))
            else
                print(string.format("当前层级等级: %d | 使用 /danmaku strata level 数字(1-100) 调整 | Current frame level: %d | Use /danmaku strata level [1-100] to adjust", config.frameLevel, config.frameLevel))
            end
        else
            -- 设置大层级
            local validStratas = {
                ["background"] = "BACKGROUND",
                ["low"] = "LOW",
                ["medium"] = "MEDIUM",
                ["high"] = "HIGH",
                ["dialog"] = "DIALOG",
                ["fullscreen"] = "FULLSCREEN",
                ["fullscreen_dialog"] = "FULLSCREEN_DIALOG",
                ["tooltip"] = "TOOLTIP"
            }
            if strataPart and validStratas[strataPart] then
                config.frameStrata = validStratas[strataPart]
                ChatDanmaku.mainFrame:SetFrameStrata(config.frameStrata)
                -- 更新所有活跃弹幕的层级
                for _, dm in ipairs(activeDanmakus) do
                    dm.frame:SetFrameStrata(config.frameStrata)
                end
                print(string.format("弹幕显示层级已设置为: %s (当前层级等级：%d) | Danmaku frame strata set to: %s (current frame level: %d)", config.frameStrata, config.frameLevel, config.frameStrata, config.frameLevel))
            else
                print(string.format("当前层级: %s (层级等级：%d) | Current strata: %s (frame level: %d)", config.frameStrata, config.frameLevel, config.frameStrata, config.frameLevel))
                print("使用 /danmaku strata [background/low/medium/high/dialog/fullscreen/fullscreen_dialog/tooltip] 调整大层级 | Use /danmaku strata [strata_name] to adjust main strata")
                print("使用 /danmaku strata level [1-100] 调整同层级内的优先级 | Use /danmaku strata level [1-100] to adjust priority in same strata")
            end
        end

    elseif string.find(cmd, "^lang") then
        -- 切换前缀语言模式
        local langCmd = string.match(cmd, "^lang%s+(%a+)")
        local validLangs = {
            ["auto"] = "自动判断",
            ["cn"] = "强制中文",
            ["en"] = "强制英文"
        }
        
        if langCmd and validLangs[langCmd] then
            config.prefixLang = langCmd
            local autoLangTip = ""
            if langCmd == "auto" then
                local autoLang = getAutoPrefixLang()
                autoLangTip = autoLang == "cn" and "（当前识别为中文）" or "（当前识别为英文）"
            end
            print(string.format("前缀语言已设置为: %s %s | Prefix language set to: %s %s", validLangs[langCmd], autoLangTip, langCmd, autoLangTip))
        else
            local currentLangCN = validLangs[config.prefixLang] or "未知"
            local autoLangTip = ""
            if config.prefixLang == "auto" then
                local autoLang = getAutoPrefixLang()
                autoLangTip = autoLang == "cn" and "（当前识别为中文）" or "（当前识别为英文）"
            end
            print(string.format("当前前缀语言模式: %s %s | Current prefix lang mode: %s %s", currentLangCN, autoLangTip, config.prefixLang, autoLangTip))
            print("使用 /danmaku lang auto - 自动判断语言（根据游戏客户端）| Use /danmaku lang auto - Auto detect language (by game client)")
            print("使用 /danmaku lang cn   - 强制显示中文前缀 | Use /danmaku lang cn   - Force Chinese prefix")
            print("使用 /danmaku lang en   - 强制显示英文前缀 | Use /danmaku lang en   - Force English prefix")
        end

    -- 切换是否显示自己的消息
    elseif string.find(cmd, "^self") then
        local selfSwitch = string.match(cmd, "^self%s+(%a+)")
        if selfSwitch == "on" then
            config.monitorSelfChat = true
        elseif selfSwitch == "off" then
            config.monitorSelfChat = false
        else
            local statusCN = config.monitorSelfChat and "开启" or "关闭"
            local statusEN = config.monitorSelfChat and "On" or "Off"
            print(string.format("当前显示自己消息: %s | Show own messages: %s", statusCN, statusEN))
            return
        end
        local statusCN = config.monitorSelfChat and "开启" or "关闭"
        local statusEN = config.monitorSelfChat and "enabled" or "disabled"
        print(string.format("显示自己消息已%s | Show own messages %s", statusCN, statusEN))

    -- 频道开关命令
    elseif string.find(cmd, "^channel") then
        local channelName, switch = string.match(cmd, "^channel%s+(%a+)%s*(%a*)")
        -- 仅输入 /danmaku channel 时显示所有频道状态
        if not channelName then
            showChannelList()
            return
        end
        
        -- 切换指定频道开关
        local chatType = string.upper(channelName)
        if config.chatChannels[chatType] then
            if switch == "on" then
                config.chatChannels[chatType].enable = true
                -- 注册对应事件
                for event, ct in pairs(eventToChatType) do
                    if ct == chatType then
                        frame:RegisterEvent(event)
                    end
                end
                local name = GetLocale():find("zh") and config.chatChannels[chatType].nameCN or config.chatChannels[chatType].nameEN
                print(string.format("|cff00ff00已开启 %s 频道弹幕 | Enabled %s channel danmaku|r", name, chatType))
            elseif switch == "off" then
                config.chatChannels[chatType].enable = false
                -- 取消注册对应事件
                for event, ct in pairs(eventToChatType) do
                    if ct == chatType then
                        frame:UnregisterEvent(event)
                    end
                end
                local name = GetLocale():find("zh") and config.chatChannels[chatType].nameCN or config.chatChannels[chatType].nameEN
                print(string.format("|cffff0000已关闭 %s 频道弹幕 | Disabled %s channel danmaku|r", name, chatType))
            else
                print("|cffff0000命令格式错误！请指定 on/off，示例：/danmaku channel GUILD on|r")
            end
        else
            print(string.format("|cffff0000未找到频道类型「%s」！输入 /danmaku channel 查看所有频道|r", channelName))
        end

    -- 过滤关键字管理命令
    elseif string.find(cmd, "^filter") then
        local op, keyword = string.match(cmd, "^filter%s+(%a+)%s+(.*)$")
        
        -- 仅输入 /danmaku filter 时显示当前过滤列表
        if not op then
            showFilterList()
            return
        end
        
        -- 增加过滤关键字
        if op == "add" and keyword and keyword ~= "" then
            local exists = false
            for _, k in ipairs(config.filterKeywords) do
                if k == keyword then
                    exists = true
                    break
                end
            end
            
            if exists then
                print(string.format("|cffff0000过滤关键字「%s」已存在！|r", keyword))
            else
                table.insert(config.filterKeywords, keyword)
                print(string.format("|cff00ff00已添加过滤关键字：%s|r", keyword))
                showFilterList()
            end
        -- 删除过滤关键字
        elseif op == "del" and keyword and keyword ~= "" then
            local removed = false
            for i = #config.filterKeywords, 1, -1 do
                if config.filterKeywords[i] == keyword then
                    table.remove(config.filterKeywords, i)
                    removed = true
                    break
                end
            end
            
            if removed then
                print(string.format("|cff00ff00已删除过滤关键字：%s|r", keyword))
                showFilterList()
            else
                print(string.format("|cffff0000未找到过滤关键字「%s」！|r", keyword))
            end
        else
            print("|cffff0000命令格式错误！|r")
            print("|cff00ff00正确用法：|r")
            print("|cff00ff00/danmaku filter          - 查看当前过滤列表|r")
            print("|cff00ff00/danmaku filter add 关键字  - 添加过滤关键字|r")
            print("|cff00ff00/danmaku filter del 关键字  - 删除过滤关键字|r")
        end

    -- ==================== 新增：Y轴偏移命令 ====================
    elseif string.find(cmd, "^y") then
        local newY = tonumber(string.match(cmd, "y%s+(-?%d+)"))
        if newY then
            config.yOffset = newY
            repositionDanmakus()
            print(string.format("|cff00ff00弹幕顶部Y轴偏移已设置为: %d | 负数=向下，正数=向上 | Danmaku Y offset set to: %d|r", newY, newY))
        else
            print(string.format("|cff00ff00当前Y轴偏移: %d | 使用 /danmaku y 数字 调整 | Current Y offset: %d|r", config.yOffset, config.yOffset))
            print("|cff00ff00示例：/danmaku y -50 （向下移动） /danmaku y 0 （贴顶）|r")
        end

    else
        -- 完整帮助信息（已移除职业颜色相关内容）
        print("=====================================")
        print("|cff00ff00/danmaku test|r         - 测试前缀+位置+职业颜色 | Test prefix & position & class color")
        print("|cff00ff00/danmaku clear|r        - 清空所有弹幕 | Clear all danmaku")
        print("|cff00ff00/danmaku y 数字|r       - 修改弹幕顶部Y轴距离（默认-25）| Set Y offset")
        print("|cff00ff00/danmaku channel|r      - 查看所有频道开关状态 | Show all channel status")
        print("|cff00ff00/danmaku channel [类型] [on/off]|r - 切换频道开关 | Toggle channel switch")
        print(" 示例：|cff00ff00/danmaku channel GUILD on|r | Example: /danmaku channel GUILD on")
        print("|cff00ff00/danmaku speed [数字]|r - 设置滚动速度 (当前: " .. config.speed .. ") | Set speed (current: " .. config.speed .. ")")
        print("|cff00ff00/danmaku fontsize [8-40]|r - 设置字体大小 (当前: " .. config.fontSize .. ") | Set font size (current: " .. config.fontSize .. ")")
        print("|cff00ff00/danmaku lifetime [1-60]|r - 设置显示时长 (当前: " .. config.lifetime .. "秒) | Set lifetime (current: " .. config.lifetime .. "s)")
        print("|cff00ff00/danmaku outline [none/outline/thickoutline]|r - 设置字体轮廓 (当前: " .. config.fontOutline .. ") | Set outline (current: " .. config.fontOutline .. ")")
        print("|cff00ff00/danmaku shadow [on/off]|r - 切换字体阴影 (当前: " .. (config.fontShadow and "开启/On" or "关闭/Off") .. ") | Toggle shadow (current: " .. (config.fontShadow and "On" or "Off") .. ")")
        print("|cff00ff00/danmaku max [1-50]|r   - 设置最大弹幕数 (当前: " .. config.maxDanmaku .. ") | Set max count (current: " .. config.maxDanmaku .. ")")
        print("|cff00ff00/danmaku strata [层级]|r - 设置显示大层级 (当前: " .. config.frameStrata .. ") | Set frame strata (current: " .. config.frameStrata .. ")")
        print(" 可选值: background/low/medium/high/dialog/fullscreen/fullscreen_dialog/tooltip")
        print("|cff00ff00/danmaku strata level [1-100]|r - 设置同层级内优先级 (当前: " .. config.frameLevel .. ") | Set frame level (current: " .. config.frameLevel .. ")")
        print("|cff00ff00/danmaku lang [auto/cn/en]|r - 设置前缀语言 (当前: " .. config.prefixLang .. ") | Set prefix lang (current: " .. config.prefixLang .. ")")
        print("|cff00ff00/danmaku self [on/off]|r - 切换是否显示自己的消息 (当前: " .. (config.monitorSelfChat and "开启/On" or "关闭/Off") .. ") | Toggle own messages (current: " .. (config.monitorSelfChat and "On" or "Off") .. ")")
        print("|cff00ff00/danmaku filter|r       - 查看当前过滤关键字列表 | Show filter list")
        print("|cff00ff00/danmaku filter add [关键字]|r - 添加过滤关键字 | Add filter keyword")
        print("|cff00ff00/danmaku filter del [关键字]|r - 删除过滤关键字 | Delete filter keyword")
        print("=====================================")
    end
end]]