local battleFrame = CreateFrame("Frame", "BPSBattleFrame", UIParent, "BackdropTemplate")
battleFrame:SetSize(320, 230)
battleFrame:SetPoint("TOP", UIParent, "TOP", 0, -130)
battleFrame:SetFrameStrata("HIGH")
battleFrame:SetBackdrop({
    bgFile = "Interface\\Tooltips\\UI-Tooltip-Background",
    edgeFile = "Interface\\Tooltips\\UI-Tooltip-Border",
    tile = true, tileSize = 16, edgeSize = 12,
    insets = { left = 4, right = 4, top = 4, bottom = 4 },
})
battleFrame:SetBackdropColor(0, 0, 0, 0.75)
battleFrame:SetMovable(true)
battleFrame:EnableMouse(true)
battleFrame:RegisterForDrag("LeftButton")
battleFrame:SetScript("OnDragStart", function(self) self:StartMoving() end)
battleFrame:SetScript("OnDragStop", function(self) self:StopMovingOrSizing() end)
battleFrame:Hide()

local function NewLine(anchorTo, fontTemplate, yOffset)
    local fs = battleFrame:CreateFontString(nil, "OVERLAY", fontTemplate or "GameFontNormal")
    if anchorTo then
        fs:SetPoint("TOP", anchorTo, "BOTTOM", 0, yOffset or -4)
    else
        fs:SetPoint("TOP", battleFrame, "TOP", 0, -10)
    end
    return fs
end

local sessionTitle   = NewLine(nil, "GameFontNormalLarge")
local overallLine    = NewLine(sessionTitle, "GameFontNormal")
local winrateLine    = NewLine(overallLine, "GameFontNormal")
local goalLine       = NewLine(winrateLine, "GameFontNormal")
local vsLine         = NewLine(goalLine, "GameFontNormalLarge", -10)
local vsStatsLine    = NewLine(vsLine, "GameFontNormal")
local vsWinrateLine  = NewLine(vsStatsLine, "GameFontNormal")
local predictionLine = NewLine(vsWinrateLine, "GameFontNormalLarge")

-- Forfeit button
local forfeitButton = CreateFrame("Button", nil, battleFrame, "UIPanelButtonTemplate")
forfeitButton:SetSize(140, 24)
forfeitButton:SetPoint("TOP", predictionLine, "BOTTOM", 0, -10)
forfeitButton:SetScript("OnClick", function()
    if C_PetBattles.IsInBattle and C_PetBattles.IsInBattle() then
        C_PetBattles.ForfeitGame()
    end
end)

local function Round(n)
    return math.floor(n + 0.5)
end

local function ComputeWinrate(wins, losses)
    local total = wins + losses
    if total == 0 then return 0 end
    return Round((wins / total) * 100)
end

local function RefreshDisplay()
    local L = BPS_GetLocale()
    local display = BattlePetStatisticsDB.display

    sessionTitle:SetText(L.SESSION_TITLE)

    local oWins, oLosses = BPS_GetSessionTotals()
    if display.showOverall then
        overallLine:SetText(string.format(L.OVERALL, oWins, oLosses))
        overallLine:Show()
    else
        overallLine:Hide()
    end

    if display.showWinrate then
        winrateLine:SetText(string.format(L.WINRATE, ComputeWinrate(oWins, oLosses)))
        winrateLine:Show()
    else
        winrateLine:Hide()
    end

    if display.showGoal then
        local goal = BPS_GetCurrentGoal()
        if goal then
            local progress = BPS_GetRealProgress(goal)
            goalLine:SetText(string.format(L.GOAL_LINE, BPS_GetGoalName(goal), math.min(progress, goal.threshold), goal.threshold))
        else
            goalLine:SetText(L.GOAL_DONE_LINE)
        end
        goalLine:Show()
    else
        goalLine:Hide()
    end

    local opponentName = BPS_GetCurrentOpponentDisplayName()
    local wins, losses = 0, 0
    if opponentName then
        wins, losses = BPS_GetStatsFor(opponentName)
    end

    if display.showVs and opponentName then
        vsLine:SetText(string.format("%s %s", L.VS, opponentName))
        vsLine:Show()
    else
        vsLine:Hide()
    end

    if display.showVsStats and opponentName then
        vsStatsLine:SetText(string.format("%s : %d   %s: %d", L.WIN, wins, L.LOSE, losses))
        vsStatsLine:Show()
    else
        vsStatsLine:Hide()
    end

    if display.showVsWinrate and opponentName then
        vsWinrateLine:SetText(string.format(L.WINRATE, ComputeWinrate(wins, losses)))
        vsWinrateLine:Show()
    else
        vsWinrateLine:Hide()
    end

    -- Prediction rule: wins < losses -> Win, otherwise -> Lose.
    -- Computed independently of display.showPrediction since the forfeit
    -- button visibility depends on it too.
    local shouldWin = opponentName and (wins < losses) or false

    if display.showPrediction and opponentName then
        if shouldWin then
            predictionLine:SetText(L.YOU_SHOULD_WIN)
            predictionLine:SetTextColor(0.1, 1.0, 0.1)
        else
            predictionLine:SetText(L.YOU_SHOULD_LOSE)
            predictionLine:SetTextColor(1.0, 0.1, 0.1)
        end
        predictionLine:Show()
    else
        predictionLine:Hide()
    end

    -- Hide the forfeit button entirely when the player is predicted to win
    -- against this opponent, so they aren't tempted to forfeit a winnable fight.
    forfeitButton:SetText(L.FORFEIT_BUTTON)
    if display.showForfeitButton and not shouldWin then
        forfeitButton:Show()
    else
        forfeitButton:Hide()
    end

    -- Re-flow the frame height roughly based on visible lines
    battleFrame:SetHeight(60 +
        (overallLine:IsShown() and 18 or 0) +
        (winrateLine:IsShown() and 18 or 0) +
        (goalLine:IsShown() and 18 or 0) +
        (vsLine:IsShown() and 24 or 0) +
        (vsStatsLine:IsShown() and 18 or 0) +
        (vsWinrateLine:IsShown() and 18 or 0) +
        (predictionLine:IsShown() and 24 or 0) +
        (forfeitButton:IsShown() and 30 or 0))
end

function BPS_ShowBattleFrame()
    RefreshDisplay()
    if not battleFrame:IsShown() then
        battleFrame:Show()
    end
end

function BPS_UpdateBattleFrame()
    RefreshDisplay()
end

function BPS_HideBattleFrame()
    battleFrame:Hide()
end

-- ===================== Requeue button (shown after battle ends) =====================
local requeueButton = CreateFrame("Button", "BPSRequeueButton", UIParent, "UIPanelButtonTemplate")
requeueButton:SetSize(260, 50)
requeueButton:SetPoint("CENTER", UIParent, "CENTER", 0, 0)
requeueButton:SetFrameStrata("DIALOG")
requeueButton:GetFontString():SetFontObject("GameFontNormalLarge")
requeueButton:Hide()

requeueButton:SetScript("OnClick", function()
    pcall(C_PetBattles.StartPVPMatchmaking)
    requeueButton:Hide()
end)

-- Close (X) button on the requeue popup so players can dismiss it without re-queuing
local requeueClose = CreateFrame("Button", nil, requeueButton)
requeueClose:SetSize(20, 20)
requeueClose:SetPoint("TOPRIGHT", requeueButton, "TOPRIGHT", 2, 2)
requeueClose:SetNormalTexture("Interface\\Buttons\\UI-StopButton")
requeueClose:GetNormalTexture():SetAlpha(0.8)
requeueClose:SetHighlightTexture("Interface\\Buttons\\UI-StopButton")
requeueClose:SetScript("OnClick", function() requeueButton:Hide() end)

function BPS_ShowRequeueButton()
    local L = BPS_GetLocale()
    requeueButton:SetText(L.REQUEUE_BUTTON)
    requeueButton:Show()
end

-- Hide the requeue button once a new battle starts
local hideHelper = CreateFrame("Frame")
hideHelper:RegisterEvent("PET_BATTLE_OPENING_START")
hideHelper:SetScript("OnEvent", function()
    requeueButton:Hide()
end)

-- ===================== Big "all goals completed" celebration popup =====================
local celebrationFrame = CreateFrame("Frame", "BPSCelebrationFrame", UIParent, "BackdropTemplate")
celebrationFrame:SetSize(520, 180)
celebrationFrame:SetPoint("CENTER", UIParent, "CENTER", 0, 150)
celebrationFrame:SetFrameStrata("FULLSCREEN_DIALOG")
celebrationFrame:SetBackdrop({
    bgFile = "Interface\\DialogFrame\\UI-DialogBox-Background",
    edgeFile = "Interface\\DialogFrame\\UI-DialogBox-Border",
    tile = true, tileSize = 32, edgeSize = 32,
    insets = { left = 11, right = 12, top = 12, bottom = 11 },
})
celebrationFrame:Hide()

local celebrationText = celebrationFrame:CreateFontString(nil, "OVERLAY", "GameFontNormalHuge")
celebrationText:SetPoint("CENTER", 0, 0)
celebrationText:SetWidth(460)
celebrationText:SetJustifyH("CENTER")

local celebrationClose = CreateFrame("Button", nil, celebrationFrame, "UIPanelCloseButton")
celebrationClose:SetPoint("TOPRIGHT", -5, -5)
celebrationClose:SetScript("OnClick", function() celebrationFrame:Hide() end)

function BPS_OnGoalCompleted(goal)
    if goal and goal.id == BPS_BIG_CELEBRATION_GOAL_ID then
        local L = BPS_GetLocale()
        celebrationText:SetText(L.BIG_CONGRATS)
        celebrationFrame:Show()
        local ok = pcall(PlaySound, SOUNDKIT and SOUNDKIT.IG_QUEST_LIST_COMPLETE, "Master")
        if not ok then
            pcall(PlaySound, SOUNDKIT and SOUNDKIT.READY_CHECK, "Master")
        end
    end
end
