local addonName, NS = ...
local GR = _G["GRS_MainFrame"] or NS.GR

if not GR then return end

-- =========================================================================
-- COMPACT MODE: DATA & STATE
-- =========================================================================

GR.CompactData = {
    isCompact = false,
    foundCount = 0,
    sentCount = 0,
    savedGeometry = nil,
    originalStartSearch = nil,
    originalParent = nil,
    originalPoints = {},
    headerFS = nil -- Store reference to the header font string
}

-- Counter Container
GR.CompactCounterFrame = CreateFrame("Frame", "GRS_CompactCounter", GR)
GR.CompactCounterFrame:SetSize(200, 20)
GR.CompactCounterFrame:Hide()
GR.CompactCounterLabel = GR.CompactCounterFrame:CreateFontString(nil, "OVERLAY", "GameFontNormal")
GR.CompactCounterLabel:SetPoint("CENTER")
GR.CompactCounterLabel:SetText("sending messages 0 out of 0")

-- Create Compact Specific Buttons
local function CreateCompactBtn(name, text, func)
    local btn = CreateFrame("Button", name, GR, "UIPanelButtonTemplate")
    btn:SetSize(140, 30)
    btn:SetText(text)
    btn:SetScript("OnClick", func)
    btn:Hide()
    if NS.SkinButton then NS.SkinButton(btn) end
    return btn
end

-- [[ NEW COMPACT SEARCH BUTTON ]]
-- Independent button for Compact Mode only. Replicates StartSearch functionality.
GR.CompactSearchBtn = CreateCompactBtn("GRS_CompactSearchBtn", "Search Players", function()
    GR:StartSearch()
end)

GR.CompactBatchBtn = CreateCompactBtn("GRS_CompactBatchBtn", "Send Batch", function()
    local mode = GR.db.sendMode or "MESSAGE"
    
    if mode == "MESSAGE" then
        -- MESSAGE mode: auto-select all and batch via timers
        for _, p in ipairs(GR.foundPlayers) do
            p.selected = true
        end
        GR:SendMessageSequence()
    else
        -- INVITE or BOTH: one player per click (matches non-compact behavior)
        if #GR.foundPlayers == 0 then
            print("|cffff0000[A.X.I.O.M.]|r No players in list."); return
        end
        local p = GR.foundPlayers[1]
        local justName = Ambiguate(p.name, "none")
        C_GuildInfo.Invite(justName)
        GR:AddToBlacklist(p.name)
        GR:AddToRecent(p.name, mode == "BOTH" and "Invited + Msg" or "Invited")
        
        -- If BOTH mode, also send message
        if mode == "BOTH" and GR.InputBody then
            local msg = GR.InputBody:GetText()
            if msg and msg ~= "" then
                local myName = UnitName("player")
                local gName = GetGuildInfo("player") or "Guild"
                local pClass = p.fullClass or "Hero"
                
                msg = msg:gsub("%b[]", function(captured)
                    local inner = captured:sub(2, -2)
                    local clean = inner:lower():gsub("%s+", "")
                    if clean == "player" then return justName end
                    if clean == "ownname" then return myName end
                    if clean == "guild" then return gName end
                    if clean == "playerclass" or clean == "class" then return pClass end
                    return captured
                end)
                
                GR.sessionWhitelist[justName] = true
                SendChatMessage(msg, "WHISPER", nil, p.name)
            end
        end
        
        -- Update counter (AddToBlacklist already removes player from foundPlayers via CleanUpScanResults)
        if GR.CompactData then
            GR.CompactData.sentCount = (GR.CompactData.sentCount or 0) + 1
            GR:UpdateCompactCounter()
        end
    end
end)

-- =========================================================================
-- LOGIC OVERRIDES
-- =========================================================================

-- [[ 1. OVERRIDE RESIZE BOUNDS ]]
-- We replace the main function to respect the Compact Mode state dynamically.
local OriginalUpdateBounds = GR.UpdateResizeBounds
GR.UpdateResizeBounds = function(self)
    if self.db.compactMode then
        -- In Compact Mode, allow minimum width of 420
        -- Max height increased to 1000 for vertical flexibility
        self:SetResizeBounds(420, 620, 500, 1400)
    else
        -- Use original logic for standard mode
        OriginalUpdateBounds(self)
    end
end

-- Override StartSearch to handle "Bypass Filter"
GR.OriginalStartSearch = GR.StartSearch
GR.StartSearch = function(self)
    if self.db.compactMode and self.db.bypassFilter then
        -- [[ BYPASS LOGIC ]]
        local now = GetTime()
        if (now - self.lastScanTime) < 5 then return end
        
        self:UpdateRaiderIOStatus()
        self.lastScanTime = now
        self.isScanning = true
        
        -- Cooldown UI Logic (Handled in Engine for visual updates, but triggered here)
        -- We manually trigger the visual lock here for the specific bypass bypass logic
        local buttons = {self.SearchBtn, self.CompactSearchBtn}
        for _, btn in pairs(buttons) do
            if btn then
                btn:Disable()
                local cd = 5
                btn:SetText("|cffff0000CD ("..cd..")|r")
                C_Timer.NewTicker(1, function(timer)
                    cd = cd - 1
                    if cd > 0 then
                        if btn then btn:SetText("|cffff0000CD ("..cd..")|r") end
                    else
                        timer:Cancel()
                        if btn then 
                            btn:Enable()
                            btn:SetText("Search Players")
                        end
                    end
                end, 5)
            end
        end
        
        C_Timer.After(60, function() if GR.isScanning then GR.isScanning = false end end)
        
        -- SIMPLE QUERY: No class/race loop
        -- Just min-max level
        local lMin = self.db.levelMin or 1
        local lMax = self.db.levelMax or 80
        local query = lMin .. "-" .. lMax
        
        if self.StatusText then self.StatusText:SetText("Bypass Scan: " .. query .. "...") end
        
        -- Force friend frame prep
        if FriendsFrame then FriendsFrame:UnregisterEvent("WHO_LIST_UPDATE") end
        C_FriendList.SetWhoToUi(1)
        C_FriendList.SendWho(query)
    else
        -- Use Original
        GR.OriginalStartSearch(self)
    end
end

-- Hook ProcessWhoResults to increment 'Found' (Y)
local OriginalProcessWho = GR.ProcessWhoResults
GR.ProcessWhoResults = function(self)
    local oldCount = #self.foundPlayers
    OriginalProcessWho(self)
    local newCount = #self.foundPlayers
    
    if self.db.compactMode then
        local diff = newCount - oldCount
        if diff > 0 then
            GR.CompactData.foundCount = GR.CompactData.foundCount + diff
            GR:UpdateCompactCounter()
        end
    end
end

-- Hook SendMessageSequence to increment 'Sent' (X)
local OriginalSendMessage = GR.SendMessageSequence
GR.SendMessageSequence = function(self)
    -- Global hook of SendChatMessage to count sent whispers during batch
    local oldSend = SendChatMessage
    SendChatMessage = function(msg, chatType, lang, target)
        oldSend(msg, chatType, lang, target)
        if GR.db.compactMode and chatType == "WHISPER" then
             GR.CompactData.sentCount = GR.CompactData.sentCount + 1
             GR:UpdateCompactCounter()
        end
    end
    
    OriginalSendMessage(self)
    -- Hook remains active to catch delayed sends
end


function GR:UpdateCompactCounter()
    local x = self.CompactData.sentCount
    local y = self.CompactData.foundCount
    
    -- X = Green, Y = Gold. If X==Y, X becomes Gold.
    local xColor = "|cff00ff00" -- Green
    if x >= y and y > 0 then xColor = "|cffffd100" end -- Gold
    
    -- Mode-aware label
    local mode = self.db.sendMode or "MESSAGE"
    local action = "sending messages"
    if mode == "INVITE" then
        action = "sending invites"
    elseif mode == "BOTH" then
        action = "sending messages + invites"
    end
    
    local txt = string.format("%s %s%d|r out of |cffffd100%d|r", action, xColor, x, y)
    self.CompactCounterLabel:SetText(txt)
end


-- =========================================================================
-- MAIN TOGGLE FUNCTION
-- =========================================================================

function GR:ToggleCompactMode(enable)
    if enable then
        GR.CompactData.isCompact = true
        
        -- 1. SAVE STATE (Geometry ignored on restore, but good practice to keep structure)
        if not GR.CompactData.savedGeometry then
             GR.CompactData.savedGeometry = { w = GR:GetWidth(), h = GR:GetHeight() }
        end
        
        -- Resize to Compact (Width 500, Height 665) -- 420 + 80
        GR:SetSize(500, 765)
        GR:UpdateResizeBounds() -- Calls our overridden function
        
        -- 2. HIDE TABS (Except 1 & 7)
        for i, tab in ipairs(GR.Tabs) do
            if i ~= 1 and i ~= 7 then tab:Hide() end
        end
        
        -- 3. HIDE PANES (Keep Left/Home visible)
        if GR.views[1] then
             local scrollChild = _G["GRS_ScrollChild"]
             if scrollChild then
                 local right = _G["GRS_RightPane"]
                 local center = _G["GRS_CenterPane"]
                 if right then right:Hide() end
                 if center then center:Hide() end
                 
                 local outer = _G["GRS_OuterScroll"]
                 if outer then outer:SetHorizontalScroll(0) end
                 
                 -- Widen left pane in compact mode (+80px)
                 local leftPane = scrollChild:GetChildren()
                 if leftPane then leftPane:SetWidth(400) end
             end
        end

        -- 4. VISUAL ADJUSTMENTS (Header & Status)
        
        -- Correctly find and change the Top Blue Header
        local headerFrame = _G["GRS_AxiomHeader"]
        if headerFrame then
            local regions = {headerFrame:GetRegions()}
            for _, r in ipairs(regions) do
                if r:IsObjectType("FontString") then
                    local txt = r:GetText()
                    if txt and string.find(txt, "Automated Xenial") then
                        GR.CompactData.headerFS = r -- Save reference
                        r:SetText("A.X.I.O.M.")
                        break
                    end
                end
            end
        end
        
        -- Hide Status Texts ("Greetings...", "Recruiter mode...")
        if GR.ioStatus then GR.ioStatus:Hide() end
        if GR.officerStatus then GR.officerStatus:Hide() end
        
        -- 5. BUTTON & UI RELOCATION
        -- In Compact Mode:
        -- - HIDE the Original Search Button
        -- - SHOW the New Compact Search Button
        
        if GR.SearchBtn then GR.SearchBtn:Hide() end
        
        -- Get left pane reference for scroll-based positioning
        local scrollChild = _G["GRS_ScrollChild"]
        local leftPane = scrollChild and scrollChild:GetChildren()
        local compactParent = leftPane or GR
        
        -- Position the COMPACT Search Button (inside left pane for scroll wrapping)
        GR.CompactSearchBtn:SetParent(compactParent)
        GR.CompactSearchBtn:ClearAllPoints()
        
        -- Find 'TEST ME' button inside the ScrollChild for positioning reference
        if GR.TestBtn then
             GR.CompactSearchBtn:SetPoint("TOPLEFT", GR.TestBtn, "BOTTOMLEFT", 0, -10)
        else
             GR.CompactSearchBtn:SetPoint("TOPLEFT", 15, -530)
        end
        GR.CompactSearchBtn:SetSize(280, 30)
        
        -- Position Batch Button
        GR.CompactBatchBtn:SetParent(compactParent)
        GR.CompactBatchBtn:ClearAllPoints()
        GR.CompactBatchBtn:SetPoint("TOPLEFT", GR.CompactSearchBtn, "BOTTOMLEFT", 0, -10)
        GR.CompactBatchBtn:SetSize(120, 30)
        
        -- [[ SEND MODE DROPDOWN - Compact Layout ]]
        if GR.SendModeBtn then
            GR.SendModeBtn:ClearAllPoints()
            GR.SendModeBtn:SetParent(compactParent)
            GR.SendModeBtn:SetPoint("LEFT", GR.CompactBatchBtn, "RIGHT", 5, 0)
            GR.SendModeBtn:SetSize(155, 30) -- 120 + 5 + 155 = 280 total
            GR.SendModeBtn:Show()
            -- Keep dropdown list at high strata to avoid scroll clipping
            if GR.SendModeList then
                GR.SendModeList:SetFrameStrata("TOOLTIP")
                GR.SendModeList:SetFrameLevel(200)
            end
        end
        
        -- Counter (left-aligned with buttons above)
        GR.CompactCounterFrame:SetParent(compactParent)
        GR.CompactCounterFrame:ClearAllPoints()
        GR.CompactCounterFrame:SetPoint("TOPLEFT", GR.CompactBatchBtn, "BOTTOMLEFT", 0, -10)
        GR.CompactCounterFrame:SetSize(280, 20)

        -- [[ REPARENT & MOVE WELCOME BUTTON ]]
        if GR.WelcomeBtn then
            GR.WelcomeBtn:ClearAllPoints()
            GR.WelcomeBtn:SetParent(compactParent)
            GR.WelcomeBtn:SetPoint("TOPLEFT", GR.CompactCounterFrame, "BOTTOMLEFT", 0, -10)
            GR.WelcomeBtn:SetSize(280, 30)
        end
        
        -- Hide Standard Status Text
        if GR.StatusText then GR.StatusText:Hide() end
        
        -- [[ VISIBILITY CHECK ]]
        -- Only show compact buttons if we are currently on the Home Tab (1).
        local isHome = (GR.activeTab == 1)
        GR.CompactSearchBtn:SetShown(isHome)
        GR.CompactBatchBtn:SetShown(isHome)
        GR.CompactCounterFrame:SetShown(isHome)
        if GR.WelcomeBtn then GR.WelcomeBtn:SetShown(isHome) end
        
        -- Apply send mode UI (button text, slider visibility, checkbox state)
        GR:UpdateSendModeUI()
        
    else
        GR.CompactData.isCompact = false
        
        -- 1. RESTORE WINDOW (Force 1280x750)
        GR:SetSize(1280, 750)
        GR:UpdateResizeBounds() -- Calls our overridden function which now sees compact=false
        
        -- [[ CRITICAL FIX: FORCE LAYOUT UPDATE ]]
        if GR.views[1] and GR.views[1]:GetScript("OnSizeChanged") then
             GR.views[1]:GetScript("OnSizeChanged")(GR.views[1], 1280, 750)
        end
        
        -- 2. RESTORE TITLES & STATUS
        if GR.CompactData.headerFS then
            GR.CompactData.headerFS:SetText("A.X.I.O.M. | Automated Xenial Index & Operations Matrix")
        end
        
        if GR.ioStatus then GR.ioStatus:Show() end
        if GR.officerStatus then GR.officerStatus:Show() end
        
        -- [[ RESTORE TABS ]]
        for _, tab in ipairs(GR.Tabs) do
            tab:Show()
        end
        GR:UpdateOfficerStatus() -- Refresh tab visibility & layout
        
        -- 3. RESTORE PANES
        local right = _G["GRS_RightPane"]
        local center = _G["GRS_CenterPane"]
        if right then right:Show() end
        if center then center:Show() end
        
        -- Restore left pane width to 320
        local scrollChild = _G["GRS_ScrollChild"]
        if scrollChild then
            local leftPane = scrollChild:GetChildren()
            if leftPane then leftPane:SetWidth(320) end
        end
        
        -- 4. RESTORE BUTTONS
        -- Hide Compact Buttons (reparent back to GR)
        GR.CompactSearchBtn:SetParent(GR)
        GR.CompactSearchBtn:Hide()
        GR.CompactBatchBtn:SetParent(GR)
        GR.CompactBatchBtn:Hide()
        GR.CompactCounterFrame:SetParent(GR)
        GR.CompactCounterFrame:Hide()

        -- Restore Welcome Button Position
        if GR.WelcomeBtn and GR.TestBtn then
             GR.WelcomeBtn:ClearAllPoints()
             -- Note: In UI.lua, the parent was `parent` (which is `GRS_HomeView` i.e. GR.views[1])
             GR.WelcomeBtn:SetParent(GR.views[1]) 
             GR.WelcomeBtn:SetFrameStrata("MEDIUM")
             GR.WelcomeBtn:SetPoint("TOPLEFT", GR.TestBtn, "BOTTOMLEFT", 0, -20)
             GR.WelcomeBtn:SetShown(true)
        end
        
        -- Restore Original Search Button
        if GR.SearchBtn then
             GR.SearchBtn:Show()
             GR.SearchBtn:Enable()
        end
        
        if GR.StatusText then GR.StatusText:Show() end
        
        -- Restore Send Mode Dropdown Position
        if GR.SendModeBtn and GR.SendModeOriginalParent then
             GR.SendModeBtn:ClearAllPoints()
             GR.SendModeBtn:SetParent(GR.SendModeOriginalParent)
             GR.SendModeBtn:SetFrameStrata("MEDIUM")
             -- Original anchor: RIGHT of btnBL, LEFT -10
             if GR.SendBatchBtn then
                 GR.SendModeBtn:SetPoint("RIGHT", GR.SendBatchBtn, "LEFT", -140, 0) -- Approximate position
             else
                 GR.SendModeBtn:SetPoint("RIGHT", -160, 0)
             end
             GR.SendModeBtn:SetSize(150, 30)
             GR.SendModeBtn:Show()
        end
    end
end

-- =========================================================================
-- TAB SWITCH HOOK
-- =========================================================================

-- Secure hook to handle button visibility when switching tabs in Compact Mode
hooksecurefunc(GR, "SwitchView", function(self, id)
    if not self.db.compactMode then return end
    
    -- In Compact Mode, buttons are parented to Main Frame (GR).
    -- They do not auto-hide when changing views. We must force it.
    
    local showCompactBtns = (id == 1) -- Only show on Home Tab
    
    if self.CompactSearchBtn then self.CompactSearchBtn:SetShown(showCompactBtns) end
    if self.CompactBatchBtn then self.CompactBatchBtn:SetShown(showCompactBtns) end
    if self.CompactCounterFrame then self.CompactCounterFrame:SetShown(showCompactBtns) end
    if self.WelcomeBtn then self.WelcomeBtn:SetShown(showCompactBtns) end
    if self.SendModeBtn then self.SendModeBtn:SetShown(showCompactBtns) end
end)