local addonName, NS = ...
local GR = NS.GR

-- =========================================================================
-- UI: RIGHT PANE (CHAT)
-- =========================================================================

function GR:BuildWhisperPane(parent)
    local expandedF = CreateFrame("Frame", nil, parent)
    expandedF:SetAllPoints()
    self.WhisperExpandedFrame = expandedF
    
    local gridH = expandedF:CreateFontString(nil, "OVERLAY", "GameFontNormalLarge")
    gridH:SetPoint("TOPLEFT", 15, -15)
    gridH:SetText(NS.L["ACTIVE_WHISPERS"] or "ACTIVE WHISPERS")
    
    local pText = expandedF:CreateFontString(nil, "OVERLAY", "GameFontHighlightSmall")
    pText:SetPoint("LEFT", gridH, "RIGHT", 30, 0) 
    pText:SetText("Page 1 / 1")
    self.pageText = pText
    
    local prevBtn = CreateFrame("Button", nil, expandedF)
    prevBtn:SetSize(20, 20)
    prevBtn:SetNormalTexture("Interface\\Buttons\\UI-SpellbookIcon-PrevPage-Up")
    prevBtn:SetHighlightTexture("Interface\\Buttons\\UI-Common-MouseHilight")
    prevBtn:SetPoint("RIGHT", pText, "LEFT", -5, 0)
    prevBtn:SetScript("OnClick", function() 
        if GR.currentPage > 1 then 
            GR.currentPage = GR.currentPage - 1
            GR:RenderWhisperGrid() 
        end 
    end)
    self.prevBtn = prevBtn
    
    local nextBtn = CreateFrame("Button", nil, expandedF)
    nextBtn:SetSize(20, 20)
    nextBtn:SetNormalTexture("Interface\\Buttons\\UI-SpellbookIcon-NextPage-Up")
    nextBtn:SetHighlightTexture("Interface\\Buttons\\UI-Common-MouseHilight")
    nextBtn:SetPoint("LEFT", pText, "RIGHT", 5, 0)
    nextBtn:SetScript("OnClick", function() 
        local maxP = math.ceil(#GR.activeChats/(GR.chatPageSize or 4))
        if maxP < 1 then maxP=1 end
        if GR.currentPage < maxP then 
            GR.currentPage = GR.currentPage + 1
            GR:RenderWhisperGrid() 
        end 
    end)
    self.nextBtn = nextBtn

    local pruneBtn = CreateFrame("Button", nil, expandedF, "UIPanelButtonTemplate")
    pruneBtn:SetSize(100, 20)
    pruneBtn:SetPoint("LEFT", nextBtn, "RIGHT", 20, 0)
    pruneBtn:SetText(NS.L["PRUNE_INACTIVE"] or "Prune Inactive")
    pruneBtn:SetScript("OnClick", function() self:PruneInactiveChats() end)
    NS.SkinButton(pruneBtn)
    
    -- [[ REPLIES ONLY CHECKBOX ]]
    local repliesCheck = CreateFrame("CheckButton", nil, expandedF, "UICheckButtonTemplate")
    repliesCheck:SetSize(24, 24)
    repliesCheck:SetPoint("LEFT", pruneBtn, "RIGHT", 10, 0)
    
    repliesCheck.text = repliesCheck:CreateFontString(nil, "OVERLAY", "GameFontHighlightSmall")
    repliesCheck.text:SetPoint("LEFT", repliesCheck, "RIGHT", 2, 0)
    repliesCheck.text:SetText(NS.L["REPLIES_ONLY"] or "Replies Only")
    
    GR.RepliesOnlyCheck = repliesCheck
    
    self.chatFrames = {}
    local gridBase = CreateFrame("Frame", nil, expandedF)
    gridBase:SetPoint("TOPLEFT", gridH, "BOTTOMLEFT", 0, -10)
    gridBase:SetPoint("BOTTOMRIGHT", -15, 10)
    self.WhisperGridBase = gridBase
    
    -- Initialize default state
    GR.currentPage = 1
    if not GR.activeChats then GR.activeChats = {} end

    function GR:UpdateWhisperLayout(totalHeight)
        self.chatPageSize = 6
        local chatH = 115
        local gap = 10
        
        for i = 1, self.chatPageSize do
            if not self.chatFrames[i] then
                local cf = CreateFrame("Frame", nil, self.WhisperGridBase)
                NS.CreateBg(cf, 0, 0, 0, 0.6)
                NS.CreateBorder(cf, 0.4, 0.4, 0.4, 1)
                cf:SetHeight(chatH); cf:SetPoint("LEFT"); cf:SetPoint("RIGHT")
                
                cf:Hide() 
                
                -- [[ NEW: HEADER WITH UNDERLINE ]]
                cf.headerBtn = CreateFrame("Button", nil, cf); cf.headerBtn:SetPoint("TOPLEFT", 5, -5); cf.headerBtn:SetSize(200, 15)
                cf.headerBtn.text = cf.headerBtn:CreateFontString(nil, "OVERLAY", "GameFontNormalSmall"); cf.headerBtn.text:SetPoint("LEFT"); cf.headerBtn.text:SetText(NS.L["INACTIVE"] or "Inactive")
                
                -- Underline Texture
                local ul = cf:CreateTexture(nil, "OVERLAY")
                ul:SetHeight(1)
                ul:SetColorTexture(1, 1, 1, 0.5) -- Semi-transparent white underline
                ul:SetPoint("TOPLEFT", cf.headerBtn.text, "BOTTOMLEFT", 0, -1)
                ul:SetPoint("TOPRIGHT", cf.headerBtn.text, "BOTTOMRIGHT", 20, -1) -- Extend slightly past name
                cf.headerLine = ul
                
                cf.headerBtn:RegisterForClicks("AnyUp") 
                cf.headerBtn:SetScript("OnClick", function(s, button)
                    if not s.playerName then return end
                    if button == "LeftButton" then ChatFrame_SendTell(s.playerName)
                    elseif button == "RightButton" and MenuUtil then
                        MenuUtil.CreateContextMenu(s, function(owner, root)
                            root:CreateTitle(s.playerName)
                            root:CreateButton("Invite to guild", function() C_GuildInfo.Invite(s.playerName) end)
                            -- [[ NEW: Perma-Blacklist ]]
                            root:CreateButton("Perma-Blacklist", function() 
                                if GR.AddToPermaBlacklist then GR:AddToPermaBlacklist(s.playerName) end 
                            end)
                        end)
                    end
                end)
                
                local closeChat = CreateFrame("Button", nil, cf, "UIPanelCloseButton"); closeChat:SetSize(20, 20); closeChat:SetPoint("TOPRIGHT", -2, -2)
                closeChat:SetScript("OnClick", function()
                    local idx = (GR.currentPage - 1) * self.chatPageSize + i
                    if GR.activeChats[idx] then table.remove(GR.activeChats, idx); GR:RenderWhisperGrid() end
                end)
                
                -- [[ MODIFIED SCROLL AREA FOR INPUT BOX ROOM ]]
                cf.scroll = CreateFrame("ScrollFrame", nil, cf, "UIPanelScrollFrameTemplate")
                cf.scroll:SetPoint("TOPLEFT", 5, -25) -- Shifted down for header
                cf.scroll:SetPoint("BOTTOMRIGHT", -25, 28) -- Lifted up for Input Box
                NS.StyleScrollBar(cf.scroll)
                
                -- [[ NEW: 2PX THICK BORDER AROUND TEXT CONTENT ]]
                local borderFrame = CreateFrame("Frame", nil, cf)
                borderFrame:SetPoint("TOPLEFT", cf.scroll, "TOPLEFT", -3, 3)
                borderFrame:SetPoint("BOTTOMRIGHT", cf.scroll, "BOTTOMRIGHT", 23, -3) -- Cover scrollbar area too
                NS.CreateThickBorder(borderFrame, 0.3, 0.3, 0.3, 1, 2)
                
                cf.text = CreateFrame("EditBox", nil, cf.scroll); cf.text:SetMultiLine(true); cf.text:SetFontObject(ChatFontSmall); cf.text:SetWidth(430); cf.text:SetAutoFocus(false); cf.text:EnableMouse(false)
                cf.scroll:SetScrollChild(cf.text)
                
                -- [[ NEW: DIRECT REPLY INPUT BOX ]]
                local replyBox = CreateFrame("EditBox", nil, cf, "InputBoxTemplate")
                replyBox:SetPoint("BOTTOMLEFT", 10, 5)
                replyBox:SetPoint("BOTTOMRIGHT", -10, 5)
                replyBox:SetHeight(20)
                replyBox:SetAutoFocus(false)
                replyBox:SetFontObject("ChatFontSmall")
                
                -- Placeholder text
                replyBox.ph = replyBox:CreateFontString(nil, "ARTWORK", "GameFontDisable")
                replyBox.ph:SetPoint("LEFT", 5, 0)
                replyBox.ph:SetText(NS.L["REPLY_PLACEHOLDER"] or "Reply...")
                
                replyBox:SetScript("OnEditFocusGained", function(s) s.ph:Hide() end)
                replyBox:SetScript("OnEditFocusLost", function(s) if s:GetText()=="" then s.ph:Show() end end)
                replyBox:SetScript("OnEscapePressed", function(s) s:ClearFocus() end)
                replyBox:SetScript("OnEnterPressed", function(s) 
                    local msg = s:GetText()
                    if msg and msg ~= "" and cf.headerBtn.playerName then
                        SendChatMessage(msg, "WHISPER", nil, cf.headerBtn.playerName)
                        s:SetText("")
                        -- Engine logic handles the update via event loop, but we can optimistically add?
                        -- Better wait for EVENT to prevent dupes, but GRS logic handles that.
                    end
                    s:ClearFocus() 
                end)
                
                cf.replyBox = replyBox
                
                self.chatFrames[i] = cf
            end
            
            if i==1 then 
                self.chatFrames[i]:SetPoint("TOP") 
            else 
                self.chatFrames[i]:SetPoint("TOP", self.chatFrames[i-1], "BOTTOM", 0, -gap) 
            end
        end
        
        for i = self.chatPageSize + 1, #self.chatFrames do
            if self.chatFrames[i] then self.chatFrames[i]:Hide() end
        end
        
        self:RenderWhisperGrid()
    end
end

-- MISSING FUNCTION IMPLEMENTATION: RENDER WHISPER GRID
function GR:RenderWhisperGrid()
    local page = self.currentPage or 1
    local pageSize = self.chatPageSize or 6
    local chats = self.activeChats or {}
    local offset = (page - 1) * pageSize

    -- Update Page Text
    local maxPage = math.ceil(#chats / pageSize)
    if maxPage < 1 then maxPage = 1 end
    
    if page > maxPage then 
        self.currentPage = maxPage
        page = maxPage
        offset = (page - 1) * pageSize
    end

    if self.pageText then self.pageText:SetText(string.format("Page %d / %d", page, maxPage)) end

    for i = 1, pageSize do
        local frame = self.chatFrames and self.chatFrames[i]
        if frame then
            local chatData = chats[offset + i]
            if chatData then
                frame:Show()
                frame.headerBtn.text:SetText(chatData.name or "Unknown")
                frame.headerBtn.playerName = chatData.name
                
                -- Handle History formatting (append timestamps if available in data, otherwise just text)
                local hist = chatData.history or ""
                if type(hist) == "table" then
                     -- If history is a table of strings, concat
                     hist = table.concat(hist, "\n")
                end
                
                if frame.text then frame.text:SetText(hist) end
                -- Auto scroll to bottom
                if frame.scroll then frame.scroll:SetVerticalScroll(frame.scroll:GetVerticalScrollRange()) end
            else
                frame:Hide()
            end
        end
    end
end

-- MISSING FUNCTION IMPLEMENTATION: PRUNE INACTIVE CHATS
function GR:PruneInactiveChats()
    if not self.activeChats then return end
    
    local prunedCount = 0
    -- Prune backwards
    for i = #self.activeChats, 1, -1 do
        local chat = self.activeChats[i]
        -- Logic: If chat is empty or marked as offline/inactive, remove it.
        -- Since 'inactive' definition varies, we will remove chats with no history or explicitly closed.
        -- For now, let's remove chats where history is empty (dead session).
        if not chat.history or chat.history == "" or (type(chat.history)=="table" and #chat.history==0) then
            table.remove(self.activeChats, i)
            prunedCount = prunedCount + 1
        end
    end
    
    if prunedCount > 0 then
        print(string.format("GRS: Pruned %d empty chat sessions.", prunedCount))
    else
        print("GRS: No empty chat sessions found.")
    end
    self:RenderWhisperGrid()
end