local _, addonTable = ...
---@type MK
local MK = addonTable.MK
local core = addonTable
local TRANSLATE = core.TRANSLATE or function(msg) return msg end

local GetClassColorByToken = core.GetClassColorByToken or function() return 1, 0.82, 0 end

local CURRENT_CHARACTER_BEST_RUNS_PANEL_WIDTH = 760
local CURRENT_CHARACTER_BEST_RUNS_PANEL_HEADER_HEIGHT = 62
local CURRENT_CHARACTER_BEST_RUNS_PANEL_FOOTER_GAP = 24
local CURRENT_CHARACTER_BEST_RUNS_PANEL_BACKGROUND_INSET = 5
local CURRENT_CHARACTER_BEST_RUNS_PANEL_BACKGROUND_BOTTOM_INSET = 8
local CURRENT_CHARACTER_BEST_RUNS_PANEL_BORDER_INSET_X = 8
local CURRENT_CHARACTER_BEST_RUNS_MAIN_WINDOW_ALPHA = 0
local CURRENT_CHARACTER_BEST_RUNS_ROW_HEIGHT = 60
local CURRENT_CHARACTER_BEST_RUNS_ROW_GAP = 5
local CURRENT_CHARACTER_BEST_RUNS_ROW_IMAGE_WIDTH = 274
local CURRENT_CHARACTER_BEST_RUNS_ROW_IMAGE_INSET = 4
local CURRENT_CHARACTER_BEST_RUNS_ROW_INSET_X = 16
local CURRENT_CHARACTER_BEST_RUNS_TIME_COLUMN_X = 388
local CURRENT_CHARACTER_BEST_RUNS_LEVEL_COLUMN_X = 525
local CURRENT_CHARACTER_BEST_RUNS_SCORE_COLUMN_RIGHT = 28

local function TrySetAtlas(texture, atlas, useAtlasSize)
    if not texture or not atlas or not texture.SetAtlas then
        return false
    end

    local ok = pcall(texture.SetAtlas, texture, atlas, useAtlasSize)
    return ok == true
end

local function CreateSolidTexture(parent, layer, subLevel)
    local texture = parent:CreateTexture(nil, layer or "ARTWORK", nil, subLevel or 0)
    texture:SetTexture("Interface\\Buttons\\WHITE8X8")
    return texture
end

local function WrapColor(text, color)
    return string.format("|c%s%s|r", color or "ffffffff", tostring(text or ""))
end

local function ApplyHorizontalGradient(texture, startR, startG, startB, startA, endR, endG, endB, endA)
    if not texture then
        return
    end

    if texture.SetGradient and CreateColor then
        texture:SetGradient("HORIZONTAL", CreateColor(startR, startG, startB, startA), CreateColor(endR, endG, endB, endA))
    elseif texture.SetGradientAlpha then
        texture:SetGradientAlpha("HORIZONTAL", startR, startG, startB, startA, endR, endG, endB, endA)
    else
        texture:SetVertexColor(endR, endG, endB, math.max(startA or 0, endA or 0) * 0.55)
    end
end

local function ApplyVerticalBlackMask(texture, topAlpha, bottomAlpha)
    if not texture then
        return
    end

    texture:SetTexture("Interface\\Buttons\\WHITE8X8")
    if texture.SetGradient and CreateColor then
        local ok = pcall(texture.SetGradient, texture, "VERTICAL", CreateColor(0, 0, 0, topAlpha), CreateColor(0, 0, 0, bottomAlpha))
        if ok then
            return
        end
    end

    if texture.SetGradientAlpha then
        local ok = pcall(texture.SetGradientAlpha, texture, "VERTICAL", 0, 0, 0, topAlpha, 0, 0, 0, bottomAlpha)
        if ok then
            return
        end
    end

    texture:SetVertexColor(0, 0, 0, math.max(topAlpha or 0, bottomAlpha or 0))
end

local function FormatBestRunDuration(durationMS)
    local duration = tonumber(durationMS) or 0
    if duration <= 0 then
        return "-"
    end

    local totalSeconds = math.floor((duration / 1000) + 0.5)
    local minutes = math.floor(totalSeconds / 60)
    local seconds = totalSeconds - (minutes * 60)
    return string.format("%d:%02d", minutes, seconds)
end

local function GetCharacterBestRunsMap(bestRuns)
    local runsByMapID = {}
    if type(bestRuns) ~= "table" or type(bestRuns.runs) ~= "table" then
        return runsByMapID
    end

    for _, run in ipairs(bestRuns.runs) do
        local mapID = tonumber(run.mapID)
        if mapID then
            runsByMapID[mapID] = run
        end
    end

    return runsByMapID
end

local function ApplyBestRunsPanelImageTexCoords(image, texCoords)
    if not image then
        return
    end

    local left = 0
    local right = 1
    local top = 0
    local bottom = 1
    if texCoords and #texCoords == 4 then
        left = texCoords[1]
        right = texCoords[2]
        top = texCoords[3]
        bottom = texCoords[4]
    end
    image:SetTexCoord(left, right, top, bottom)
end

local function PlayCurrentCharacterBestRunsPanelSound(soundType)
    if not (PlaySound and _G.SOUNDKIT) then
        return
    end

    local soundKit = _G.SOUNDKIT
    local soundID
    if soundType == "open" then
        soundID = soundKit.IG_SPELLBOOK_OPEN
    else
        soundID = soundKit.IG_ABILITY_CLOSE
    end

    if soundID then
        PlaySound(soundID)
    end
end

local function GetCurrentCharacterPlayerModelFrame(owner)
    local widgets = owner and owner.widgets
    local container = widgets and widgets.currentCharacterCard
    local card = container and (container.currentCharacterCard or container.leftCard)
    return card and card.playerModelFrame
end

local function SetCurrentCharacterPlayerModelAlpha(owner, panel, transparent)
    local modelFrame = GetCurrentCharacterPlayerModelFrame(owner)
    if not (modelFrame and modelFrame.SetAlpha and panel) then
        return
    end

    if transparent then
        if panel.mkPlayerModelPreviousAlpha == nil then
            panel.mkPlayerModelPreviousAlpha = modelFrame.GetAlpha and modelFrame:GetAlpha() or 1
        end
        if panel.mkPlayerModelWasShown == nil then
            panel.mkPlayerModelWasShown = modelFrame.IsShown and modelFrame:IsShown() or false
        end
        modelFrame:SetAlpha(CURRENT_CHARACTER_BEST_RUNS_MAIN_WINDOW_ALPHA)
        if modelFrame.Hide then
            modelFrame:Hide()
        end
        return
    end

    if panel.mkPlayerModelPreviousAlpha == nil and panel.mkPlayerModelWasShown == nil then
        return
    end

    local previousAlpha = tonumber(panel.mkPlayerModelPreviousAlpha) or 1
    local wasShown = panel.mkPlayerModelWasShown == true
    panel.mkPlayerModelPreviousAlpha = nil
    panel.mkPlayerModelWasShown = nil

    modelFrame:SetAlpha(previousAlpha)
    if wasShown and modelFrame.Show then
        modelFrame:Show()
    elseif not wasShown and modelFrame.Hide then
        modelFrame:Hide()
    end
end

local function SetCurrentCharacterBestRunsMainWindowAlpha(owner, panel, transparent)
    local mainWindow = owner and owner.mainWindow
    if not (mainWindow and mainWindow.SetAlpha and panel) then
        return
    end

    if transparent then
        if panel.mkMainWindowPreviousAlpha == nil then
            panel.mkMainWindowPreviousAlpha = mainWindow.GetAlpha and mainWindow:GetAlpha() or 1
        end
        mainWindow:SetAlpha(CURRENT_CHARACTER_BEST_RUNS_MAIN_WINDOW_ALPHA)
        SetCurrentCharacterPlayerModelAlpha(owner, panel, true)
        return
    end

    local previousAlpha = tonumber(panel.mkMainWindowPreviousAlpha) or 1
    panel.mkMainWindowPreviousAlpha = nil
    mainWindow:SetAlpha(previousAlpha)
    SetCurrentCharacterPlayerModelAlpha(owner, panel, false)
end

local function ApplyCurrentCharacterBestRunsPanelBackplate(panel)
    if not panel then
        return
    end

    if panel.SetBackdrop then
        panel:SetBackdrop(nil)
    end

    if not panel.mkTransmogPanelBackground then
        panel.mkTransmogPanelBackground = panel:CreateTexture(nil, "BACKGROUND", nil, -4)
        panel.mkTransmogPanelDarkOverlay = panel:CreateTexture(nil, "BACKGROUND", nil, -3)

        local topGradient = panel:CreateTexture(nil, "BACKGROUND", nil, -2)
        topGradient:SetHeight(92)
        panel.mkTransmogPanelTopGradient = topGradient

        local bottomGradient = panel:CreateTexture(nil, "BACKGROUND", nil, -2)
        bottomGradient:SetHeight(92)
        panel.mkTransmogPanelBottomGradient = bottomGradient

        local borderFrame = CreateFrame("Frame", nil, panel)
        borderFrame:SetPoint("TOPLEFT", panel, "TOPLEFT", -CURRENT_CHARACTER_BEST_RUNS_PANEL_BORDER_INSET_X, 12)
        borderFrame:SetPoint("BOTTOMRIGHT", panel, "BOTTOMRIGHT", CURRENT_CHARACTER_BEST_RUNS_PANEL_BORDER_INSET_X, -6)
        borderFrame:EnableMouse(false)
        panel.mkTransmogPanelBorderFrame = borderFrame

        local border = borderFrame:CreateTexture(nil, "ARTWORK")
        border:SetAllPoints(borderFrame)
        panel.mkTransmogPanelBorder = border
    end

    panel.mkTransmogPanelBackground:ClearAllPoints()
    panel.mkTransmogPanelBackground:SetPoint("TOPLEFT", panel, "TOPLEFT", CURRENT_CHARACTER_BEST_RUNS_PANEL_BACKGROUND_INSET, -CURRENT_CHARACTER_BEST_RUNS_PANEL_BACKGROUND_INSET)
    panel.mkTransmogPanelBackground:SetPoint("BOTTOMRIGHT", panel, "BOTTOMRIGHT", -CURRENT_CHARACTER_BEST_RUNS_PANEL_BACKGROUND_INSET, CURRENT_CHARACTER_BEST_RUNS_PANEL_BACKGROUND_BOTTOM_INSET)
    panel.mkTransmogPanelBackground:SetDrawLayer("BACKGROUND", -4)

    panel.mkTransmogPanelDarkOverlay:ClearAllPoints()
    panel.mkTransmogPanelDarkOverlay:SetAllPoints(panel.mkTransmogPanelBackground)
    panel.mkTransmogPanelDarkOverlay:SetDrawLayer("BACKGROUND", -1)

    panel.mkTransmogPanelTopGradient:ClearAllPoints()
    panel.mkTransmogPanelTopGradient:SetPoint("TOPLEFT", panel, "TOPLEFT", CURRENT_CHARACTER_BEST_RUNS_PANEL_BACKGROUND_INSET, -CURRENT_CHARACTER_BEST_RUNS_PANEL_BACKGROUND_INSET)
    panel.mkTransmogPanelTopGradient:SetPoint("TOPRIGHT", panel, "TOPRIGHT", -CURRENT_CHARACTER_BEST_RUNS_PANEL_BACKGROUND_INSET, -CURRENT_CHARACTER_BEST_RUNS_PANEL_BACKGROUND_INSET)
    panel.mkTransmogPanelTopGradient:SetDrawLayer("BACKGROUND", -2)

    panel.mkTransmogPanelBottomGradient:ClearAllPoints()
    panel.mkTransmogPanelBottomGradient:SetPoint("BOTTOMLEFT", panel, "BOTTOMLEFT", CURRENT_CHARACTER_BEST_RUNS_PANEL_BACKGROUND_INSET, CURRENT_CHARACTER_BEST_RUNS_PANEL_BACKGROUND_BOTTOM_INSET)
    panel.mkTransmogPanelBottomGradient:SetPoint("BOTTOMRIGHT", panel, "BOTTOMRIGHT", -CURRENT_CHARACTER_BEST_RUNS_PANEL_BACKGROUND_INSET, CURRENT_CHARACTER_BEST_RUNS_PANEL_BACKGROUND_BOTTOM_INSET)
    panel.mkTransmogPanelBottomGradient:SetDrawLayer("BACKGROUND", -2)

    if panel.mkTransmogPanelBorderFrame.SetFrameLevel and panel.GetFrameLevel then
        panel.mkTransmogPanelBorderFrame:SetFrameLevel((panel:GetFrameLevel() or 0) + 12)
    end

    if not TrySetAtlas(panel.mkTransmogPanelBackground, "transmog-outfit-darkbg", false) then
        panel.mkTransmogPanelBackground:SetTexture("Interface\\Buttons\\WHITE8X8")
        panel.mkTransmogPanelBackground:SetVertexColor(0.02, 0.018, 0.014, 0.96)
    else
        panel.mkTransmogPanelBackground:SetVertexColor(1, 1, 1, 1)
    end

    ApplyVerticalBlackMask(panel.mkTransmogPanelDarkOverlay, 0.20, 0.74)
    TrySetAtlas(panel.mkTransmogPanelTopGradient, "transmog-outfit-toptexture", false)
    panel.mkTransmogPanelTopGradient:SetVertexColor(1, 1, 1, 1)
    TrySetAtlas(panel.mkTransmogPanelBottomGradient, "transmog-outfit-bottomtexture", false)
    panel.mkTransmogPanelBottomGradient:SetVertexColor(1, 1, 1, 1)
    TrySetAtlas(panel.mkTransmogPanelBorder, "transmog-tabs-frame", false)
    panel.mkTransmogPanelBorder:SetVertexColor(1, 1, 1, 1)
end

local function GetPlainCurrentCharacterName(character, characterKey)
    local name = character and character.name or characterKey or (UnitName("player") or TRANSLATE("未知"))
    if type(name) ~= "string" or name == "" then
        name = UnitName("player") or TRANSLATE("未知")
    end

    if name:find("-", 1, true) then
        return name
    end

    local realm = character and character.realm or GetRealmName()
    if type(realm) == "string" and realm ~= "" then
        return string.format("%s-%s", name, realm)
    end

    return name
end

local function CreateCurrentCharacterBestRunRow(parent)
    local row = CreateFrame("Frame", nil, parent, "BackdropTemplate")
    row:SetHeight(CURRENT_CHARACTER_BEST_RUNS_ROW_HEIGHT)
    if row.SetBackdrop then
        row:SetBackdrop({
            bgFile = "Interface\\Buttons\\WHITE8X8",
            edgeFile = "Interface\\Tooltips\\UI-Tooltip-Border",
            tile = false,
            edgeSize = 10,
            insets = { left = 3, right = 3, top = 3, bottom = 3 },
        })
        row:SetBackdropColor(0.015, 0.015, 0.015, 0.88)
        row:SetBackdropBorderColor(1, 1, 1, 0.18)
    end

    local image = row:CreateTexture(nil, "ARTWORK", nil, -1)
    image:SetPoint("TOPLEFT", row, "TOPLEFT", CURRENT_CHARACTER_BEST_RUNS_ROW_IMAGE_INSET, -CURRENT_CHARACTER_BEST_RUNS_ROW_IMAGE_INSET)
    image:SetPoint("BOTTOMLEFT", row, "BOTTOMLEFT", CURRENT_CHARACTER_BEST_RUNS_ROW_IMAGE_INSET, CURRENT_CHARACTER_BEST_RUNS_ROW_IMAGE_INSET)
    image:SetWidth(CURRENT_CHARACTER_BEST_RUNS_ROW_IMAGE_WIDTH - CURRENT_CHARACTER_BEST_RUNS_ROW_IMAGE_INSET)
    image:SetVertexColor(1, 1, 1, 0.70)

    local imageShade = CreateSolidTexture(row, "ARTWORK", 0)
    imageShade:SetAllPoints(image)
    imageShade:SetVertexColor(0, 0, 0, 0.28)

    local imageFade = CreateSolidTexture(row, "ARTWORK", 1)
    imageFade:SetAllPoints(image)
    ApplyHorizontalGradient(imageFade, 0, 0, 0, 0.10, 0, 0, 0, 0.86)

    local topLine = CreateSolidTexture(row, "OVERLAY", 1)
    topLine:SetPoint("TOPLEFT", row, "TOPLEFT", 8, -1)
    topLine:SetPoint("TOPRIGHT", row, "TOPRIGHT", -8, -1)
    topLine:SetHeight(1)
    topLine:SetVertexColor(1, 1, 1, 0.12)

    local bottomLine = CreateSolidTexture(row, "OVERLAY", 1)
    bottomLine:SetPoint("BOTTOMLEFT", row, "BOTTOMLEFT", 8, 1)
    bottomLine:SetPoint("BOTTOMRIGHT", row, "BOTTOMRIGHT", -8, 1)
    bottomLine:SetHeight(1)
    bottomLine:SetVertexColor(1, 1, 1, 0.12)

    local dungeonName = row:CreateFontString(nil, "OVERLAY", "GameFontHighlight")
    dungeonName:SetPoint("LEFT", row, "LEFT", CURRENT_CHARACTER_BEST_RUNS_ROW_INSET_X, 0)
    dungeonName:SetWidth(CURRENT_CHARACTER_BEST_RUNS_ROW_IMAGE_WIDTH - (CURRENT_CHARACTER_BEST_RUNS_ROW_INSET_X * 2))
    dungeonName:SetJustifyH("LEFT")
    dungeonName:SetTextColor(1, 1, 1, 0.98)
    if core.ApplyFont then
        core.ApplyFont(dungeonName, 15, "OUTLINE")
    end

    local timeLabel = row:CreateFontString(nil, "OVERLAY", "GameFontHighlightLarge")
    timeLabel:SetPoint("LEFT", row, "LEFT", CURRENT_CHARACTER_BEST_RUNS_TIME_COLUMN_X, 0)
    timeLabel:SetWidth(88)
    timeLabel:SetJustifyH("CENTER")
    timeLabel:SetTextColor(1, 1, 1, 0.96)
    if core.ApplyFont then
        core.ApplyFont(timeLabel, 18, "")
    end

    local levelLabel = row:CreateFontString(nil, "OVERLAY", "GameFontHighlightLarge")
    levelLabel:SetPoint("LEFT", row, "LEFT", CURRENT_CHARACTER_BEST_RUNS_LEVEL_COLUMN_X, 0)
    levelLabel:SetWidth(92)
    levelLabel:SetJustifyH("CENTER")
    levelLabel:SetTextColor(1, 1, 1, 0.98)
    if core.ApplyFont then
        core.ApplyFont(levelLabel, 28, "")
    end

    local scoreLabel = row:CreateFontString(nil, "OVERLAY", "GameFontHighlightLarge")
    scoreLabel:SetPoint("RIGHT", row, "RIGHT", -CURRENT_CHARACTER_BEST_RUNS_SCORE_COLUMN_RIGHT, 0)
    scoreLabel:SetWidth(120)
    scoreLabel:SetJustifyH("RIGHT")
    scoreLabel:SetTextColor(0.98, 0.82, 0.38, 1)
    if core.ApplyFont then
        core.ApplyFont(scoreLabel, 26, "")
    end

    row.image = image
    row.imageShade = imageShade
    row.imageFade = imageFade
    row.dungeonName = dungeonName
    row.timeLabel = timeLabel
    row.levelLabel = levelLabel
    row.scoreLabel = scoreLabel
    return row
end

local function EnsureCurrentCharacterBestRunRows(panel, requiredCount)
    panel.rows = panel.rows or {}
    while #panel.rows < requiredCount do
        panel.rows[#panel.rows + 1] = CreateCurrentCharacterBestRunRow(panel.rowsContainer)
    end
end

local function GetBestRunDungeonName(owner, mapID)
    if owner and owner.GetAbbreviatedDungeonName then
        return owner:GetAbbreviatedDungeonName(mapID)
    end
    if mapID then
        return tostring(mapID)
    end
    return TRANSLATE("未知地下城")
end

local function BuildCurrentCharacterBestRunRows(owner, character)
    local liveBestRuns
    if owner and owner.GetPlayerMythicPlusBestRuns then
        liveBestRuns = owner:GetPlayerMythicPlusBestRuns("player")
    end

    local bestRuns = liveBestRuns or (character and character.bestRuns)
    local runsByMapID = GetCharacterBestRunsMap(bestRuns)
    local rowData = {}
    local mapIDs = owner and owner.GetCurrentSeasonDungeonMapIDs and owner:GetCurrentSeasonDungeonMapIDs() or {}

    if type(mapIDs) == "table" and #mapIDs > 0 then
        for _, mapID in ipairs(mapIDs) do
            rowData[#rowData + 1] = {
                mapID = mapID,
                run = runsByMapID[mapID],
            }
        end
    elseif type(bestRuns) == "table" and type(bestRuns.runs) == "table" then
        for _, run in ipairs(bestRuns.runs) do
            if tonumber(run.mapID) then
                rowData[#rowData + 1] = {
                    mapID = tonumber(run.mapID),
                    run = run,
                }
            end
        end
    end

    return rowData, bestRuns
end

local function UpdateCurrentCharacterBestRunRow(owner, row, data)
    if not row or type(data) ~= "table" then
        return
    end

    local mapID = tonumber(data.mapID)
    local run = data.run
    local texturePath, texCoords
    if owner and owner.GetDungeonJournalTexture and mapID then
        texturePath, texCoords = owner:GetDungeonJournalTexture(mapID)
    end

    if texturePath then
        row.image:SetTexture(texturePath)
        row.image:SetVertexColor(1, 1, 1, 0.70)
        ApplyBestRunsPanelImageTexCoords(row.image, texCoords)
    else
        row.image:SetTexture("Interface\\Buttons\\WHITE8X8")
        row.image:SetVertexColor(0.08, 0.10, 0.12, 1)
        row.image:SetTexCoord(0, 1, 0, 1)
    end

    row.dungeonName:SetText(GetBestRunDungeonName(owner, mapID))

    local level = run and tonumber(run.level) or 0
    local score = run and tonumber(run.score) or 0
    if level and level > 0 then
        row.timeLabel:SetText(FormatBestRunDuration(run.durationMS))
        row.timeLabel:SetTextColor(1, 1, 1, 0.96)
        row.levelLabel:SetText("+" .. tostring(level))
        row.levelLabel:SetTextColor(1, 1, 1, 0.98)
        row.scoreLabel:SetText(tostring(math.floor((score or 0) + 0.5)))
        if owner and owner.GetSpecificDungeonScoreColor then
            local scoreR, scoreG, scoreB = owner:GetSpecificDungeonScoreColor(score)
            row.scoreLabel:SetTextColor(scoreR, scoreG, scoreB, 1)
        else
            row.scoreLabel:SetTextColor(1, 1, 1, 0.95)
        end
    else
        row.timeLabel:SetText("-")
        row.timeLabel:SetTextColor(0.55, 0.55, 0.55, 0.92)
        row.levelLabel:SetText("-")
        row.levelLabel:SetTextColor(0.55, 0.55, 0.55, 0.92)
        row.scoreLabel:SetText(TRANSLATE("无记录"))
        row.scoreLabel:SetTextColor(0.55, 0.55, 0.55, 0.92)
    end

    row:Show()
end

local function LayoutCurrentCharacterBestRunsPanel(panel, rowCount)
    local rowsHeight = 0
    if rowCount > 0 then
        rowsHeight = (rowCount * CURRENT_CHARACTER_BEST_RUNS_ROW_HEIGHT) + ((rowCount - 1) * CURRENT_CHARACTER_BEST_RUNS_ROW_GAP)
    end

    local contentWidth = CURRENT_CHARACTER_BEST_RUNS_PANEL_WIDTH - (CURRENT_CHARACTER_BEST_RUNS_ROW_INSET_X * 2)
    local panelHeight = CURRENT_CHARACTER_BEST_RUNS_PANEL_HEADER_HEIGHT + math.max(rowsHeight, 54) + CURRENT_CHARACTER_BEST_RUNS_PANEL_FOOTER_GAP
    panel:SetSize(CURRENT_CHARACTER_BEST_RUNS_PANEL_WIDTH, panelHeight)
    ApplyCurrentCharacterBestRunsPanelBackplate(panel)
    panel.rowsContainer:SetSize(contentWidth, rowsHeight)
    panel.emptyLabel:SetWidth(contentWidth)

    for index, row in ipairs(panel.rows or {}) do
        row:ClearAllPoints()
        if index <= rowCount then
            row:SetPoint("TOPLEFT", panel.rowsContainer, "TOPLEFT", 0, -((index - 1) * (CURRENT_CHARACTER_BEST_RUNS_ROW_HEIGHT + CURRENT_CHARACTER_BEST_RUNS_ROW_GAP)))
            row:SetPoint("TOPRIGHT", panel.rowsContainer, "TOPRIGHT", 0, -((index - 1) * (CURRENT_CHARACTER_BEST_RUNS_ROW_HEIGHT + CURRENT_CHARACTER_BEST_RUNS_ROW_GAP)))
        end
    end
end

local function UpdateCurrentCharacterBestRunsPanelHeader(owner, panel, character, characterKey, bestRuns)
    local classToken = character and character.class or select(2, UnitClass("player"))
    local classR, classG, classB = GetClassColorByToken(classToken)
    local score = (bestRuns and tonumber(bestRuns.score)) or (character and tonumber(character.rating)) or 0

    panel.titleLabel:SetText(TRANSLATE("赛季地下城最佳记录"))
    panel.nameLabel:SetText(GetPlainCurrentCharacterName(character, characterKey))
    panel.nameLabel:SetTextColor(classR, classG, classB, 1)

    local scoreColor = owner and owner.GetDungeonScoreColorString and owner:GetDungeonScoreColorString(score) or "ffffffff"
    panel.scoreLabel:SetText(string.format("%s%s", WrapColor(TRANSLATE("赛季评分") .. "：", "ffffd100"), WrapColor(math.floor(score + 0.5), scoreColor)))
    panel.scoreLabel:SetTextColor(1, 1, 1, 1)
end

function MK:GetCurrentCharacterBestRunsPanel()
    self.widgets = self.widgets or {}
    if self.widgets.currentCharacterBestRunsPanel then
        return self.widgets.currentCharacterBestRunsPanel
    end

    local panel = CreateFrame("Frame", "MKCurrentCharacterBestRunsPanel", UIParent, "BackdropTemplate")
    panel:SetFrameStrata("DIALOG")
    panel:SetFrameLevel(200)
    if panel.SetToplevel then
        panel:SetToplevel(true)
    end
    panel:SetClampedToScreen(true)
    panel:SetMovable(true)
    panel:EnableMouse(true)
    panel:RegisterForDrag("LeftButton")
    panel:SetScript("OnDragStart", function(frame)
        frame:StartMoving()
    end)
    panel:SetScript("OnDragStop", function(frame)
        frame:StopMovingOrSizing()
    end)
    panel:Hide()
    panel:SetScript("OnShow", function(frame)
        SetCurrentCharacterBestRunsMainWindowAlpha(self, frame, true)
        PlayCurrentCharacterBestRunsPanelSound("open")
    end)
    panel:SetScript("OnHide", function(frame)
        SetCurrentCharacterBestRunsMainWindowAlpha(self, frame, false)
        PlayCurrentCharacterBestRunsPanelSound("close")
    end)
    ApplyCurrentCharacterBestRunsPanelBackplate(panel)

    local titleLabel = panel:CreateFontString(nil, "OVERLAY", "GameFontNormalLarge")
    titleLabel:SetPoint("TOP", panel, "TOP", 0, -16)
    titleLabel:SetJustifyH("CENTER")
    titleLabel:SetTextColor(1, 0.82, 0, 1)
    if core.ApplyFont then
        core.ApplyFont(titleLabel, 16, "OUTLINE")
    end

    local nameLabel = panel:CreateFontString(nil, "OVERLAY", "GameFontHighlight")
    nameLabel:SetPoint("TOPLEFT", panel, "TOPLEFT", CURRENT_CHARACTER_BEST_RUNS_ROW_INSET_X, -39)
    nameLabel:SetWidth(360)
    nameLabel:SetJustifyH("LEFT")
    if core.ApplyFont then
        core.ApplyFont(nameLabel, 13, "OUTLINE")
    end

    local scoreLabel = panel:CreateFontString(nil, "OVERLAY", "GameFontHighlight")
    scoreLabel:SetPoint("TOPRIGHT", panel, "TOPRIGHT", -CURRENT_CHARACTER_BEST_RUNS_ROW_INSET_X, -39)
    scoreLabel:SetWidth(260)
    scoreLabel:SetJustifyH("RIGHT")
    if core.ApplyFont then
        core.ApplyFont(scoreLabel, 13, "OUTLINE")
    end

    local rowsContainer = CreateFrame("Frame", nil, panel)
    rowsContainer:SetPoint("TOPLEFT", panel, "TOPLEFT", CURRENT_CHARACTER_BEST_RUNS_ROW_INSET_X, -CURRENT_CHARACTER_BEST_RUNS_PANEL_HEADER_HEIGHT)

    local emptyLabel = panel:CreateFontString(nil, "OVERLAY", "GameFontHighlight")
    emptyLabel:SetPoint("TOP", rowsContainer, "TOP", 0, -18)
    emptyLabel:SetJustifyH("CENTER")
    emptyLabel:SetText(TRANSLATE("无记录"))
    emptyLabel:SetTextColor(0.65, 0.65, 0.65, 0.95)
    if core.ApplyFont then
        core.ApplyFont(emptyLabel, 14, "")
    end
    emptyLabel:Hide()

    local closeButton = CreateFrame("Button", nil, panel, "UIPanelCloseButton")
    closeButton:SetPoint("TOPRIGHT", panel, "TOPRIGHT", -3, -3)
    if closeButton.SetFrameLevel and panel.GetFrameLevel then
        closeButton:SetFrameLevel((panel:GetFrameLevel() or 0) + 20)
    end
    closeButton:SetScript("OnClick", function()
        panel:Hide()
    end)

    if type(UISpecialFrames) == "table" and panel:GetName() then
        table.insert(UISpecialFrames, panel:GetName())
    end

    if self.mainWindow and self.mainWindow.HookScript then
        self.mainWindow:HookScript("OnHide", function()
            panel:Hide()
        end)
    end

    panel.titleLabel = titleLabel
    panel.nameLabel = nameLabel
    panel.scoreLabel = scoreLabel
    panel.rowsContainer = rowsContainer
    panel.emptyLabel = emptyLabel
    panel.closeButton = closeButton
    panel.rows = {}

    self.widgets.currentCharacterBestRunsPanel = panel
    return panel
end

function MK:ShowCurrentCharacterBestRunsPanel(character, characterKey)
    local panel = self:GetCurrentCharacterBestRunsPanel()
    if not panel then
        return
    end

    local rowData, bestRuns = BuildCurrentCharacterBestRunRows(self, character)
    UpdateCurrentCharacterBestRunsPanelHeader(self, panel, character, characterKey, bestRuns)
    EnsureCurrentCharacterBestRunRows(panel, #rowData)
    LayoutCurrentCharacterBestRunsPanel(panel, #rowData)

    for index, row in ipairs(panel.rows or {}) do
        if index <= #rowData then
            UpdateCurrentCharacterBestRunRow(self, row, rowData[index])
        else
            row:Hide()
        end
    end

    if #rowData <= 0 then
        panel.emptyLabel:Show()
    else
        panel.emptyLabel:Hide()
    end

    panel.characterKey = characterKey
    panel:ClearAllPoints()
    if self.mainWindow and self.mainWindow:IsShown() then
        panel:SetPoint("CENTER", self.mainWindow, "CENTER", 0, -8)
    else
        panel:SetPoint("CENTER", UIParent, "CENTER", 0, 0)
    end
    panel:Show()
    if panel.Raise then
        panel:Raise()
    end
end
