
-- rChat: core
-- zork, 2016
-- Updated for WoW Midnight (12.0.0) - 2026

-----------------------------
-- Variables
-----------------------------

local A, L = ...

local cfg = {}
cfg.dropshadow = {}
cfg.dropshadow.offset = {1,-2}
cfg.dropshadow.color = {0,0,0,0.25}
cfg.editbox = {}
cfg.editbox.font = {STANDARD_TEXT_FONT, 13, "THINOUTLINE"}
cfg.chat = {}
cfg.chat.font = {STANDARD_TEXT_FONT, 13, "THINOUTLINE"} --{STANDARD_TEXT_FONT, 12, "OUTLINE"}

-----------------------------
-- Copy Window
-----------------------------

local copyFrame = nil

local function CreateCopyFrame()
  if copyFrame then return copyFrame end
  
  local frame = CreateFrame("Frame", "rChatCopyFrame", UIParent, "BasicFrameTemplateWithInset")
  frame:SetSize(600, 400)
  frame:SetPoint("CENTER")
  frame:SetMovable(true)
  frame:EnableMouse(true)
  frame:RegisterForDrag("LeftButton")
  frame:SetScript("OnDragStart", frame.StartMoving)
  frame:SetScript("OnDragStop", frame.StopMovingOrSizing)
  frame:SetFrameStrata("DIALOG")
  frame:Hide()
  
  frame.title = frame:CreateFontString(nil, "OVERLAY")
  frame.title:SetFontObject("GameFontHighlightLarge")
  frame.title:SetPoint("TOP", frame.TitleBg, "TOP", 0, -5)
  frame.title:SetText(L.Strings["CHAT_COPY_WINDOW_TITLE"])
  
  frame.CloseButton:SetScript("OnClick", function() frame:Hide() end)
  
  -- Scroll frame for the editbox
  local scrollFrame = CreateFrame("ScrollFrame", nil, frame, "UIPanelScrollFrameTemplate")
  scrollFrame:SetPoint("TOPLEFT", frame, "TOPLEFT", 15, -35)
  scrollFrame:SetPoint("BOTTOMRIGHT", frame, "BOTTOMRIGHT", -35, 70)
  
  -- EditBox for text - now displays colored text that can be selected
  local editBox = CreateFrame("EditBox", nil, scrollFrame)
  editBox:SetMultiLine(true)
  editBox:SetAutoFocus(false)
  editBox:SetFontObject("ChatFontNormal")
  editBox:SetWidth(550)
  editBox:SetHeight(1000)
  editBox:SetScript("OnEscapePressed", function() frame:Hide() end)
  scrollFrame:SetScrollChild(editBox)
  frame.editBox = editBox
  
  -- "Copy All" button - selects all text
  local copyAllBtn = CreateFrame("Button", nil, frame, "UIPanelButtonTemplate")
  copyAllBtn:SetSize(120, 22)
  copyAllBtn:SetPoint("BOTTOMRIGHT", frame, "BOTTOMRIGHT", -15, 42)
  copyAllBtn:SetText(L.Strings["CHAT_COPY_ALL_BUTTON"])
  copyAllBtn:SetScript("OnClick", function(self)
    -- Select all text in editbox
    frame.editBox:SetFocus()
    frame.editBox:HighlightText()
    -- Show success message
    print("|cff33ff99rChat:|r " .. L.Strings["CHAT_COPIED_SUCCESS"])
  end)
  frame.copyAllBtn = copyAllBtn
  
  -- Instruction text
  local instruction = frame:CreateFontString(nil, "OVERLAY", "GameFontHighlight")
  instruction:SetPoint("BOTTOMLEFT", frame, "BOTTOMLEFT", 15, 10)
  instruction:SetText(L.Strings["CHAT_COPY_INSTRUCTION"])
  
  copyFrame = frame
  return frame
end

-- Show copy window with text
local function ShowCopyWindow(text)
  local frame = CreateCopyFrame()
  
  -- Set text in editbox with color codes (EditBox will render them as colored text)
  frame.editBox:SetText(text)
  
  frame:Show()
end

-----------------------------
-- Functions
-----------------------------

--SkinChat
local function SkinChat(self)
  if not self then return end
  local name = self:GetName()
  
  -- Font settings
  self:SetFont(unpack(cfg.chat.font))
  self:SetShadowOffset(unpack(cfg.dropshadow.offset))
  self:SetShadowColor(unpack(cfg.dropshadow.color))
  
  --chat fading
  self:SetFading(true)
  
  -- Set fade time from settings
  local fadeTime = 20 -- default
  if rChatDB and rChatDB.chat and rChatDB.chat.chatFadeTime then
    fadeTime = rChatDB.chat.chatFadeTime
  end
  self:SetTimeVisible(fadeTime)
  self:SetFadeDuration(1) -- 1 second fade animation
  
  --hide button frame
  local bf = _G[name.."ButtonFrame"]
  if bf then
    bf:HookScript("OnShow", bf.Hide)
    bf:Hide()
  end
  
  --modernize chat tab - remove textures, white text only
  local tab = _G[name.."Tab"]
  if tab then
    -- COMPLETE texture removal for WoW 12.0
    -- Kill all textures by setting them to nil and alpha 0
    local function KillTexture(texture)
      if texture then
        texture:SetTexture(nil)
        texture:SetAlpha(0)
        texture:Hide()
      end
    end
    
    -- Old naming convention (pre-12.0)
    local oldTextures = {
      "Left", "Middle", "Right",
      "SelectedLeft", "SelectedMiddle", "SelectedRight",
      "HighlightLeft", "HighlightMiddle", "HighlightRight",
      "ActiveLeft", "ActiveMiddle", "ActiveRight",
    }
    for _, texName in pairs(oldTextures) do
      KillTexture(_G[name.."Tab"..texName])
    end
    
    -- New naming convention (12.0+)
    KillTexture(tab.leftTexture)
    KillTexture(tab.middleTexture)
    KillTexture(tab.rightTexture)
    KillTexture(tab.leftSelectedTexture)
    KillTexture(tab.middleSelectedTexture)
    KillTexture(tab.rightSelectedTexture)
    KillTexture(tab.leftHighlightTexture)
    KillTexture(tab.middleHighlightTexture)
    KillTexture(tab.rightHighlightTexture)
    KillTexture(tab.leftDisabledTexture)
    KillTexture(tab.middleDisabledTexture)
    KillTexture(tab.rightDisabledTexture)
    
    -- Glow textures
    KillTexture(tab.glow)
    KillTexture(tab.leftGlow)
    KillTexture(tab.middleGlow)
    KillTexture(tab.rightGlow)
    
    -- Background textures (WoW 12.0 specific)
    if tab.Background then
      KillTexture(tab.Background)
    end
    
    -- Try to find and kill ANY texture regions on the tab
    for i = 1, tab:GetNumRegions() do
      local region = select(i, tab:GetRegions())
      if region and region:GetObjectType() == "Texture" then
        local textureName = region:GetName()
        -- Don't kill the conversation icon or text
        if not textureName or not textureName:match("Conversation") then
          KillTexture(region)
        end
      end
    end
    
    -- Style the tab text - white color, clean font
    local tabText = tab:GetFontString() or _G[name.."TabText"] or tab.Text
    if tabText then
      tabText:SetFont(STANDARD_TEXT_FONT, 12, "OUTLINE")
      tabText:SetTextColor(1, 1, 1, 1)  -- White
      tabText:SetShadowOffset(1, -1)
      tabText:SetShadowColor(0, 0, 0, 0.8)
    end
    
    -- Hook to maintain white color
    tab:HookScript("OnShow", function(self)
      local text = self:GetFontString() or self.Text
      if text then
        text:SetTextColor(1, 1, 1, 1)
      end
    end)
    
    -- Highlight on mouse over
    tab:HookScript("OnEnter", function(self)
      local text = self:GetFontString() or self.Text
      if text then
        text:SetTextColor(0.9, 0.9, 0.5, 1)  -- Slight highlight on hover
      end
    end)
    
    tab:HookScript("OnLeave", function(self)
      local text = self:GetFontString() or self.Text
      if text then
        text:SetTextColor(1, 1, 1, 1)  -- Back to white
      end
    end)
  end
  
  --editbox
  local eb = _G[name.."EditBox"]
  if eb then
    eb:SetAltArrowKeyMode(false)
    --textures
    local left = _G[name.."EditBoxLeft"]
    local mid = _G[name.."EditBoxMid"]
    local right = _G[name.."EditBoxRight"]
    if left then left:Hide() end
    if mid then mid:Hide() end
    if right then right:Hide() end
    --reposition
    eb:ClearAllPoints()
    
    -- Get editbox position from settings
    local editboxPos = "top" -- default
    if rChatDB and rChatDB.chat and rChatDB.chat.editboxPosition then
      editboxPos = rChatDB.chat.editboxPosition
    end
    
    if editboxPos == "bottom" then
      -- Position at bottom
      eb:SetPoint("TOP", self, "BOTTOM", 0, -3)
      eb:SetPoint("LEFT", self, -5, 0)
      eb:SetPoint("RIGHT", self, 10, 0)
    else
      -- Position at top (default)
      if name == "ChatFrame2" then
        eb:SetPoint("BOTTOM", self, "TOP", 0, 22+24)
      else
        eb:SetPoint("BOTTOM", self, "TOP", 0, 22)
      end
      eb:SetPoint("LEFT", self, -5, 0)
      eb:SetPoint("RIGHT", self, 10, 0)
    end
  end
end

local function UpdateBackgroundAnchors(self)
  --fix weird combat log
  self:SetClampRectInsets(0, 0, 0, 0)
end

-- Function to update editbox positions for all chat frames
function L:UpdateEditBoxPositions()
  local editboxPos = "top" -- default
  if rChatDB and rChatDB.chat and rChatDB.chat.editboxPosition then
    editboxPos = rChatDB.chat.editboxPosition
  end
  
  for i = 1, NUM_CHAT_WINDOWS do
    local chatframe = _G["ChatFrame"..i]
    if chatframe then
      local name = chatframe:GetName()
      local eb = _G[name.."EditBox"]
      if eb then
        eb:ClearAllPoints()
        
        if editboxPos == "bottom" then
          -- Position at bottom
          eb:SetPoint("TOP", chatframe, "BOTTOM", 0, -3)
          eb:SetPoint("LEFT", chatframe, -5, 0)
          eb:SetPoint("RIGHT", chatframe, 10, 0)
        else
          -- Position at top (default)
          if name == "ChatFrame2" then
            eb:SetPoint("BOTTOM", chatframe, "TOP", 0, 22+24)
          else
            eb:SetPoint("BOTTOM", chatframe, "TOP", 0, 22)
          end
          eb:SetPoint("LEFT", chatframe, -5, 0)
          eb:SetPoint("RIGHT", chatframe, 10, 0)
        end
      end
    end
  end
end

-- Function to update chat fade time for all chat frames
function L:UpdateChatFadeTime()
  local fadeTime = 20 -- default
  if rChatDB and rChatDB.chat and rChatDB.chat.chatFadeTime then
    fadeTime = rChatDB.chat.chatFadeTime
  end
  
  for i = 1, NUM_CHAT_WINDOWS do
    local chatframe = _G["ChatFrame"..i]
    if chatframe then
      chatframe:SetTimeVisible(fadeTime)
      chatframe:SetFadeDuration(1)
    end
  end
end

-- Function to get all chat text for the copy window.
-- Uses issecretvalue() (same approach as Prat) to skip tainted entries safely.
local function GetChatText(chatFrame)
  local lines = {}
  local numMessages = chatFrame:GetNumMessages()

  for i = 1, numMessages do
    local ok, msg = pcall(chatFrame.GetMessageInfo, chatFrame, i)
    if ok and msg ~= nil then
      if issecretvalue and issecretvalue(msg) then
        -- tainted: skip silently
      else
        lines[#lines + 1] = msg
      end
    end
  end

  if #lines == 0 then return "" end
  return table.concat(lines, "\n")
end

-- Create chat copy button for a frame
local function CreateChatCopyButton(chatFrame)
  if not chatFrame or chatFrame.rChatCopyButton then return end
  
  local button = CreateFrame("Button", nil, chatFrame)
  button:SetSize(18, 18)
  button:SetPoint("BOTTOMRIGHT", chatFrame, "BOTTOMRIGHT", -2, 2)
  
  -- Create icon texture (using custom copy icon)
  local icon = button:CreateTexture(nil, "ARTWORK")
  icon:SetAllPoints()
  icon:SetTexture("Interface\\AddOns\\rChat\\core\\copy-icon")
  icon:SetAlpha(0.15) -- Very subtle, almost invisible
  
  -- Highlight texture on hover
  local highlight = button:CreateTexture(nil, "HIGHLIGHT")
  highlight:SetAllPoints()
  highlight:SetTexture("Interface\\AddOns\\rChat\\core\\copy-icon")
  highlight:SetAlpha(0)
  
  -- Hover effects
  button:SetScript("OnEnter", function(self)
    icon:SetAlpha(1.0) -- Fully visible on hover
    GameTooltip:SetOwner(self, "ANCHOR_RIGHT")
    GameTooltip:SetText(L.Strings["CHAT_COPY_BUTTON_TOOLTIP"])
    GameTooltip:Show()
  end)
  
  button:SetScript("OnLeave", function(self)
    icon:SetAlpha(0.15) -- Back to almost invisible
    GameTooltip:Hide()
  end)
  
  -- Click handler
  button:SetScript("OnClick", function(self)
    local chatText = GetChatText(chatFrame)
    if chatText and #chatText > 0 then
      ShowCopyWindow(chatText)
    else
      print("|cff33ff99rChat:|r No chat messages to copy.")
    end
  end)
  
  chatFrame.rChatCopyButton = button
  
  -- Hide if setting is disabled
  if not (rChatDB and rChatDB.chat and rChatDB.chat.enableChatCopyButton) then
    button:Hide()
  end
end

-- Update all chat copy buttons visibility
function L:UpdateChatCopyButtons()
  local enabled = rChatDB and rChatDB.chat and rChatDB.chat.enableChatCopyButton
  
  for i = 1, NUM_CHAT_WINDOWS do
    local chatframe = _G["ChatFrame"..i]
    if chatframe then
      if enabled then
        CreateChatCopyButton(chatframe)
        if chatframe.rChatCopyButton then
          chatframe.rChatCopyButton:Show()
        end
      else
        if chatframe.rChatCopyButton then
          chatframe.rChatCopyButton:Hide()
        end
      end
    end
  end
end

--OpenTemporaryWindow
local function OpenTemporaryWindow()
  for _, name in next, CHAT_FRAMES do
    local frame = _G[name]
    if (frame and frame.isTemporary) then
      SkinChat(frame)
    end
  end
end

--OnMouseScroll
local function OnMouseScroll(self,dir)
  if(dir > 0) then
    if(IsShiftKeyDown()) then self:ScrollToTop() else self:ScrollUp() end
  else
    if(IsShiftKeyDown()) then self:ScrollToBottom() else self:ScrollDown() end
  end
end

--we hook SetItemRef instead of replacing it, to avoid ADDON_ACTION_BLOCKED
--errors when Blizzard's handler triggers protected functions (e.g. SetPassThroughButtons
--on map pins when opening quest/worldmap links).
--
--hooksecurefunc is a POST-hook: Blizzard's original always runs first in its
--own secure context (no taint). rChat then handles its two custom cases:
--  1. "url:" links  - Blizzard ignores unknown link types, so we show our UI
--  2. Alt+player    - Blizzard shows the inspect/trade menu; we ALSO invite.
--                     Both actions happen, which is acceptable behaviour.
hooksecurefunc("SetItemRef", function(link, ...)
  local linkType, linkData = link:match("(%a+):(.+)")
  if not linkType then return end

  -- Handle URL links: Blizzard does nothing with "url:" type, we show copy UI
  if linkType == "url" then
    if rChatDB and rChatDB.chat and rChatDB.chat.enableURLCopy then
      ShowCopyWindow(linkData)
    else
      local eb = LAST_ACTIVE_CHAT_EDIT_BOX or ChatFrame1EditBox
      if eb then
        eb:SetText(linkData)
        eb:SetFocus()
        eb:HighlightText()
        if not eb:IsShown() then eb:Show() end
      end
    end
    return
  end

  -- Handle Alt+Click player invite (in addition to Blizzard's default action)
  if IsAltKeyDown() and linkType == "player" then
    local playerName = linkData:match("([^:]+)")
    if playerName then
      pcall(C_PartyInfo.InviteUnit, playerName)
    end
    return
  end
end)

--AddMessage
local function AddMessage(self, text, ...)
  -- Guard against tainted/secret strings (WoW secure execution environment).
  -- type(text) == "string" is true even for secret strings, so we use pcall
  -- to safely attempt string operations. If tainted, we pass through unmodified.
  if type(text) ~= "string" then
    return self.DefaultAddMessage(self, text, ...)
  end

  local ok, result = pcall(function()
    local t = text

    -- Add timestamp if enabled
    if rChatDB and rChatDB.chat and rChatDB.chat.showTimestamp then
      local timestamp = date("%H:%M")
      t = "|cff888888[" .. timestamp .. "]|r " .. t
    end

    --channel replace (Trade and such)
    t = t:gsub('|h%[(%d+)%. .-%]|h', '|h%1.|h')
    --url search
    t = t:gsub('([wWhH][wWtT][wWtT][%.pP]%S+[^%p%s])', '|cffffffff|Hurl:%1|h[%1]|h|r')
    return t
  end)

  if ok and type(result) == "string" then
    text = result
  end
  -- If pcall failed (tainted secret string), text remains unchanged and passes through.

  return self.DefaultAddMessage(self, text, ...)
end

-----------------------------
-- Stuff
-----------------------------

--editbox font
ChatFontNormal:SetFont(unpack(cfg.editbox.font))
ChatFontNormal:SetShadowOffset(unpack(cfg.dropshadow.offset))
ChatFontNormal:SetShadowColor(unpack(cfg.dropshadow.color))

--font size
CHAT_FONT_HEIGHTS = {10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20}

--tabs
CHAT_TAB_HIDE_DELAY = 1
CHAT_FRAME_TAB_NORMAL_MOUSEOVER_ALPHA = 1
CHAT_FRAME_TAB_NORMAL_NOMOUSE_ALPHA = 0
CHAT_FRAME_TAB_SELECTED_MOUSEOVER_ALPHA = 1
CHAT_FRAME_TAB_SELECTED_NOMOUSE_ALPHA = 0
CHAT_FRAME_TAB_ALERTING_MOUSEOVER_ALPHA = 1
CHAT_FRAME_TAB_ALERTING_NOMOUSE_ALPHA = 1

-- Function to update tab visibility settings
local function UpdateTabVisibility()
  if rChatDB and rChatDB.chat and rChatDB.chat.alwaysShowTabs then
    -- Keep tabs always visible
    CHAT_FRAME_TAB_NORMAL_NOMOUSE_ALPHA = 1
    CHAT_FRAME_TAB_SELECTED_NOMOUSE_ALPHA = 1
  else
    -- Default: tabs fade out
    CHAT_FRAME_TAB_NORMAL_NOMOUSE_ALPHA = 0
    CHAT_FRAME_TAB_SELECTED_NOMOUSE_ALPHA = 0
  end
  
  -- Apply to all chat frames immediately
  for i = 1, NUM_CHAT_WINDOWS do
    local chatFrame = _G["ChatFrame"..i]
    if chatFrame then
      FCFTab_UpdateAlpha(chatFrame)
    end
  end
end

--channels
CHAT_WHISPER_GET              = "From %s "
CHAT_WHISPER_INFORM_GET       = "To %s "
CHAT_BN_WHISPER_GET           = "From %s "
CHAT_BN_WHISPER_INFORM_GET    = "To %s "
CHAT_YELL_GET                 = "%s "
CHAT_SAY_GET                  = "%s "
CHAT_BATTLEGROUND_GET         = "|Hchannel:Battleground|hBG.|h %s: "
CHAT_BATTLEGROUND_LEADER_GET  = "|Hchannel:Battleground|hBGL.|h %s: "
CHAT_GUILD_GET                = "|Hchannel:Guild|hG.|h %s: "
CHAT_OFFICER_GET              = "|Hchannel:Officer|hGO.|h %s: "
CHAT_PARTY_GET                = "|Hchannel:Party|hP.|h %s: "
CHAT_PARTY_LEADER_GET         = "|Hchannel:Party|hPL.|h %s: "
CHAT_PARTY_GUIDE_GET          = "|Hchannel:Party|hPG.|h %s: "
CHAT_RAID_GET                 = "|Hchannel:Raid|hR.|h %s: "
CHAT_RAID_LEADER_GET          = "|Hchannel:Raid|hRL.|h %s: "
CHAT_RAID_WARNING_GET         = "|Hchannel:RaidWarning|hRW.|h %s: "
CHAT_INSTANCE_CHAT_GET        = "|Hchannel:Battleground|hI.|h %s: "
CHAT_INSTANCE_CHAT_LEADER_GET = "|Hchannel:Battleground|hIL.|h %s: "
--CHAT_MONSTER_PARTY_GET       = CHAT_PARTY_GET
--CHAT_MONSTER_SAY_GET         = CHAT_SAY_GET
--CHAT_MONSTER_WHISPER_GET     = CHAT_WHISPER_GET
--CHAT_MONSTER_YELL_GET        = CHAT_YELL_GET
CHAT_FLAG_AFK = "<AFK> "
CHAT_FLAG_DND = "<DND> "
CHAT_FLAG_GM = "<[GM]> "

-- Chat message filter to add player levels
local function AddPlayerLevelFilter(self, event, message, sender, ...)
  if not (rChatDB and rChatDB.chat and rChatDB.chat.showPlayerLevel) then
    return false
  end
  
  -- Only process if we have a valid sender
  if not sender or sender == "" then
    return false
  end
  
  -- Extract base name (without realm)
  local playerName = sender:match("^([^%-]+)")
  if not playerName then
    return false
  end
  
  -- Try to get level information
  local level = nil
  
  -- Try different methods to get level
  if UnitExists(playerName) then
    level = UnitLevel(playerName)
  elseif UnitExists(sender) then
    level = UnitLevel(sender)
  end
  
  -- If we got a valid level, modify the message to include it
  if level and level > 0 then
    -- Add level at the beginning of the message in gray color
    local levelTag = "|cff888888[" .. level .. "]|r "
    message = levelTag .. message
    return false, message, sender, ...
  end
  
  return false
end

-- Register the filter for relevant chat events
local function RegisterLevelFilters()
  if not (rChatDB and rChatDB.chat and rChatDB.chat.showPlayerLevel) then
    return
  end
  
  local chatEvents = {
    "CHAT_MSG_SAY",
    "CHAT_MSG_YELL",
    "CHAT_MSG_PARTY",
    "CHAT_MSG_PARTY_LEADER",
    "CHAT_MSG_RAID",
    "CHAT_MSG_RAID_LEADER",
    "CHAT_MSG_GUILD",
    "CHAT_MSG_OFFICER",
    "CHAT_MSG_INSTANCE_CHAT",
    "CHAT_MSG_INSTANCE_CHAT_LEADER",
  }
  
  for i = 1, NUM_CHAT_WINDOWS do
    local frame = _G["ChatFrame" .. i]
    if frame then
      for _, eventName in ipairs(chatEvents) do
        ChatFrame_RemoveMessageEventFilter(eventName, AddPlayerLevelFilter)
        ChatFrame_AddMessageEventFilter(eventName, AddPlayerLevelFilter)
      end
    end
  end
end

--remove the annoying guild loot messages by replacing them with the original ones
YOU_LOOT_MONEY_GUILD = YOU_LOOT_MONEY
LOOT_MONEY_SPLIT_GUILD = LOOT_MONEY_SPLIT

--don't cut the toastframe
if BNToastFrame then
  BNToastFrame:SetClampedToScreen(true)
  BNToastFrame:SetClampRectInsets(-15,15,15,-15)
end

--ChatFrameMenuButton
if ChatFrameMenuButton then
  ChatFrameMenuButton:HookScript("OnShow", ChatFrameMenuButton.Hide)
  ChatFrameMenuButton:Hide()
end

--ChatFrameChannelButton
if ChatFrameChannelButton then
  ChatFrameChannelButton:HookScript("OnShow", ChatFrameChannelButton.Hide)
  ChatFrameChannelButton:Hide()
end

--ChatFrameToggleVoiceDeafenButton
if ChatFrameToggleVoiceDeafenButton then
  ChatFrameToggleVoiceDeafenButton:HookScript("OnShow", ChatFrameToggleVoiceDeafenButton.Hide)
  ChatFrameToggleVoiceDeafenButton:Hide()
end

--ChatFrameToggleVoiceMuteButton
if ChatFrameToggleVoiceMuteButton then
  ChatFrameToggleVoiceMuteButton:HookScript("OnShow", ChatFrameToggleVoiceMuteButton.Hide)
  ChatFrameToggleVoiceMuteButton:Hide()
end

--hide the friend micro button
local button = QuickJoinToastButton or FriendsMicroButton
if button then
  button:HookScript("OnShow", button.Hide)
  button:Hide()
end

--skin chat
for i = 1, NUM_CHAT_WINDOWS do
  local chatframe = _G["ChatFrame"..i]
  if chatframe then
    SkinChat(chatframe)
    --adjust channel display
    if (i ~= 2) then
      chatframe.DefaultAddMessage = chatframe.AddMessage
      chatframe.AddMessage = AddMessage
    end
  end
end

--scroll
FloatingChatFrame_OnMouseScroll = OnMouseScroll

--temporary chat windows
hooksecurefunc("FCF_OpenTemporaryWindow", OpenTemporaryWindow)

--background thingy
hooksecurefunc("FloatingChatFrame_UpdateBackgroundAnchors", UpdateBackgroundAnchors)

-----------------------------
-- Initialize rChat modules
-----------------------------

-- LibDBIcon and Minimap integration
local LDB = LibStub:GetLibrary("LibDataBroker-1.1", true)
local LDBIcon = LibStub:GetLibrary("LibDBIcon-1.0", true)

-- Create LDB data object
if LDB then
    local rChatLDB = LDB:NewDataObject("rChat", {
        type = "launcher",
        text = "rChat",
        icon = "Interface\\AddOns\\rChat\\core\\logo",
        OnClick = function(clickedFrame, button)
            if button == "LeftButton" then
                -- Open custom settings window directly
                L:ShowConfig()
            elseif button == "RightButton" then
                -- Toggle Chicchai
                local enabled = L:GetConfig("chicchai", "enabled")
                L:SetConfig("chicchai", "enabled", not enabled)
                print("|cff33ff99rChat:|r Chicchai", not enabled and "|cff00ff00" .. L.Strings["CHICCHAI_ENABLED"] .. "|r" or "|cffff0000" .. L.Strings["CHICCHAI_DISABLED"] .. "|r")
                ReloadUI()
            end
        end,
        OnTooltipShow = function(tooltip)
            tooltip:AddLine(L.Strings["MINIMAP_TOOLTIP"])
        end,
    })
end

-- Function to update minimap icon visibility
function L:UpdateMinimapIcon()
    if LDBIcon and rChatDB and rChatDB.minimap then
        if rChatDB.minimap.hide then
            LDBIcon:Hide("rChat")
        else
            LDBIcon:Show("rChat")
        end
    end
end

-- Initialize minimap icon
local function InitMinimapIcon()
    if LDBIcon then
        -- Register with LibDBIcon
        LDBIcon:Register("rChat", rChatLDB or LDB:GetDataObjectByName("rChat"), rChatDB.minimap)
        
        -- Apply initial visibility
        L:UpdateMinimapIcon()
    end
end

-- Create event frame for initialization
local eventFrame = CreateFrame("Frame")
eventFrame:RegisterEvent("PLAYER_LOGIN")
eventFrame:SetScript("OnEvent", function(self, event)
    if event == "PLAYER_LOGIN" then
        -- Initialize config
        L:InitConfig()
        
        -- Initialize minimap icon
        InitMinimapIcon()
        
        -- Register Interface Options panel
        L:RegisterInterfaceOptions()
        
        -- Apply tab visibility settings
        UpdateTabVisibility()
        
        -- Update editbox positions
        C_Timer.After(0.5, function()
            L:UpdateEditBoxPositions()
        end)
        
        -- Create chat copy buttons
        C_Timer.After(0.7, function()
            L:UpdateChatCopyButtons()
        end)
        
        -- Register level display filters if enabled
        C_Timer.After(1, function()
            RegisterLevelFilters()
        end)
        
        -- Initialize Chicchai if enabled
        L:InitChicchai()
        
        -- Unregister event
        self:UnregisterEvent("PLAYER_LOGIN")
    end
end)

-- Blizzard Addon Compartment (TOC)
function rChat_OnAddonCompartmentClick(_, btn)
    if btn == "LeftButton" then
        L:ShowConfig()
    elseif btn == "RightButton" then
        local enabled = L:GetConfig("chicchai", "enabled")
        L:SetConfig("chicchai", "enabled", not enabled)
        print("|cff33ff99rChat:|r Chicchai", not enabled and "|cff00ff00" .. L.Strings["CHICCHAI_ENABLED"] .. "|r" or "|cffff0000" .. L.Strings["CHICCHAI_DISABLED"] .. "|r")
        ReloadUI()
    end
end

function rChat_OnAddonCompartmentEnter(_, tooltip)
    if tooltip and tooltip.AddLine then
        tooltip:AddLine(L.Strings["MINIMAP_TOOLTIP"])
    end
end

function rChat_OnAddonCompartmentLeave()
    GameTooltip:Hide()
end
