
_G.Cowmera = _G.Cowmera or {}

local function CowmeraGFEnsureDB()
    CowmeraDB = CowmeraDB or {}
    CowmeraDB.groupFinder = CowmeraDB.groupFinder or {}
    local db = CowmeraDB.groupFinder
    db.sessionLog = db.sessionLog or {}
    if db.disableToast == nil then
        db.disableToast = false
    end
    return db
end

local function CowmeraGFChatPrint(msg)
    print("|cff22c55e[Cowmera]|r " .. tostring(msg))
end

local function CowmeraGFGetPlayerName()
    local name = UnitName("player") or "Unknown"
    local realm = GetRealmName() or "UnknownRealm"
    return name .. "-" .. realm
end

local function CowmeraGFGetClassColorCode(classFile)
    local colors = _G.RAID_CLASS_COLORS
    if type(colors) == "table" and classFile and colors[classFile] then
        local c = colors[classFile]
        if c and c.colorStr then
            return "|c" .. tostring(c.colorStr)
        elseif c and c.r and c.g and c.b then
            return string.format("|cff%02x%02x%02x", math.floor(c.r * 255 + 0.5), math.floor(c.g * 255 + 0.5), math.floor(c.b * 255 + 0.5))
        end
    end
    return nil
end

local function CowmeraGFColorTextByClass(text, classFile)
    local prefix = CowmeraGFGetClassColorCode(classFile)
    if not prefix or not text or text == "" then
        return tostring(text or "")
    end
    return prefix .. tostring(text) .. "|r"
end

local function CowmeraGFGetUnitFullName(unit)
    if not unit or not UnitExists(unit) then
        return nil
    end
    local name, realm = UnitName(unit)
    if not name or name == "" then
        return nil
    end
    realm = realm or GetRealmName() or ""
    if realm ~= "" then
        return name .. "-" .. realm
    end
    return name
end

local function CowmeraGFResolveNameClass(fullName)
    if not fullName or fullName == "" then
        return nil
    end

    local playerName = CowmeraGFGetPlayerName()
    local simplePlayerName = UnitName("player")
    if fullName == playerName or (simplePlayerName and fullName == simplePlayerName) then
        local _, classFile = UnitClass("player")
        return classFile
    end

    return nil
end

local function CowmeraGFStatusText(value)
    if value == nil then
        return "unknown"
    end
    if type(value) == "number" then
        local enum = _G.Enum and _G.Enum.LFGListApplicationStatus
        if type(enum) == "table" then
            for key, enumValue in pairs(enum) do
                if enumValue == value then
                    return tostring(key)
                end
            end
        end
    end
    local text = tostring(value or "")
    if text == "" then
        return "unknown"
    end
    return text
end

local function CowmeraGFNormalizeStatus(value)
    return string.lower(CowmeraGFStatusText(value):gsub("[%s_%-]", ""))
end

local function CowmeraGFIsStatus(value, ...)
    local normalized = CowmeraGFNormalizeStatus(value)
    for i = 1, select("#", ...) do
        local option = tostring(select(i, ...) or "")
        option = string.lower(option:gsub("[%s_%-]", ""))
        if normalized == option then
            return true
        end
    end
    return false
end

local function CowmeraGFTimeText(ts)
    ts = tonumber(ts) or time()
    return date("%H:%M:%S", ts)
end

local function CowmeraGFDateText(value)
    local ts = tonumber(value)
    if not ts or ts <= 0 then
        return "Never"
    end
    return date("%Y-%m-%d %H:%M:%S", ts)
end

local function CowmeraGFSafeActivityName(activityIDs, fallbackActivityID)
    local ids = {}
    if type(activityIDs) == "table" then
        for _, id in ipairs(activityIDs) do
            if tonumber(id) then
                table.insert(ids, tonumber(id))
            end
        end
    end
    if #ids == 0 and tonumber(fallbackActivityID) then
        table.insert(ids, tonumber(fallbackActivityID))
    end

    for _, activityID in ipairs(ids) do
        if C_LFGList and C_LFGList.GetActivityInfoTable then
            local ok, activityInfo = pcall(C_LFGList.GetActivityInfoTable, activityID)
            if ok and type(activityInfo) == "table" then
                if activityInfo.fullName and activityInfo.fullName ~= "" then
                    return activityInfo.fullName
                end
                if activityInfo.shortName and activityInfo.shortName ~= "" then
                    return activityInfo.shortName
                end
            end
        end
        if C_LFGList and C_LFGList.GetActivityInfo then
            local ok, name = pcall(C_LFGList.GetActivityInfo, activityID)
            if ok and type(name) == "string" and name ~= "" then
                return name
            end
        end
    end

    return ""
end

local function CowmeraGFReadSearchResult(searchResultID)
    if not (C_LFGList and C_LFGList.GetSearchResultInfo and searchResultID) then
        return nil
    end

    local ok, info = pcall(C_LFGList.GetSearchResultInfo, searchResultID)
    if not ok or type(info) ~= "table" then
        return nil
    end

    local entry = {
        searchResultID = tonumber(searchResultID) or searchResultID,
        leaderName = info.leaderName or "",
        groupName = info.name or info.groupName or "",
        comment = info.comment or "",
        voiceChat = info.voiceChat or "",
        requiredItemLevel = info.requiredItemLevel or 0,
        requiredDungeonScore = info.requiredDungeonScore or 0,
        age = info.age or 0,
        numMembers = info.numMembers or 0,
        autoAccept = info.autoAccept and true or false,
        questID = info.questID or 0,
        activityIDs = info.activityIDs or {},
        activityID = info.activityID or 0,
    }

    entry.activityName = CowmeraGFSafeActivityName(entry.activityIDs, entry.activityID)
    return entry
end

local function CowmeraGFStoreListing(data, bucket, statusText)
    if type(data) ~= "table" then
        return nil
    end

    local db = CowmeraGFEnsureDB()
    local now = time()
    local record = {
        player = CowmeraGFGetPlayerName(),
        storedAt = now,
        bucket = bucket or "lastApplication",
        status = CowmeraGFStatusText(statusText),
        searchResultID = data.searchResultID or 0,
        leaderName = data.leaderName or "",
        groupName = data.groupName or data.name or "",
        comment = data.comment or "",
        voiceChat = data.voiceChat or "",
        requiredItemLevel = tonumber(data.requiredItemLevel) or 0,
        requiredDungeonScore = tonumber(data.requiredDungeonScore) or 0,
        age = tonumber(data.age) or 0,
        numMembers = tonumber(data.numMembers) or 0,
        autoAccept = data.autoAccept and true or false,
        questID = tonumber(data.questID) or 0,
        activityIDs = data.activityIDs or {},
        activityID = tonumber(data.activityID) or 0,
        activityName = data.activityName or "",
    }

    if record.activityName == "" then
        record.activityName = CowmeraGFSafeActivityName(record.activityIDs, record.activityID)
    end

    db[bucket or "lastApplication"] = record
    db.lastSeen = record
    return record
end

local function CowmeraGFStoreSearchResult(searchResultID, bucket, statusText)
    local data = CowmeraGFReadSearchResult(searchResultID)
    if not data then
        return nil
    end
    return CowmeraGFStoreListing(data, bucket, statusText)
end

local function CowmeraGFGetJoinedRecord()
    local db = CowmeraGFEnsureDB()
    if type(db.currentJoined) == "table" then
        return db.currentJoined
    end
    if type(db.lastJoined) == "table" then
        return db.lastJoined
    end
    if type(db.lastApplication) == "table" then
        return db.lastApplication
    end
    return nil
end

local function CowmeraGFColorOrange(text)
    return "|cffff9900" .. tostring(text or "") .. "|r"
end

local function CowmeraGFColorGreen(text)
    return "|cff00ff00" .. tostring(text or "") .. "|r"
end

local function CowmeraGFFormatShort(record)
    if type(record) ~= "table" then
        return "|cffff9900Unknown Activity|r | |cff00ff00Unknown Title|r | Unknown Leader"
    end

    local activityText = CowmeraGFColorOrange(record.activityName ~= "" and record.activityName or "Unknown Activity")
    local groupText = CowmeraGFColorGreen(record.groupName ~= "" and record.groupName or "Unknown Title")
    local leaderText = (record.leaderName ~= "" and record.leaderName or "Unknown Leader")
    local leaderClass = CowmeraGFResolveNameClass(record.leaderName)
    leaderText = CowmeraGFColorTextByClass(leaderText, leaderClass)

    return string.format(
        "%s | %s | %s",
        activityText,
        groupText,
        leaderText
    )
end

local function CowmeraGFBuildSummary(record)
    if type(record) ~= "table" then
        return "No Group Finder listing recorded yet."
    end

    local lines = {}
    table.insert(lines, string.format("Status: %s", CowmeraGFStatusText(record.status)))
    table.insert(lines, string.format("Time: %s", CowmeraGFDateText(record.storedAt)))
    table.insert(lines, string.format("Activity: %s", record.activityName ~= "" and record.activityName or "Unknown"))
    table.insert(lines, string.format("Title: %s", record.groupName ~= "" and record.groupName or "Unknown"))
    table.insert(lines, string.format("Leader: %s", record.leaderName ~= "" and record.leaderName or "Unknown"))
    table.insert(lines, string.format("Members: %s", tostring(record.numMembers or 0)))
    table.insert(lines, string.format("Required ilvl: %s", tostring(record.requiredItemLevel or 0)))
    table.insert(lines, string.format("Required score: %s", tostring(record.requiredDungeonScore or 0)))
    if record.comment and record.comment ~= "" then
        table.insert(lines, "")
        table.insert(lines, "Comment:")
        table.insert(lines, record.comment)
    end
    return table.concat(lines, "\n")
end

local function CowmeraGFBuildSessionLogText()
    local db = CowmeraGFEnsureDB()
    local log = db.sessionLog or {}
    if #log == 0 then
        return "No Group Finder events recorded this session."
    end

    local lines = {}
    for i = #log, 1, -1 do
        local entry = log[i]
        table.insert(lines, string.format("[%s] %s: %s", CowmeraGFTimeText(entry.at), tostring(entry.label or "Event"), tostring(entry.detail or "")))
    end
    return table.concat(lines, "\n")
end

local function CowmeraGFEnsureToast()
    if _G.CowmeraGFToastFrame then
        return _G.CowmeraGFToastFrame
    end

    local toast = CreateFrame("Frame", "CowmeraGFToastFrame", UIParent, "BackdropTemplate")
    toast:SetSize(520, 94)
    toast:SetPoint("TOP", UIParent, "TOP", 0, -160)
    toast:SetFrameStrata("DIALOG")
    toast:SetFrameLevel(500)
    toast:Hide()
    if toast.SetBackdrop then
        toast:SetBackdrop({
            bgFile = "Interface/ChatFrame/ChatFrameBackground",
            edgeFile = "Interface/Tooltips/UI-Tooltip-Border",
            tile = true,
            tileSize = 16,
            edgeSize = 12,
            insets = { left = 3, right = 3, top = 3, bottom = 3 },
        })
        toast:SetBackdropColor(0, 0, 0, 0.82)
        toast:SetBackdropBorderColor(0.65, 0.4, 0.08, 1)
    end

    local title = toast:CreateFontString(nil, "ARTWORK", "GameFontNormalLarge")
    title:SetPoint("TOPLEFT", 16, -12)
    title:SetJustifyH("LEFT")
    title:SetText("Group Finder")

    local body = toast:CreateFontString(nil, "ARTWORK", "GameFontHighlight")
    body:SetPoint("TOPLEFT", title, "BOTTOMLEFT", 0, -8)
    body:SetPoint("RIGHT", toast, "RIGHT", -16, 0)
    body:SetJustifyH("LEFT")
    body:SetJustifyV("TOP")
    body:SetSpacing(2)
    body:SetText("")

    toast.title = title
    toast.body = body
    toast.anim = toast:CreateAnimationGroup()

    local fadeIn = toast.anim:CreateAnimation("Alpha")
    fadeIn:SetOrder(1)
    fadeIn:SetFromAlpha(0)
    fadeIn:SetToAlpha(1)
    fadeIn:SetDuration(0.15)

    local hold = toast.anim:CreateAnimation("Alpha")
    hold:SetOrder(2)
    hold:SetFromAlpha(1)
    hold:SetToAlpha(1)
    hold:SetDuration(4.2)

    local fadeOut = toast.anim:CreateAnimation("Alpha")
    fadeOut:SetOrder(3)
    fadeOut:SetFromAlpha(1)
    fadeOut:SetToAlpha(0)
    fadeOut:SetDuration(0.5)

    toast.anim:SetScript("OnFinished", function()
        toast:Hide()
    end)

    _G.CowmeraGFToastFrame = toast
    return toast
end

local function CowmeraGFShouldShowEvent(label)
    local db = CowmeraGFEnsureDB()
    if label == "Invited" then
        return db.showInvited and true or false
    elseif label == "Accepted" then
        return db.showAccepted and true or false
    elseif label == "Joined" then
        return db.showJoined and true or false
    end
    return true
end

local function CowmeraGFShowToast(label, record)
    local db = CowmeraGFEnsureDB()
    local toast = CowmeraGFEnsureToast()
    if db.disableToast or not CowmeraGFShouldShowEvent(label) then
        toast.anim:Stop()
        toast:Hide()
        return
    end
    local ts = CowmeraGFTimeText(time())
    toast.title:SetText("Group Finder - " .. tostring(label))
    toast.body:SetText(string.format("[%s] %s", ts, CowmeraGFFormatShort(record)))
    toast.anim:Stop()
    toast:SetAlpha(0)
    toast:Show()
    toast.anim:Play()
end

local function CowmeraGFLogEvent(label, record, forceChat)
    if type(record) ~= "table" then
        return
    end
    if not CowmeraGFShouldShowEvent(label) then
        return
    end

    local db = CowmeraGFEnsureDB()
    db.sessionLog = db.sessionLog or {}
    local detail = CowmeraGFFormatShort(record)
    local eventKey = table.concat({
        tostring(label or ""),
        tostring(record.searchResultID or 0),
        tostring(record.groupName or ""),
        tostring(record.leaderName or ""),
        tostring(record.activityName or ""),
    }, "|")

    if db.lastEventKey == eventKey and (time() - (db.lastEventAt or 0)) < 2 then
        return
    end

    db.lastEventKey = eventKey
    db.lastEventAt = time()
    table.insert(db.sessionLog, {
        at = time(),
        label = label,
        detail = detail,
    })
    if #db.sessionLog > 50 then
        table.remove(db.sessionLog, 1)
    end

    if forceChat ~= false then
        CowmeraGFChatPrint(string.format("[%s] Group Finder %s: %s", CowmeraGFTimeText(time()), string.lower(tostring(label or "Update")), detail))
    end
    CowmeraGFShowToast(label, record)
end

local function CowmeraGFRefreshPanel()
    local panel = _G.CowmeraGroupFinderPanelState
    if not panel then
        return
    end

    local db = CowmeraGFEnsureDB()
    local joined = CowmeraGFGetJoinedRecord()
    local applied = db.lastApplication

    if panel.disableToastCheck then
        panel.disableToastCheck:SetChecked(db.disableToast and true or false)
    end
    if panel.invitedCheck then
        panel.invitedCheck:SetChecked(db.showInvited and true or false)
    end
    if panel.acceptedCheck then
        panel.acceptedCheck:SetChecked(db.showAccepted and true or false)
    end
    if panel.joinedCheck then
        panel.joinedCheck:SetChecked(db.showJoined and true or false)
    end

    if panel.summaryText then
        if joined then
            panel.summaryText:SetText("Last joined or accepted listing: " .. CowmeraGFFormatShort(joined) .. " | " .. CowmeraGFDateText(joined.storedAt))
        elseif applied then
            panel.summaryText:SetText("Most recent application: " .. CowmeraGFFormatShort(applied) .. " | " .. CowmeraGFDateText(applied.storedAt))
        else
            panel.summaryText:SetText("No Group Finder listing recorded yet.")
        end
    end

    if panel.output then
        local logText = CowmeraGFBuildSessionLogText()
        panel.output:SetText(logText)
        local lineCount = 1
        for _ in string.gmatch(logText, "\n") do
            lineCount = lineCount + 1
        end
        local _, lineHeight = panel.output:GetFont()
        lineHeight = tonumber(lineHeight) or 14
        local contentHeight = math.max(220, (lineCount * lineHeight) + 20)
        if panel.logContent then
            panel.logContent:SetHeight(contentHeight)
        end
        if panel.logScroll then
            panel.logScroll:SetVerticalScroll(0)
            if panel.logScroll.UpdateScrollChildRect then
                panel.logScroll:UpdateScrollChildRect()
            end
        end
    end

    if panel.detailsText then
        local chunks = {}
        table.insert(chunks, "Current / Last Joined")
        table.insert(chunks, CowmeraGFBuildSummary(joined))
        table.insert(chunks, "")
        table.insert(chunks, "Most Recent Application")
        table.insert(chunks, CowmeraGFBuildSummary(applied))
        panel.detailsText:SetText(table.concat(chunks, "\n"))
    end
end

local function CowmeraGFHandleApplicationStatus(searchResultID, newStatus, oldStatus, groupName)
    local statusText = CowmeraGFStatusText(newStatus)
    local record = CowmeraGFStoreSearchResult(searchResultID, "lastApplication", statusText)
    if not record and type(groupName) == "string" and groupName ~= "" then
        record = CowmeraGFStoreListing({ searchResultID = searchResultID, groupName = groupName }, "lastApplication", statusText)
    end
    if record and groupName and groupName ~= "" and (record.groupName == "" or record.groupName == "Unknown") then
        record.groupName = tostring(groupName)
    end

    local db = CowmeraGFEnsureDB()
    db.lastStatusChangedAt = time()

    if CowmeraGFIsStatus(newStatus, "invited") then
        db.currentJoined = CowmeraGFStoreListing(record, "lastInvited", statusText) or record
        CowmeraGFLogEvent("Invited", db.currentJoined, true)
    elseif CowmeraGFIsStatus(newStatus, "inviteaccepted", "accepted") then
        local acceptedRecord = CowmeraGFStoreListing(record, "lastJoined", statusText) or record
        db.currentJoined = acceptedRecord
        CowmeraGFLogEvent("Accepted", acceptedRecord, true)
    elseif CowmeraGFIsStatus(newStatus, "applied") then
        -- keep for summary, no toast/chat spam
    elseif CowmeraGFIsStatus(newStatus, "declined", "declinedfull", "declineddelisted", "cancelled", "timedout", "invitedeclined") then
        db.lastRejectedStatus = statusText
        db.lastRejectedAt = time()
    end

    CowmeraGFRefreshPanel()
end

local function CowmeraGFHandleJoinedGroup(searchResultID, groupName)
    local db = CowmeraGFEnsureDB()
    local source = nil
    if searchResultID then
        source = CowmeraGFReadSearchResult(searchResultID)
    end
    source = source or db.lastApplication or db.lastSeen or { searchResultID = searchResultID or 0, groupName = groupName or "" }
    if groupName and groupName ~= "" then
        source.groupName = groupName
    end
    local joinedRecord = CowmeraGFStoreListing(source, "lastJoined", "joined")
    if joinedRecord then
        db.currentJoined = joinedRecord
        CowmeraGFLogEvent("Joined", joinedRecord, true)
    end
    CowmeraGFRefreshPanel()
end

local function CowmeraGFHandleLeftGroup()
    local db = CowmeraGFEnsureDB()
    db.currentJoined = nil
    db.leftGroupAt = time()
    CowmeraGFRefreshPanel()
end

local tracker = CreateFrame("Frame")
tracker:RegisterEvent("PLAYER_LOGIN")
tracker:RegisterEvent("PLAYER_LOGOUT")
tracker:RegisterEvent("LFG_LIST_APPLICATION_STATUS_UPDATED")
tracker:RegisterEvent("LFG_LIST_JOINED_GROUP")
tracker:RegisterEvent("GROUP_LEFT")
tracker:SetScript("OnEvent", function(_, event, ...)
    if event == "PLAYER_LOGIN" then
        local db = CowmeraGFEnsureDB()
        db.sessionLog = {}
        db.lastEventKey = nil
        db.lastEventAt = 0
        db.lastInvited = nil
        db.currentJoined = nil
        CowmeraGFRefreshPanel()
    elseif event == "PLAYER_LOGOUT" then
        local db = CowmeraGFEnsureDB()
        db.sessionLog = {}
        db.lastEventKey = nil
        db.lastEventAt = 0
    elseif event == "LFG_LIST_APPLICATION_STATUS_UPDATED" then
        CowmeraGFHandleApplicationStatus(...)
    elseif event == "LFG_LIST_JOINED_GROUP" then
        CowmeraGFHandleJoinedGroup(...)
    elseif event == "GROUP_LEFT" then
        CowmeraGFHandleLeftGroup()
    end
end)

function _G.Cowmera.BuildGroupFinderPanel(host, parentFrame)
    if not host then
        return
    end

    if host.CowmeraGroupFinderBuilt then
        CowmeraGFRefreshPanel()
        return
    end
    host.CowmeraGroupFinderBuilt = true

    local title = host:CreateFontString(nil, "ARTWORK", "GameFontHighlightLarge")
    title:SetPoint("TOP", 0, -18)
    title:SetText("Group Finder Tracking")

    local subtitle = host:CreateFontString(nil, "ARTWORK", "GameFontHighlightSmall")
    subtitle:SetPoint("TOP", title, "BOTTOM", 0, -10)
    subtitle:SetWidth(620)
    subtitle:SetJustifyH("CENTER")
    subtitle:SetText("Shows invites, accepted entries, joined groups, and a session-only Group Finder log.")

    local groupFinderButton = CreateFrame("Button", nil, host, "UIPanelButtonTemplate")
    groupFinderButton:SetSize(120, 24)
    groupFinderButton:SetPoint("TOPLEFT", 20, -56)
    groupFinderButton:SetText("Open Finder")
    groupFinderButton:SetScript("OnClick", function()
        if type(_G.PVEFrame_ToggleFrame) == "function" then
            pcall(_G.PVEFrame_ToggleFrame, "GroupFinderFrame")
        elseif type(_G.ToggleLFDParentFrame) == "function" then
            pcall(_G.ToggleLFDParentFrame)
        end
    end)

    local disableToastCheck = CreateFrame("CheckButton", nil, host, "UICheckButtonTemplate")
    disableToastCheck:SetPoint("LEFT", groupFinderButton, "RIGHT", 12, 0)
    disableToastCheck.Text:SetText("Disable Toast")
    disableToastCheck.Text:SetTextColor(1, 0.82, 0, 1)
    disableToastCheck:SetScript("OnClick", function(self)
        local db = CowmeraGFEnsureDB()
        db.disableToast = self:GetChecked() and true or false
        if db.disableToast and _G.CowmeraGFToastFrame then
            _G.CowmeraGFToastFrame.anim:Stop()
            _G.CowmeraGFToastFrame:Hide()
        end
    end)

    local invitedCheck = CreateFrame("CheckButton", nil, host, "UICheckButtonTemplate")
    invitedCheck:SetPoint("LEFT", disableToastCheck, "RIGHT", 16, 0)
    invitedCheck.Text:SetText("Invited")
    invitedCheck.Text:SetTextColor(1, 0.82, 0, 1)
    invitedCheck:SetScript("OnClick", function(self)
        local db = CowmeraGFEnsureDB()
        db.showInvited = self:GetChecked() and true or false
        CowmeraGFRefreshPanel()
    end)

    local acceptedCheck = CreateFrame("CheckButton", nil, host, "UICheckButtonTemplate")
    acceptedCheck:SetPoint("LEFT", invitedCheck, "RIGHT", 12, 0)
    acceptedCheck.Text:SetText("Accepted")
    acceptedCheck.Text:SetTextColor(1, 0.82, 0, 1)
    acceptedCheck:SetScript("OnClick", function(self)
        local db = CowmeraGFEnsureDB()
        db.showAccepted = self:GetChecked() and true or false
        CowmeraGFRefreshPanel()
    end)

    local joinedCheck = CreateFrame("CheckButton", nil, host, "UICheckButtonTemplate")
    joinedCheck:SetPoint("LEFT", acceptedCheck, "RIGHT", 12, 0)
    joinedCheck.Text:SetText("Joined")
    joinedCheck.Text:SetTextColor(1, 0.82, 0, 1)
    joinedCheck:SetScript("OnClick", function(self)
        local db = CowmeraGFEnsureDB()
        db.showJoined = self:GetChecked() and true or false
        CowmeraGFRefreshPanel()
    end)

    local summaryLabel = host:CreateFontString(nil, "ARTWORK", "GameFontNormal")
    summaryLabel:SetPoint("TOPLEFT", 20, -94)
    summaryLabel:SetText("Summary")

    local summaryText = host:CreateFontString(nil, "ARTWORK", "GameFontHighlightSmall")
    summaryText:SetPoint("TOPLEFT", summaryLabel, "BOTTOMLEFT", 0, -8)
    summaryText:SetWidth(620)
    summaryText:SetJustifyH("LEFT")
    summaryText:SetJustifyV("TOP")
    summaryText:SetText("No Group Finder listing recorded yet.")

    local logLabel = host:CreateFontString(nil, "ARTWORK", "GameFontNormal")
    logLabel:SetPoint("TOPLEFT", summaryText, "BOTTOMLEFT", 0, -14)
    logLabel:SetText("Session Log")

    local logBg = CreateFrame("Frame", nil, host, "BackdropTemplate")
    logBg:SetPoint("TOPLEFT", logLabel, "BOTTOMLEFT", -6, -8)
    logBg:SetPoint("BOTTOMRIGHT", -18, 18)
    if logBg.SetBackdrop then
        logBg:SetBackdrop({
            bgFile = "Interface/ChatFrame/ChatFrameBackground",
            edgeFile = "Interface/Tooltips/UI-Tooltip-Border",
            tile = true,
            tileSize = 16,
            edgeSize = 12,
            insets = { left = 3, right = 3, top = 3, bottom = 3 },
        })
        logBg:SetBackdropColor(0, 0, 0, 0.55)
        logBg:SetBackdropBorderColor(0.65, 0.4, 0.08, 0.9)
    end

    local logScroll = CreateFrame("ScrollFrame", nil, logBg, "UIPanelScrollFrameTemplate")
    logScroll:SetPoint("TOPLEFT", 8, -8)
    logScroll:SetPoint("BOTTOMRIGHT", -28, 8)

    local logContent = CreateFrame("Frame", nil, logScroll)
    logContent:SetSize(700, 420)
    logScroll:SetScrollChild(logContent)

    local output = logContent:CreateFontString(nil, "ARTWORK", "GameFontHighlightSmall")
    output:SetPoint("TOPLEFT", 0, 0)
    output:SetPoint("RIGHT", logContent, "RIGHT", 0, 0)
    output:SetJustifyH("LEFT")
    output:SetJustifyV("TOP")
    output:SetSpacing(2)
    output:SetText("No Group Finder events recorded this session.")

    _G.CowmeraGroupFinderPanelState = {
        host = host,
        title = title,
        subtitle = subtitle,
        summaryText = summaryText,
        output = output,
        logScroll = logScroll,
        logContent = logContent,
        disableToastCheck = disableToastCheck,
        invitedCheck = invitedCheck,
        acceptedCheck = acceptedCheck,
        joinedCheck = joinedCheck,
    }

    _G.Cowmera.RefreshGroupFinderPanel = CowmeraGFRefreshPanel
    CowmeraGFRefreshPanel()
end

_G.Cowmera.RefreshGroupFinderPanel = CowmeraGFRefreshPanel
