-- ===================== Main frame =====================
local optionsFrame = CreateFrame("Frame", "BPSOptionsFrame", UIParent, "BackdropTemplate")
optionsFrame:SetSize(580, 780)
optionsFrame:SetPoint("CENTER")
optionsFrame:SetFrameStrata("DIALOG")
optionsFrame:SetBackdrop({
    bgFile   = "Interface\\Buttons\\WHITE8x8",
    edgeFile = "Interface\\Buttons\\WHITE8x8",
    edgeSize = 1,
})
optionsFrame:SetBackdropColor(0.06, 0.06, 0.07, 0.97)
optionsFrame:SetBackdropBorderColor(0, 0, 0, 1)
optionsFrame:SetMovable(true)
optionsFrame:EnableMouse(true)
optionsFrame:RegisterForDrag("LeftButton")
optionsFrame:SetScript("OnDragStart", function(s) s:StartMoving() end)
optionsFrame:SetScript("OnDragStop",  function(s) s:StopMovingOrSizing() end)
optionsFrame:SetClampedToScreen(true)
optionsFrame:Hide()

if UISpecialFrames then table.insert(UISpecialFrames, "BPSOptionsFrame") end

-- Accent header strip
local headerBar = CreateFrame("Frame", nil, optionsFrame, "BackdropTemplate")
headerBar:SetPoint("TOPLEFT", 1, -1)
headerBar:SetPoint("TOPRIGHT", -1, -1)
headerBar:SetHeight(78)
headerBar:SetBackdrop({ bgFile = "Interface\\Buttons\\WHITE8x8" })
headerBar:SetBackdropColor(0.10, 0.10, 0.12, 1)

local accentLine = headerBar:CreateTexture(nil, "ARTWORK")
accentLine:SetColorTexture(0.16, 0.55, 0.95, 1)
accentLine:SetPoint("BOTTOMLEFT", 0, 0)
accentLine:SetPoint("BOTTOMRIGHT", 0, 0)
accentLine:SetHeight(2)

local closeBtn = CreateFrame("Button", nil, optionsFrame, "UIPanelCloseButton")
closeBtn:SetPoint("TOPRIGHT", -4, -4)

local mainTitle = headerBar:CreateFontString(nil, "OVERLAY", "GameFontNormalLarge")
mainTitle:SetPoint("TOPLEFT", 18, -14)
mainTitle:SetText("Battle Pet Statistics")
mainTitle:SetTextColor(1, 1, 1)

-- ===================== Tab system (top, button-style) =====================
local TAB_OPTIONS = 1
local TAB_STATS   = 2
local currentTab  = TAB_OPTIONS

local tabBtns   = {}
local tabPanels = {}
local TAB_LABELS_FALLBACK = { "Options", "Statistics" }

local function StyleTabButton(btn, isActive)
    if isActive then
        btn:SetBackdropColor(0.16, 0.55, 0.95, 1)
        btn.label:SetTextColor(1, 1, 1)
    else
        btn:SetBackdropColor(0.16, 0.16, 0.18, 1)
        btn.label:SetTextColor(0.7, 0.7, 0.72)
    end
end

for i = 1, 2 do
    local btn = CreateFrame("Button", "BPSTab" .. i, headerBar, "BackdropTemplate")
    btn:SetSize(140, 26)
    btn:SetBackdrop({ bgFile = "Interface\\Buttons\\WHITE8x8" })
    btn:SetID(i)

    if i == 1 then
        btn:SetPoint("BOTTOMLEFT", 18, 12)
    else
        btn:SetPoint("LEFT", tabBtns[i - 1], "RIGHT", 8, 0)
    end

    local label = btn:CreateFontString(nil, "OVERLAY", "GameFontNormalSmall")
    label:SetPoint("CENTER")
    btn.label = label

    btn:SetScript("OnClick", function(self)
        currentTab = self:GetID()
        for j, p in ipairs(tabPanels) do
            p:SetShown(j == currentTab)
            StyleTabButton(tabBtns[j], j == currentTab)
        end
        -- Re-apply all text/locale-dependent values whenever the tab changes,
        -- so a language switch made earlier in the session is never left
        -- stale on a tab that wasn't re-opened since.
        if BPS_RefreshOptions then BPS_RefreshOptions() end
    end)
    btn:SetScript("OnEnter", function(self)
        if self:GetID() ~= currentTab then
            self:SetBackdropColor(0.22, 0.22, 0.25, 1)
        end
    end)
    btn:SetScript("OnLeave", function(self)
        StyleTabButton(self, self:GetID() == currentTab)
    end)

    label:SetText(TAB_LABELS_FALLBACK[i])
    StyleTabButton(btn, i == currentTab)
    tabBtns[i] = btn
end

local function MakePanel()
    local p = CreateFrame("Frame", nil, optionsFrame)
    p:SetPoint("TOPLEFT", 18, -90)
    p:SetPoint("BOTTOMRIGHT", -18, 16)
    p:Hide()
    return p
end

local optPanel  = MakePanel()
local statPanel = MakePanel()
tabPanels[TAB_OPTIONS] = optPanel
tabPanels[TAB_STATS]   = statPanel

-- ===================== OPTIONS TAB =====================

-- Language
local langLabel = optPanel:CreateFontString(nil, "OVERLAY", "GameFontNormalLarge")
langLabel:SetPoint("TOPLEFT", 0, 0)

local langDropdown = CreateFrame("Frame", "BPSLangDropdown", optPanel, "UIDropDownMenuTemplate")
langDropdown:SetPoint("TOPLEFT", langLabel, "BOTTOMLEFT", -16, -4)

local function SetLanguage(mode)
    EnsureDB()
    BattlePetStatisticsDB.language = mode
    BPS_RefreshOptions()
end

local function LangDropdown_Init(self, level)
    EnsureDB()
    local L = BPS_GetLocale()
    local opts = {
        { v="AUTO", t=L.LANG_AUTO },
        { v="EN",   t=L.LANG_EN },
        { v="FR",   t=L.LANG_FR },
        { v="DE",   t=L.LANG_DE },
        { v="IT",   t=L.LANG_IT },
        { v="PL",   t=L.LANG_PL },
        { v="SV",   t=L.LANG_SV },
        { v="CS",   t=L.LANG_CS },
    }
    for _, o in ipairs(opts) do
        local info = UIDropDownMenu_CreateInfo()
        info.text    = o.t
        info.value   = o.v
        info.func    = function(self) SetLanguage(self.value) end
        info.checked = (BattlePetStatisticsDB.language == o.v)
        UIDropDownMenu_AddButton(info, level)
    end
end
UIDropDownMenu_Initialize(langDropdown, LangDropdown_Init)
UIDropDownMenu_SetWidth(langDropdown, 150)

-- Display line toggles
local dispTitle  = optPanel:CreateFontString(nil, "OVERLAY", "GameFontNormalLarge")
dispTitle:SetPoint("TOPLEFT", langDropdown, "BOTTOMLEFT", 16, -12)

local DISP_KEYS   = { "showOverall","showWinrate","showGoal","showVs","showVsStats","showVsWinrate","showPrediction","showForfeitButton" }
local DISP_LKEYS  = { "SHOW_OVERALL","SHOW_WINRATE","SHOW_GOAL","SHOW_VS","SHOW_VS_STATS","SHOW_VS_WINRATE","SHOW_PREDICTION","SHOW_FORFEIT_BUTTON" }
local dispChecks  = {}

for i, key in ipairs(DISP_KEYS) do
    local col = (i - 1) % 2
    local row = math.floor((i - 1) / 2)
    local cb = CreateFrame("CheckButton", "BPSDispCB" .. i, optPanel, "UICheckButtonTemplate")
    cb:SetPoint("TOPLEFT", dispTitle, "BOTTOMLEFT", col * 265, -4 - row * 24)
    cb.dbKey = key
    cb:SetScript("OnClick", function(self)
        EnsureDB()
        BattlePetStatisticsDB.display[self.dbKey] = self:GetChecked() and true or false
    end)
    if not cb.labelFS then
        local fs = optPanel:CreateFontString(nil, "OVERLAY", "GameFontHighlightSmall")
        fs:SetPoint("LEFT", cb, "RIGHT", 2, 0)
        cb.labelFS = fs
    end
    dispChecks[i] = cb
end

-- Goal section: completed achievements list (green, read-only) + dropdown for
-- picking the current goal among the NOT-YET-completed ones only.
local goalTitle = optPanel:CreateFontString(nil, "OVERLAY", "GameFontNormalLarge")
goalTitle:SetPoint("TOPLEFT", dispTitle, "BOTTOMLEFT", 0, -118)

local goalCompletedLabel = optPanel:CreateFontString(nil, "OVERLAY", "GameFontNormal")
goalCompletedLabel:SetPoint("TOPLEFT", goalTitle, "BOTTOMLEFT", 4, -8)

-- Up to #BPS_GOALS lines to list completed achievements in green; hidden when unused.
local MAX_GOALS = #BPS_GOALS
local completedLines = {}
for i = 1, MAX_GOALS do
    local fs = optPanel:CreateFontString(nil, "OVERLAY", "GameFontHighlightSmall")
    if i == 1 then
        fs:SetPoint("TOPLEFT", goalCompletedLabel, "BOTTOMLEFT", 4, -4)
    else
        fs:SetPoint("TOPLEFT", completedLines[i - 1], "BOTTOMLEFT", 0, -2)
    end
    fs:SetTextColor(0.2, 1.0, 0.2)
    fs:Hide()
    completedLines[i] = fs
end

local goalNoneCompletedText = optPanel:CreateFontString(nil, "OVERLAY", "GameFontDisableSmall")
goalNoneCompletedText:SetPoint("TOPLEFT", goalCompletedLabel, "BOTTOMLEFT", 4, -4)
goalNoneCompletedText:Hide()

-- goalCurrentLabel is anchored dynamically in BPS_RefreshOptions, right below
-- whichever completed-goal element is currently the last one shown, so the
-- completed list only takes up as much vertical space as it actually needs.
local goalCurrentLabel = optPanel:CreateFontString(nil, "OVERLAY", "GameFontNormal")

local goalDropdown = CreateFrame("Frame", "BPSGoalDropdown", optPanel, "UIDropDownMenuTemplate")
goalDropdown:SetPoint("TOPLEFT", goalCurrentLabel, "BOTTOMLEFT", -16, -4)

local function GoalDropdown_Init(self, level)
    EnsureDB()
    local L = BPS_GetLocale()

    -- Only the NOT-YET-completed goals are selectable here; completed ones are
    -- shown separately above in the green "completed" list.
    for _, goal in ipairs(BPS_GOALS) do
        if not BPS_IsGoalCompleted(goal.id) then
            local isCurrent = (BattlePetStatisticsDB.currentGoalId == goal.id)
            local progress  = BPS_GetRealProgress(goal)
            local progressLabel = math.min(progress, goal.threshold) .. "/" .. goal.threshold
            local info = UIDropDownMenu_CreateInfo()
            if isCurrent then
                info.text = "|cffffff00> " .. BPS_GetGoalName(goal) .. " (" .. progressLabel .. ")|r"
            else
                info.text = BPS_GetGoalName(goal) .. " (" .. progressLabel .. ")"
            end
            info.value    = goal.id
            info.checked  = isCurrent
            info.disabled = false
            info.func = function(self)
                BPS_SetCurrentGoal(self.value)
                BPS_RefreshOptions()
            end
            UIDropDownMenu_AddButton(info, level)
        end
    end
end
UIDropDownMenu_Initialize(goalDropdown, GoalDropdown_Init)
UIDropDownMenu_SetWidth(goalDropdown, 360)

-- Keybinding section
local kbTitle = optPanel:CreateFontString(nil, "OVERLAY", "GameFontNormalLarge")
kbTitle:SetPoint("TOPLEFT", goalDropdown, "BOTTOMLEFT", 16, -14)

local kbHint = optPanel:CreateFontString(nil, "OVERLAY", "GameFontHighlightSmall")
kbHint:SetPoint("TOPLEFT", kbTitle, "BOTTOMLEFT", 4, -6)
kbHint:SetWidth(500)
kbHint:SetJustifyH("LEFT")

local kbOpenBtn = CreateFrame("Button", nil, optPanel, "UIPanelButtonTemplate")
kbOpenBtn:SetSize(200, 24)
kbOpenBtn:SetPoint("TOPLEFT", kbHint, "BOTTOMLEFT", 0, -6)
kbOpenBtn:SetScript("OnClick", function()
    local opened = false
    pcall(function()
        if Settings and Settings.OpenToCategory and Settings.KEYBINDINGS_CATEGORY_ID then
            Settings.OpenToCategory(Settings.KEYBINDINGS_CATEGORY_ID)
            opened = true
        end
    end)
    if not opened then
        pcall(function()
            if _G.KeyBindingFrame then ToggleFrame(KeyBindingFrame); opened = true end
        end)
    end
    if not opened then
        print("|cff33ff99BPS|r: Esc → Key Bindings → \"Battle Pet Statistics\"")
    end
end)

-- ===================== Trade Win Session section =====================
local twTitle = optPanel:CreateFontString(nil, "OVERLAY", "GameFontNormalLarge")
twTitle:SetPoint("TOPLEFT", kbOpenBtn, "BOTTOMLEFT", -16, -18)

local twIntro = optPanel:CreateFontString(nil, "OVERLAY", "GameFontHighlightSmall")
twIntro:SetPoint("TOPLEFT", twTitle, "BOTTOMLEFT", 4, -6)
twIntro:SetWidth(500)
twIntro:SetJustifyH("LEFT")

-- Group 1: when to show the alias popup (4 mutually exclusive radio buttons)
local SHOW_WINDOW_MODES = { "startup", "after_first_battle", "never", "if_not_renamed" }
local twRadios = {}
for i, mode in ipairs(SHOW_WINDOW_MODES) do
    local radio = CreateFrame("CheckButton", "BPSShowWindowRadio" .. i, optPanel, "UIRadioButtonTemplate")
    if i == 1 then
        radio:SetPoint("TOPLEFT", twIntro, "BOTTOMLEFT", 0, -10)
    else
        radio:SetPoint("TOPLEFT", twRadios[i - 1], "BOTTOMLEFT", 0, -6)
    end
    radio.text = _G[radio:GetName() .. "Text"]
    radio.text:SetWidth(460)
    radio.text:SetJustifyH("LEFT")
    radio:SetScript("OnClick", function()
        BattlePetStatisticsDB.showWindowMode = mode
        for j, r in ipairs(twRadios) do r:SetChecked(j == i) end
    end)
    twRadios[i] = radio
end

-- Group 2: restore pet names to default on logout (2 mutually exclusive radios)
local twRestoreLabel = optPanel:CreateFontString(nil, "OVERLAY", "GameFontHighlightSmall")
twRestoreLabel:SetPoint("TOPLEFT", twRadios[#twRadios], "BOTTOMLEFT", 0, -14)
twRestoreLabel:SetWidth(500)
twRestoreLabel:SetJustifyH("LEFT")

local twRestoreYes = CreateFrame("CheckButton", "BPSRestoreYesRadio", optPanel, "UIRadioButtonTemplate")
twRestoreYes:SetPoint("TOPLEFT", twRestoreLabel, "BOTTOMLEFT", 0, -8)
twRestoreYes.text = _G[twRestoreYes:GetName() .. "Text"]

local twRestoreNo = CreateFrame("CheckButton", "BPSRestoreNoRadio", optPanel, "UIRadioButtonTemplate")
twRestoreNo:SetPoint("LEFT", twRestoreYes.text, "RIGHT", 20, 0)
twRestoreNo.text = _G[twRestoreNo:GetName() .. "Text"]

twRestoreYes:SetScript("OnClick", function()
    BattlePetStatisticsDB.restoreNamesOnLogout = true
    twRestoreYes:SetChecked(true); twRestoreNo:SetChecked(false)
end)
twRestoreNo:SetScript("OnClick", function()
    BattlePetStatisticsDB.restoreNamesOnLogout = false
    twRestoreYes:SetChecked(false); twRestoreNo:SetChecked(true)
end)

-- ===================== STATISTICS TAB =====================

-- ----- Global statistics block -----
local statsHeader = statPanel:CreateFontString(nil, "OVERLAY", "GameFontNormalLarge")
statsHeader:SetPoint("TOPLEFT", 0, 0)

local totalLine = statPanel:CreateFontString(nil, "OVERLAY", "GameFontNormal")
totalLine:SetPoint("TOPLEFT", statsHeader, "BOTTOMLEFT", 4, -8)

local totalWinLine = statPanel:CreateFontString(nil, "OVERLAY", "GameFontHighlight")
totalWinLine:SetPoint("TOPLEFT", totalLine, "BOTTOMLEFT", 12, -2)

local totalLoseLine = statPanel:CreateFontString(nil, "OVERLAY", "GameFontHighlight")
totalLoseLine:SetPoint("TOPLEFT", totalWinLine, "BOTTOMLEFT", 0, -2)

local totalWinrateLine = statPanel:CreateFontString(nil, "OVERLAY", "GameFontHighlight")
totalWinrateLine:SetPoint("TOPLEFT", totalLoseLine, "BOTTOMLEFT", 0, -2)

local sessionCountLine = statPanel:CreateFontString(nil, "OVERLAY", "GameFontNormal")
sessionCountLine:SetPoint("TOPLEFT", totalWinrateLine, "BOTTOMLEFT", -12, -10)

local sessionLine = statPanel:CreateFontString(nil, "OVERLAY", "GameFontNormal")
sessionLine:SetPoint("TOPLEFT", sessionCountLine, "BOTTOMLEFT", 0, -8)

local sessionWinLine = statPanel:CreateFontString(nil, "OVERLAY", "GameFontHighlight")
sessionWinLine:SetPoint("TOPLEFT", sessionLine, "BOTTOMLEFT", 12, -2)

local sessionLoseLine = statPanel:CreateFontString(nil, "OVERLAY", "GameFontHighlight")
sessionLoseLine:SetPoint("TOPLEFT", sessionWinLine, "BOTTOMLEFT", 0, -2)

local sessionWinrateLine = statPanel:CreateFontString(nil, "OVERLAY", "GameFontHighlight")
sessionWinrateLine:SetPoint("TOPLEFT", sessionLoseLine, "BOTTOMLEFT", 0, -2)

-- ----- Fair-play ranking block -----
local fairplayTitle = statPanel:CreateFontString(nil, "OVERLAY", "GameFontNormalLarge")
fairplayTitle:SetPoint("TOPLEFT", sessionWinrateLine, "BOTTOMLEFT", -12, -16)

local fairplayRefreshHint = statPanel:CreateFontString(nil, "OVERLAY", "GameFontDisableSmall")
fairplayRefreshHint:SetPoint("TOPLEFT", fairplayTitle, "BOTTOMLEFT", 0, -2)
fairplayRefreshHint:SetFontObject(GameFontDisableSmall)

local COL_WIDTH_PET   = 163  -- +30% vs the previous 125
local COL_WIDTH_WIN   = 45
local COL_WIDTH_LOSE  = 45
local COL_WIDTH_RATIO = 50

local headerPet   = statPanel:CreateFontString(nil, "OVERLAY", "GameFontNormalSmall")
local headerWin   = statPanel:CreateFontString(nil, "OVERLAY", "GameFontNormalSmall")
local headerLose  = statPanel:CreateFontString(nil, "OVERLAY", "GameFontNormalSmall")
local headerRatio = statPanel:CreateFontString(nil, "OVERLAY", "GameFontNormalSmall")
headerPet:SetPoint("TOPLEFT", fairplayRefreshHint, "BOTTOMLEFT", 4, -10)
headerPet:SetWidth(COL_WIDTH_PET); headerPet:SetJustifyH("LEFT")
headerWin:SetPoint("LEFT", headerPet, "RIGHT", 0, 0)
headerWin:SetWidth(COL_WIDTH_WIN); headerWin:SetJustifyH("LEFT")
headerLose:SetPoint("LEFT", headerWin, "RIGHT", 10, 0)
headerLose:SetWidth(COL_WIDTH_LOSE); headerLose:SetJustifyH("LEFT")
headerRatio:SetPoint("LEFT", headerLose, "RIGHT", 0, 0)
headerRatio:SetWidth(COL_WIDTH_RATIO); headerRatio:SetJustifyH("LEFT")

local listArea = CreateFrame("Frame", nil, statPanel)
listArea:SetPoint("TOPLEFT", headerPet, "BOTTOMLEFT", 0, -6)

local ROW_HEIGHT = 18
local NUM_ROWS   = 10
local rows       = {}
for i = 1, NUM_ROWS do
    local row = CreateFrame("Frame", nil, listArea)
    row:SetPoint("LEFT", listArea, "LEFT", 0, 0)
    row:SetPoint("RIGHT", listArea, "RIGHT", 0, 0)
    row:SetHeight(ROW_HEIGHT)
    if i == 1 then
        row:SetPoint("TOPLEFT", listArea, "TOPLEFT", 0, 0)
    else
        row:SetPoint("TOPLEFT", rows[i - 1], "BOTTOMLEFT", 0, 0)
    end
    row.pet   = row:CreateFontString(nil, "OVERLAY", "GameFontHighlightSmall")
    row.pet:SetPoint("LEFT", 0, 0); row.pet:SetWidth(COL_WIDTH_PET); row.pet:SetJustifyH("LEFT")
    row.win   = row:CreateFontString(nil, "OVERLAY", "GameFontHighlightSmall")
    row.win:SetPoint("LEFT", row.pet, "RIGHT", 0, 0); row.win:SetWidth(COL_WIDTH_WIN); row.win:SetJustifyH("LEFT")
    row.lose  = row:CreateFontString(nil, "OVERLAY", "GameFontHighlightSmall")
    row.lose:SetPoint("LEFT", row.win, "RIGHT", 10, 0); row.lose:SetWidth(COL_WIDTH_LOSE); row.lose:SetJustifyH("LEFT")
    row.ratio = row:CreateFontString(nil, "OVERLAY", "GameFontHighlightSmall")
    row.ratio:SetPoint("LEFT", row.lose, "RIGHT", 0, 0); row.ratio:SetWidth(COL_WIDTH_RATIO); row.ratio:SetJustifyH("LEFT")
    -- Anchored to the fixed-width ratio column (not to the end of its text),
    -- so the buttons line up vertically across every row regardless of how
    -- wide the displayed percentage text is.
    row.editBtn = CreateFrame("Button", nil, row, "UIPanelButtonTemplate")
    row.editBtn:SetSize(55, 14)
    row.editBtn:SetPoint("LEFT", row.ratio, "RIGHT", 10, 0)
    row.deleteBtn = CreateFrame("Button", nil, row, "UIPanelButtonTemplate")
    row.deleteBtn:SetSize(18, 14)
    row.deleteBtn:SetText("x")
    row.deleteBtn:SetPoint("LEFT", row.editBtn, "RIGHT", 4, 0)
    rows[i] = row
end

local noDataText = statPanel:CreateFontString(nil, "OVERLAY", "GameFontDisable")
noDataText:SetPoint("TOP", listArea, "TOP", 0, -40)
noDataText:Hide()

local resetBtn = CreateFrame("Button", nil, statPanel, "UIPanelButtonTemplate")
resetBtn:SetSize(220, 24)
resetBtn:SetPoint("BOTTOM", 0, 4)

-- Pagination: anchored just above the Reset button, so the list area below
-- fills whatever space remains between the table header and the pagination row.
local pageText   = statPanel:CreateFontString(nil, "OVERLAY", "GameFontHighlightSmall")
pageText:SetPoint("BOTTOM", resetBtn, "TOP", 0, 10)
local prevBtn = CreateFrame("Button", nil, statPanel, "UIPanelButtonTemplate")
prevBtn:SetSize(80, 20); prevBtn:SetText("<")
prevBtn:SetPoint("RIGHT", pageText, "LEFT", -10, 0)
local nextBtn = CreateFrame("Button", nil, statPanel, "UIPanelButtonTemplate")
nextBtn:SetSize(80, 20); nextBtn:SetText(">")
nextBtn:SetPoint("LEFT", pageText, "RIGHT", 10, 0)

listArea:SetPoint("BOTTOMRIGHT", statPanel, "BOTTOMRIGHT", -18, 34)
resetBtn:SetScript("OnClick", function()
    local L = BPS_GetLocale()
    StaticPopupDialogs["BPS_RESET_CONFIRM"] = {
        text = L.RESET_CONFIRM, button1 = YES, button2 = NO,
        OnAccept = function() BPS_ResetStats(); BPS_RefreshOptions() end,
        timeout = 0, whileDead = true, hideOnEscape = true, preferredIndex = 3,
    }
    StaticPopup_Show("BPS_RESET_CONFIRM")
end)

-- ===================== Manual edit popup =====================
local editFrame = CreateFrame("Frame", "BPSEditFrame", UIParent, "BackdropTemplate")
editFrame:SetSize(300, 150)
editFrame:SetPoint("CENTER")
editFrame:SetFrameStrata("FULLSCREEN_DIALOG")
editFrame:SetBackdrop({
    bgFile   = "Interface\\Buttons\\WHITE8x8",
    edgeFile = "Interface\\Buttons\\WHITE8x8",
    edgeSize = 1,
})
editFrame:SetBackdropColor(0.08, 0.08, 0.09, 0.97)
editFrame:SetBackdropBorderColor(0.16, 0.55, 0.95, 1)
editFrame:EnableMouse(true)
editFrame:Hide()

local editTitle    = editFrame:CreateFontString(nil, "OVERLAY", "GameFontNormal")
editTitle:SetPoint("TOP", 0, -16); editTitle:SetWidth(260)
local editWLabel   = editFrame:CreateFontString(nil, "OVERLAY", "GameFontHighlight")
editWLabel:SetPoint("TOPLEFT", 24, -46)
local editWBox     = CreateFrame("EditBox", nil, editFrame, "InputBoxTemplate")
editWBox:SetSize(60, 20)
editWBox:SetPoint("LEFT", editWLabel, "RIGHT", 10, 0)
editWBox:SetAutoFocus(false); editWBox:SetNumeric(true)
local editLLabel   = editFrame:CreateFontString(nil, "OVERLAY", "GameFontHighlight")
editLLabel:SetPoint("TOPLEFT", editWLabel, "BOTTOMLEFT", 0, -18)
local editLBox     = CreateFrame("EditBox", nil, editFrame, "InputBoxTemplate")
editLBox:SetSize(60, 20)
editLBox:SetPoint("LEFT", editLLabel, "RIGHT", 10, 0)
editLBox:SetAutoFocus(false); editLBox:SetNumeric(true)
local editSaveBtn  = CreateFrame("Button", nil, editFrame, "UIPanelButtonTemplate")
editSaveBtn:SetSize(100, 22); editSaveBtn:SetPoint("BOTTOMLEFT", 20, 12)
local editCancelBtn = CreateFrame("Button", nil, editFrame, "UIPanelButtonTemplate")
editCancelBtn:SetSize(100, 22); editCancelBtn:SetPoint("BOTTOMRIGHT", -20, 12)
editCancelBtn:SetScript("OnClick", function() editFrame:Hide() end)

local editingKey = nil
local function OpenEditPopup(key, wins, losses)
    local L = BPS_GetLocale()
    editingKey = key
    editTitle:SetText(string.format(L.EDIT_TITLE, key))
    editWLabel:SetText(L.EDIT_WINS)
    editLLabel:SetText(L.EDIT_LOSSES)
    editSaveBtn:SetText(L.SAVE_BUTTON)
    editCancelBtn:SetText(L.CANCEL_BUTTON)
    editWBox:SetText(tostring(wins))
    editLBox:SetText(tostring(losses))
    editFrame:Show()
end

editSaveBtn:SetScript("OnClick", function()
    if editingKey then
        BPS_SetStatsFor(editingKey, tonumber(editWBox:GetText()) or 0, tonumber(editLBox:GetText()) or 0)
    end
    editFrame:Hide()
    BPS_RefreshOptions()
end)

-- ===================== Sorted list + pagination =====================
local sortedCache = {}
local currentPage = 1
local function GetNumPages() return math.max(1, math.ceil(#sortedCache / NUM_ROWS)) end

local function BuildSortedList()
    local list = {}
    for key, e in pairs(BPS_GetAllStats()) do
        local total = e.wins + e.losses
        local winrate = total == 0 and 50 or (e.wins / total) * 100
        table.insert(list, { key=key, wins=e.wins, losses=e.losses, winrate=winrate,
            dist=math.abs(winrate - 50), total=total })
    end
    table.sort(list, function(a, b)
        if a.dist ~= b.dist then return a.dist < b.dist end
        -- Same distance from 50% (e.g. 100% vs 0%): the higher winrate wins.
        if a.winrate ~= b.winrate then return a.winrate > b.winrate end
        return a.total > b.total
    end)
    return list
end

local function UpdatePage()
    local L = BPS_GetLocale()
    local np = GetNumPages()
    currentPage = math.max(1, math.min(currentPage, np))
    local off = (currentPage - 1) * NUM_ROWS
    for i = 1, NUM_ROWS do
        local d = sortedCache[i + off]
        local row = rows[i]
        if d then
            row.pet:SetText(d.key)
            row.win:SetText(d.wins)
            row.lose:SetText(d.losses)
            row.ratio:SetText(string.format("%.0f%%", d.winrate))
            row.editBtn:SetText(BPS_GetLocale().EDIT_BUTTON)
            row.editBtn:SetScript("OnClick", function() OpenEditPopup(d.key, d.wins, d.losses) end)
            row.deleteBtn:SetScript("OnClick", function()
                local Lx = BPS_GetLocale()
                StaticPopupDialogs["BPS_DELETE_ENTRY_CONFIRM"] = {
                    text = string.format(Lx.DELETE_ENTRY_CONFIRM or "Delete stats for %s?", d.key),
                    button1 = YES, button2 = NO,
                    OnAccept = function()
                        BPS_DeleteStatsFor(d.key)
                        BPS_RefreshOptions()
                    end,
                    timeout = 0, whileDead = true, hideOnEscape = true, preferredIndex = 3,
                }
                StaticPopup_Show("BPS_DELETE_ENTRY_CONFIRM")
            end)
            row:Show()
        else
            row:Hide()
        end
    end
    pageText:SetText(string.format("%d / %d", currentPage, np))
    prevBtn:SetEnabled(currentPage > 1)
    nextBtn:SetEnabled(currentPage < np)
end

prevBtn:SetScript("OnClick", function() currentPage = currentPage - 1; UpdatePage() end)
nextBtn:SetScript("OnClick", function() currentPage = currentPage + 1; UpdatePage() end)

-- ===================== Master refresh =====================
function BPS_RefreshOptions()
    EnsureDB()
    local L = BPS_GetLocale()

    -- Tabs
    tabBtns[TAB_OPTIONS].label:SetText(L.OPTIONS_TITLE_TAB or "Options")
    tabBtns[TAB_STATS].label:SetText(L.STATS_TITLE_TAB or "Statistics")

    -- Lang dropdown
    langLabel:SetText(L.LANGUAGE)
    UIDropDownMenu_Initialize(langDropdown, LangDropdown_Init)
    local LANG_LABELS = {
        EN = L.LANG_EN, FR = L.LANG_FR, DE = L.LANG_DE, IT = L.LANG_IT,
        PL = L.LANG_PL, SV = L.LANG_SV, CS = L.LANG_CS,
    }
    local lbl = LANG_LABELS[BattlePetStatisticsDB.language] or L.LANG_AUTO
    UIDropDownMenu_SetText(langDropdown, lbl)

    -- Display checks
    dispTitle:SetText(L.DISPLAY_SECTION_TITLE)
    for i, key in ipairs(DISP_KEYS) do
        local cb = dispChecks[i]
        cb:SetChecked(BattlePetStatisticsDB.display[key] and true or false)
        cb.labelFS:SetText(L[DISP_LKEYS[i]])
    end

    -- Goal section: completed list (green) + dropdown of remaining goals
    goalTitle:SetText(L.GOAL_SECTION_TITLE)
    goalCompletedLabel:SetText(L.GOAL_COMPLETED_LIST_TITLE or "Haut Fait validés :")
    goalCurrentLabel:SetText(L.GOAL_CURRENT)

    local completedGoals = {}
    for _, goal in ipairs(BPS_GOALS) do
        if BPS_IsGoalCompleted(goal.id) then
            table.insert(completedGoals, goal)
        end
    end

    local lastCompletedElement -- whichever element ends up at the bottom of the completed list
    if #completedGoals == 0 then
        goalNoneCompletedText:SetText(L.GOAL_NONE_COMPLETED or "Aucun haut fait validé pour le moment.")
        goalNoneCompletedText:Show()
        for _, fs in ipairs(completedLines) do fs:Hide() end
        lastCompletedElement = goalNoneCompletedText
    else
        goalNoneCompletedText:Hide()
        for i, fs in ipairs(completedLines) do
            local goal = completedGoals[i]
            if goal then
                fs:SetText("[OK] " .. BPS_GetGoalName(goal) .. " (" .. goal.threshold .. "/" .. goal.threshold .. ")")
                fs:Show()
                lastCompletedElement = fs
            else
                fs:Hide()
            end
        end
    end

    -- Re-anchor the "current goal" label right below the last visible completed
    -- element, so the completed list only takes the vertical space it needs.
    goalCurrentLabel:ClearAllPoints()
    goalCurrentLabel:SetPoint("TOPLEFT", lastCompletedElement, "BOTTOMLEFT", -4, -14)

    UIDropDownMenu_Initialize(goalDropdown, GoalDropdown_Init)
    -- Catch up the current goal in case it was already completed before the
    -- player ever opened this panel (e.g. fresh install with pre-existing
    -- achievement progress), so we don't show "All done" prematurely.
    if BPS_AutoAdvanceGoal then BPS_AutoAdvanceGoal() end
    local cg = BPS_GetCurrentGoal()
    if cg and not BPS_IsGoalCompleted(cg.id) then
        local prog = BPS_GetRealProgress(cg)
        UIDropDownMenu_SetText(goalDropdown, string.format("%s (%d/%d)", BPS_GetGoalName(cg), math.min(prog, cg.threshold), cg.threshold))
    else
        UIDropDownMenu_SetText(goalDropdown, L.GOAL_DONE_LINE or "All done!")
    end

    -- Keybindings section
    kbTitle:SetText(L.KEYBIND_SECTION_TITLE)
    kbHint:SetText(L.KEYBIND_HINT)
    kbOpenBtn:SetText(L.OPEN_KEYBINDINGS)

    -- Trade Win Session section
    twTitle:SetText(L.TRADEWIN_SECTION_TITLE)
    twIntro:SetText(L.TRADEWIN_INTRO)
    local SHOW_WINDOW_LABEL_KEYS = {
        "TRADEWIN_SHOW_STARTUP", "TRADEWIN_SHOW_AFTER_BATTLE",
        "TRADEWIN_SHOW_NEVER", "TRADEWIN_SHOW_IF_NOT_RENAMED",
    }
    for i, radio in ipairs(twRadios) do
        radio.text:SetText(L[SHOW_WINDOW_LABEL_KEYS[i]])
        radio:SetChecked(BattlePetStatisticsDB.showWindowMode == SHOW_WINDOW_MODES[i])
    end
    twRestoreLabel:SetText(L.TRADEWIN_RESTORE_QUESTION)
    twRestoreYes.text:SetText(L.TRADEWIN_RESTORE_YES)
    twRestoreNo.text:SetText(L.TRADEWIN_RESTORE_NO)
    twRestoreYes:SetChecked(BattlePetStatisticsDB.restoreNamesOnLogout == true)
    twRestoreNo:SetChecked(BattlePetStatisticsDB.restoreNamesOnLogout == false)

    -- Statistics tab: global stats block
    statsHeader:SetText(L.STATS_GLOBAL_TITLE)
    local allStats = BPS_GetAllStats()
    local totalW, totalL = 0, 0
    for _, e in pairs(allStats) do totalW = totalW + e.wins; totalL = totalL + e.losses end
    local totalGames = totalW + totalL
    local totalWinrate = totalGames == 0 and 0 or (totalW / totalGames) * 100

    totalLine:SetText(string.format(L.TOTAL_GAMES, totalGames))
    totalWinLine:SetText(string.format(L.TOTAL_WON, totalW))
    totalLoseLine:SetText(string.format(L.TOTAL_LOST, totalL))
    totalWinrateLine:SetText(string.format(L.WINRATE, Round(totalWinrate)))

    sessionCountLine:SetText(string.format(L.SESSION_COUNT_LINE, BPS_GetSessionCount()))

    local sW, sL = BPS_GetSessionTotals()
    local sessionGames = sW + sL
    local sessionWinrate = sessionGames == 0 and 0 or (sW / sessionGames) * 100

    sessionLine:SetText(L.SESSION_CURRENT_TITLE)
    sessionWinLine:SetText(string.format(L.TOTAL_WON, sW))
    sessionLoseLine:SetText(string.format(L.TOTAL_LOST, sL))
    sessionWinrateLine:SetText(string.format(L.WINRATE, Round(sessionWinrate)))

    -- Fair-play ranking block
    fairplayTitle:SetText(L.FAIRPLAY_TITLE)
    fairplayRefreshHint:SetText(L.FAIRPLAY_REFRESH_HINT)
    headerPet:SetText(L.COL_PET)
    headerWin:SetText(L.COL_WIN)
    headerLose:SetText(L.COL_LOSE)
    headerRatio:SetText(L.COL_WINRATE)
    resetBtn:SetText(L.RESET_BUTTON)

    sortedCache = BuildSortedList()
    currentPage = 1

    if #sortedCache == 0 then
        noDataText:SetText(L.NO_DATA); noDataText:Show()
        listArea:Hide(); pageText:Hide(); prevBtn:Hide(); nextBtn:Hide()
    else
        noDataText:Hide(); listArea:Show(); pageText:Show(); prevBtn:Show(); nextBtn:Show()
    end
    UpdatePage()
end

function BPS_ToggleOptions()
    EnsureDB()
    if optionsFrame:IsShown() then
        optionsFrame:Hide()
    else
        -- Show Options tab by default
        currentTab = TAB_OPTIONS
        for i, p in ipairs(tabPanels) do
            p:SetShown(i == currentTab)
            StyleTabButton(tabBtns[i], i == currentTab)
        end
        BPS_RefreshOptions()
        optionsFrame:Show()
    end
end
