-- WoWTetris UI v5.1
-- Premium WoW-Inspired Interface

local addonName, addon = ...

local mainFrame, menuFrame, gameFrame, gameBoard, boardBlocks
local nextPieceFrames, holdPieceFrame
local scoreText, levelText, linesText, timeText
local xpBar, xpText, classLevelText
local pauseOverlay, gameOverOverlay, levelUpOverlay
local ultimateFrame, ultimateCooldownText
local boardBackground

-- Level Rank System
local LEVEL_RANKS = {
    {minLevel = 1, maxLevel = 4, name = "Bronze", color = "|cffcd7f32", rgb = {0.8, 0.5, 0.2}},
    {minLevel = 5, maxLevel = 9, name = "Silver", color = "|cffc0c0c0", rgb = {0.75, 0.75, 0.75}},
    {minLevel = 10, maxLevel = 14, name = "Gold", color = "|cffffd700", rgb = {1, 0.84, 0}},
    {minLevel = 15, maxLevel = 19, name = "Platinum", color = "|cffe5e4e2", rgb = {0.9, 0.89, 0.88}},
    {minLevel = 20, maxLevel = 29, name = "Diamond", color = "|cff40e0d0", rgb = {0.25, 0.88, 0.82}},
    {minLevel = 30, maxLevel = 39, name = "Master", color = "|cffff8000", rgb = {1, 0.5, 0}},
    {minLevel = 40, maxLevel = 49, name = "Grandmaster", color = "|cffa335ee", rgb = {0.64, 0.21, 0.93}},
    {minLevel = 50, maxLevel = 999, name = "Legend", color = "|cffe6cc80", rgb = {0.9, 0.8, 0.5}},
}

function addon:GetLevelRank(level)
    for _, rank in ipairs(LEVEL_RANKS) do
        if level >= rank.minLevel and level <= rank.maxLevel then return rank end
    end
    return LEVEL_RANKS[1]
end

local function CreateBlock(parent, size)
    local f = CreateFrame("Frame", nil, parent)
    f:SetSize(size, size)
    f.tex = f:CreateTexture(nil, "ARTWORK")
    f.tex:SetAllPoints()
    f.tex:SetTexCoord(0.08, 0.92, 0.08, 0.92)
    f.bg = f:CreateTexture(nil, "BACKGROUND")
    f.bg:SetAllPoints()
    f.bg:SetColorTexture(0.02, 0.02, 0.04, 0.5)
    return f
end

local function CreateStyledPanel(parent, width, height, style)
    local f = CreateFrame("Frame", nil, parent, "BackdropTemplate")
    f:SetSize(width, height)
    if style == "dark" then
        f: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}})
        f:SetBackdropColor(0.05, 0.05, 0.08, 0.95)
        f:SetBackdropBorderColor(0.3, 0.3, 0.35, 1)
    elseif style == "gold" then
        f:SetBackdrop({bgFile = "Interface\\ChatFrame\\ChatFrameBackground", edgeFile = "Interface\\DialogFrame\\UI-DialogBox-Gold-Border", tile = true, tileSize = 16, edgeSize = 20, insets = {left=5, right=5, top=5, bottom=5}})
        f:SetBackdropColor(0.08, 0.06, 0.03, 0.95)
    elseif style == "pvp" then
        f: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}})
        f:SetBackdropColor(0.15, 0.05, 0.05, 0.95)
        f:SetBackdropBorderColor(0.6, 0.2, 0.2, 1)
    else
        f:SetBackdrop({bgFile = "Interface\\ChatFrame\\ChatFrameBackground", edgeFile = "Interface\\Tooltips\\UI-Tooltip-Border", tile = true, tileSize = 16, edgeSize = 10, insets = {left=2, right=2, top=2, bottom=2}})
        f:SetBackdropColor(0.06, 0.06, 0.08, 0.9)
        f:SetBackdropBorderColor(0.4, 0.4, 0.45, 1)
    end
    return f
end

local function CreateMenuButton(parent, width, height, text, isGold)
    local btn = CreateFrame("Button", nil, parent, "BackdropTemplate")
    btn:SetSize(width, height)
    if isGold then
        btn:SetBackdrop({bgFile = "Interface\\ChatFrame\\ChatFrameBackground", edgeFile = "Interface\\DialogFrame\\UI-DialogBox-Gold-Border", tile = true, tileSize = 16, edgeSize = 16, insets = {left=4, right=4, top=4, bottom=4}})
        btn:SetBackdropColor(0.2, 0.15, 0.05, 0.95)
    else
        btn:SetBackdrop({bgFile = "Interface\\ChatFrame\\ChatFrameBackground", edgeFile = "Interface\\Tooltips\\UI-Tooltip-Border", tile = true, tileSize = 16, edgeSize = 14, insets = {left=3, right=3, top=3, bottom=3}})
        btn:SetBackdropColor(0.08, 0.08, 0.12, 0.95)
        btn:SetBackdropBorderColor(0.4, 0.4, 0.5, 1)
    end
    btn.text = btn:CreateFontString(nil, "OVERLAY", "GameFontNormalLarge")
    btn.text:SetPoint("CENTER")
    btn.text:SetText(text)
    btn:SetScript("OnEnter", function(self)
        if isGold then self:SetBackdropColor(0.35, 0.25, 0.1, 1)
        else self:SetBackdropColor(0.15, 0.15, 0.2, 1) self:SetBackdropBorderColor(0.6, 0.6, 0.7, 1) end
    end)
    btn:SetScript("OnLeave", function(self)
        if isGold then self:SetBackdropColor(0.2, 0.15, 0.05, 0.95)
        else self:SetBackdropColor(0.08, 0.08, 0.12, 0.95) self:SetBackdropBorderColor(0.4, 0.4, 0.5, 1) end
    end)
    return btn
end

local function CreateSmallButton(parent, width, height, text, style)
    local btn = CreateFrame("Button", nil, parent, "BackdropTemplate")
    btn:SetSize(width, height)
    if style == "gold" then
        btn:SetBackdrop({bgFile = "Interface\\ChatFrame\\ChatFrameBackground", edgeFile = "Interface\\DialogFrame\\UI-DialogBox-Gold-Border", tile = true, tileSize = 16, edgeSize = 12, insets = {left=3, right=3, top=3, bottom=3}})
        btn:SetBackdropColor(0.15, 0.12, 0.05, 0.95)
    elseif style == "red" then
        btn:SetBackdrop({bgFile = "Interface\\ChatFrame\\ChatFrameBackground", edgeFile = "Interface\\Tooltips\\UI-Tooltip-Border", tile = true, tileSize = 16, edgeSize = 10, insets = {left=2, right=2, top=2, bottom=2}})
        btn:SetBackdropColor(0.4, 0.1, 0.1, 0.95)
        btn:SetBackdropBorderColor(0.7, 0.2, 0.2, 1)
    else
        btn:SetBackdrop({bgFile = "Interface\\ChatFrame\\ChatFrameBackground", edgeFile = "Interface\\Tooltips\\UI-Tooltip-Border", tile = true, tileSize = 16, edgeSize = 10, insets = {left=2, right=2, top=2, bottom=2}})
        btn:SetBackdropColor(0.1, 0.1, 0.12, 0.95)
        btn:SetBackdropBorderColor(0.4, 0.4, 0.45, 1)
    end
    btn.text = btn:CreateFontString(nil, "OVERLAY", "GameFontNormal")
    btn.text:SetPoint("CENTER")
    btn.text:SetText(text)
    btn:SetScript("OnEnter", function(self) self:SetBackdropColor(0.2, 0.2, 0.25, 1) end)
    btn:SetScript("OnLeave", function(self)
        if style == "gold" then self:SetBackdropColor(0.15, 0.12, 0.05, 0.95)
        elseif style == "red" then self:SetBackdropColor(0.4, 0.1, 0.1, 0.95)
        else self:SetBackdropColor(0.1, 0.1, 0.12, 0.95) end
    end)
    return btn
end

local function RenderPreview(frame, pieceType)
    for _, b in ipairs(frame.blocks) do b:Hide() b:ClearAllPoints() end
    if not pieceType then return end
    local blocks = addon:GetPieceBlocks(pieceType, 0)
    local tex = addon:GetPieceTexture(pieceType)
    local minX, maxX, minY, maxY = 10, -10, 10, -10
    for _, b in ipairs(blocks) do
        minX, maxX = math.min(minX, b[1]), math.max(maxX, b[1])
        minY, maxY = math.min(minY, b[2]), math.max(maxY, b[2])
    end
    local bw, bh = maxX - minX + 1, maxY - minY + 1
    local bs = math.min((frame:GetWidth()-8)/bw, (frame:GetHeight()-8)/bh, 16)
    local ox = (frame:GetWidth() - bw*bs) / 2
    local oy = (frame:GetHeight() - bh*bs) / 2
    for i, pb in ipairs(blocks) do
        local b = frame.blocks[i]
        if b then
            b:SetSize(bs-1, bs-1)
            b.tex:SetTexture(tex)
            b.tex:SetVertexColor(1, 1, 1, 1)
            b:SetPoint("BOTTOMLEFT", frame, "BOTTOMLEFT", ox+(pb[1]-minX)*bs, oy+(maxY-pb[2])*bs)
            b:Show()
        end
    end
end

function addon:InitializeUI()
    mainFrame = CreateFrame("Frame", "WoWTetrisFrame", UIParent, "BackdropTemplate")
    mainFrame:SetSize(650, 580)  -- Wider to fit quest tracker on left
    mainFrame:SetPoint("CENTER")
    mainFrame:SetMovable(true)
    mainFrame:EnableMouse(true)
    mainFrame:RegisterForDrag("LeftButton")
    mainFrame:SetScript("OnDragStart", mainFrame.StartMoving)
    mainFrame:SetScript("OnDragStop", mainFrame.StopMovingOrSizing)
    mainFrame:SetClampedToScreen(true)
    mainFrame:SetFrameStrata("HIGH")
    mainFrame:Hide()
    mainFrame:SetBackdrop({bgFile = "Interface\\DialogFrame\\UI-DialogBox-Background-Dark", edgeFile = "Interface\\DialogFrame\\UI-DialogBox-Gold-Border", tile = true, tileSize = 32, edgeSize = 32, insets = {left=8, right=8, top=8, bottom=8}})
    
    local closeBtn = CreateFrame("Button", nil, mainFrame, "UIPanelCloseButton")
    closeBtn:SetPoint("TOPRIGHT", -5, -5)
    closeBtn:SetScript("OnClick", function() mainFrame:Hide() addon:PauseGame() end)
    
    addon:CreateMenuFrame()
    addon:CreateGameFrame()
    addon.mainFrame = mainFrame
    addon:ShowMenu()
end

function addon:CreateMenuFrame()
    menuFrame = CreateFrame("Frame", nil, mainFrame)
    menuFrame:SetAllPoints()
    menuFrame:SetFrameLevel(mainFrame:GetFrameLevel() + 5)
    
    -- Subtle dark background
    local bgTex = menuFrame:CreateTexture(nil, "BACKGROUND")
    bgTex:SetAllPoints()
    bgTex:SetColorTexture(0.05, 0.05, 0.08, 0.95)
    
    -- Title section
    local title = menuFrame:CreateFontString(nil, "OVERLAY", "GameFontNormalHuge")
    title:SetPoint("TOP", 0, -15)
    title:SetText("|cffffd700WoW |cff00ffffTETRIS|r")
    
    -- Class display panel (compact)
    local classPanel = CreateStyledPanel(menuFrame, 220, 130, "gold")
    classPanel:SetPoint("TOP", 0, -45)
    
    -- Race icon (left side)
    menuFrame.raceIcon = classPanel:CreateTexture(nil, "ARTWORK")
    menuFrame.raceIcon:SetSize(50, 50)
    menuFrame.raceIcon:SetPoint("TOPLEFT", 15, -10)
    menuFrame.raceIcon:SetTexCoord(0.08, 0.92, 0.08, 0.92)
    menuFrame.raceIcon:SetTexture("Interface\\Icons\\INV_Misc_QuestionMark")
    
    -- Class icon (right side)
    menuFrame.classIcon = classPanel:CreateTexture(nil, "ARTWORK")
    menuFrame.classIcon:SetSize(50, 50)
    menuFrame.classIcon:SetPoint("TOPRIGHT", -15, -10)
    menuFrame.classIcon:SetTexCoord(0.08, 0.92, 0.08, 0.92)
    
    menuFrame.classGlow = classPanel:CreateTexture(nil, "BACKGROUND")
    menuFrame.classGlow:SetSize(70, 70)
    menuFrame.classGlow:SetPoint("CENTER", menuFrame.classIcon, "CENTER")
    menuFrame.classGlow:SetTexture("Interface\\GLUES\\Models\\UI_Draenei\\GenericGlow64")
    menuFrame.classGlow:SetBlendMode("ADD")
    menuFrame.classGlow:SetAlpha(0.5)
    
    -- Plus sign between icons
    menuFrame.plusSign = classPanel:CreateFontString(nil, "OVERLAY", "GameFontNormalLarge")
    menuFrame.plusSign:SetPoint("CENTER", 0, 15)
    menuFrame.plusSign:SetText("|cffffd700+|r")
    
    -- Race name (below race icon)
    menuFrame.raceName = classPanel:CreateFontString(nil, "OVERLAY", "GameFontNormalSmall")
    menuFrame.raceName:SetPoint("TOP", menuFrame.raceIcon, "BOTTOM", 0, -2)
    menuFrame.raceName:SetText("|cff888888Race|r")
    
    -- Class name (below class icon)
    menuFrame.className = classPanel:CreateFontString(nil, "OVERLAY", "GameFontNormalSmall")
    menuFrame.className:SetPoint("TOP", menuFrame.classIcon, "BOTTOM", 0, -2)
    
    -- Level and rank (center bottom)
    menuFrame.classLevel = classPanel:CreateFontString(nil, "OVERLAY", "GameFontNormalSmall")
    menuFrame.classLevel:SetPoint("BOTTOM", 0, 25)
    
    menuFrame.rankText = classPanel:CreateFontString(nil, "OVERLAY", "GameFontNormalSmall")
    menuFrame.rankText:SetPoint("TOP", menuFrame.classLevel, "BOTTOM", 0, -1)
    
    -- Currency display (top right)
    menuFrame.currencyFrame = CreateFrame("Frame", nil, menuFrame)
    menuFrame.currencyFrame:SetSize(150, 35)
    menuFrame.currencyFrame:SetPoint("TOPRIGHT", -15, -50)
    
    menuFrame.coinsText = menuFrame.currencyFrame:CreateFontString(nil, "OVERLAY", "GameFontNormalSmall")
    menuFrame.coinsText:SetPoint("TOPRIGHT", 0, 0)
    menuFrame.coinsText:SetText("|cffffd700Coins:|r 0")
    
    menuFrame.tokensText = menuFrame.currencyFrame:CreateFontString(nil, "OVERLAY", "GameFontNormalSmall")
    menuFrame.tokensText:SetPoint("TOPRIGHT", 0, -15)
    menuFrame.tokensText:SetText("|cffff4444PvP:|r 0")
    
    -- Menu Buttons - Two columns for better fit
    local buttonWidth = 200
    local buttonHeight = 36
    local buttonSpacing = 42
    local startY = -185
    local leftX = -110
    local rightX = 110
    
    -- Left column
    local playBtn = CreateMenuButton(menuFrame, buttonWidth, buttonHeight + 4, "|cff00ff00PLAY|r", true)
    playBtn:SetPoint("TOP", leftX, startY)
    playBtn:SetScript("OnClick", function()
        if addon.selectedClass then addon:StartGame() else addon:ShowClassSelection() end
    end)
    
    local classBtn = CreateMenuButton(menuFrame, buttonWidth, buttonHeight, "Select Class", false)
    classBtn:SetPoint("TOP", leftX, startY - buttonSpacing)
    classBtn:SetScript("OnClick", function() addon:ShowClassSelection(false, nil, true) end)  -- menuOnly = true
    
    local questBtn = CreateMenuButton(menuFrame, buttonWidth, buttonHeight, "|cffffff00Quests|r", false)
    questBtn:SetPoint("TOP", leftX, startY - buttonSpacing * 2)
    questBtn:SetScript("OnClick", function() addon:ShowQuestFrame() end)
    menuFrame.questBtn = questBtn
    
    local shopBtn = CreateMenuButton(menuFrame, buttonWidth, buttonHeight, "|cffffd700Shop|r", false)
    shopBtn:SetPoint("TOP", leftX, startY - buttonSpacing * 3)
    shopBtn:SetScript("OnClick", function() addon:ShowShopFrame() end)
    
    -- Right column
    local affixBtn = CreateMenuButton(menuFrame, buttonWidth, buttonHeight, "|cffff6600Affixes|r", false)
    affixBtn:SetPoint("TOP", rightX, startY)
    affixBtn:SetScript("OnClick", function() addon:ShowAffixSelection() end)
    
    local leaderBtn = CreateMenuButton(menuFrame, buttonWidth, buttonHeight, "Leaderboard", false)
    leaderBtn:SetPoint("TOP", rightX, startY - buttonSpacing)
    leaderBtn:SetScript("OnClick", function() addon:ShowLeaderboard() end)
    
    local pvpBtn = CreateMenuButton(menuFrame, buttonWidth, buttonHeight, "|cffff0000Find Battle|r", false)
    pvpBtn:SetPoint("TOP", rightX, startY - buttonSpacing * 2)
    pvpBtn:SetScript("OnClick", function()
        -- Require race and class selection before queueing
        if not addon.selectedRace then
            print("|cffff0000[Tetris]|r Please select a Race first!")
            addon:ShowClassSelection()
            return
        end
        if not addon.selectedClass then
            print("|cffff0000[Tetris]|r Please select a Class first!")
            addon:ShowClassSelection()
            return
        end
        if not addon.selectedUltimate then
            print("|cffff0000[Tetris]|r Please select an Ultimate first!")
            addon:ShowClassSelection()
            return
        end
        addon:ShowQueueFrame()
    end)
    menuFrame.pvpBtn = pvpBtn
    
    local tutorialBtn = CreateMenuButton(menuFrame, buttonWidth, buttonHeight, "|cff00ffffTutorial|r", false)
    tutorialBtn:SetPoint("TOP", rightX, startY - buttonSpacing * 3)
    tutorialBtn:SetScript("OnClick", function() addon:ShowTutorial() end)
    
    -- Bottom row - centered Options button
    local optionsBtn = CreateMenuButton(menuFrame, buttonWidth, buttonHeight, "|cff888888Options|r", false)
    optionsBtn:SetPoint("TOP", 0, startY - buttonSpacing * 4 - 10)
    optionsBtn:SetScript("OnClick", function() addon:ShowOptionsFrame() end)
    
    -- PvP Stats under Find Battle
    menuFrame.pvpStats = menuFrame:CreateFontString(nil, "OVERLAY", "GameFontNormalSmall")
    menuFrame.pvpStats:SetPoint("TOP", pvpBtn, "BOTTOM", 0, -2)
    menuFrame.pvpStats:SetText("")
    
    -- Quest notification
    menuFrame.questNotify = menuFrame:CreateFontString(nil, "OVERLAY", "GameFontNormalSmall")
    menuFrame.questNotify:SetPoint("TOP", questBtn, "BOTTOM", 0, -1)
    menuFrame.questNotify:SetText("")
    
    -- Affix count
    menuFrame.affixCount = menuFrame:CreateFontString(nil, "OVERLAY", "GameFontNormalSmall")
    menuFrame.affixCount:SetPoint("TOP", affixBtn, "BOTTOM", 0, -1)
    menuFrame.affixCount:SetText("")
    
    -- Version at bottom
    local versionText = menuFrame:CreateFontString(nil, "OVERLAY", "GameFontNormalSmall")
    versionText:SetPoint("BOTTOM", 0, 8)
    versionText:SetText("|cff555555v10.29|r")
end

function addon:CreateGameFrame()
    gameFrame = CreateFrame("Frame", nil, mainFrame)
    gameFrame:SetAllPoints()
    gameFrame:SetFrameLevel(mainFrame:GetFrameLevel() + 10)
    gameFrame:Hide()
    
    -- Add background to game frame to cover menu
    local gameBg = gameFrame:CreateTexture(nil, "BACKGROUND")
    gameBg:SetAllPoints()
    gameBg:SetColorTexture(0.05, 0.05, 0.08, 1)
    
    local blockSize = 22
    local boardW, boardH = addon.BOARD_WIDTH * blockSize, addon.BOARD_HEIGHT * blockSize
    
    -- Left panel - Quest Tracker
    local leftPanel = CreateFrame("Frame", nil, gameFrame, "BackdropTemplate")
    leftPanel:SetSize(160, boardH + 8)
    leftPanel:SetPoint("TOPLEFT", 10, -15)
    leftPanel:SetBackdrop({bgFile = "Interface\\ChatFrame\\ChatFrameBackground", edgeFile = "Interface\\Tooltips\\UI-Tooltip-Border", tile = true, tileSize = 16, edgeSize = 10, insets = {left=2, right=2, top=2, bottom=2}})
    leftPanel:SetBackdropColor(0.05, 0.05, 0.08, 0.95)
    leftPanel:SetBackdropBorderColor(0.4, 0.35, 0.2, 0.8)
    gameFrame.questTracker = leftPanel
    
    local questTitle = leftPanel:CreateFontString(nil, "OVERLAY", "GameFontNormal")
    questTitle:SetPoint("TOP", 0, -8)
    questTitle:SetText("|cffffff00Quests|r")
    
    -- Quest tracker rows (show up to 6 quests)
    gameFrame.questTrackerRows = {}
    for i = 1, 6 do
        local row = CreateFrame("Button", nil, leftPanel)
        row:SetSize(150, 32)
        row:SetPoint("TOP", 0, -25 - (i-1) * 34)
        
        row.name = row:CreateFontString(nil, "OVERLAY", "GameFontNormalSmall")
        row.name:SetPoint("TOPLEFT", 5, -2)
        row.name:SetWidth(140)
        row.name:SetJustifyH("LEFT")
        
        row.progress = row:CreateFontString(nil, "OVERLAY", "GameFontNormalSmall")
        row.progress:SetPoint("TOPLEFT", 5, -14)
        
        -- Progress bar background
        row.barBg = row:CreateTexture(nil, "BACKGROUND")
        row.barBg:SetSize(140, 6)
        row.barBg:SetPoint("TOPLEFT", 5, -25)
        row.barBg:SetColorTexture(0.1, 0.1, 0.1, 1)
        
        -- Progress bar fill
        row.bar = row:CreateTexture(nil, "ARTWORK")
        row.bar:SetSize(1, 4)
        row.bar:SetPoint("LEFT", row.barBg, "LEFT", 1, 0)
        row.bar:SetColorTexture(0.2, 0.6, 0.2, 1)
        
        -- Highlight for clickable completed quests
        row.highlight = row:CreateTexture(nil, "HIGHLIGHT")
        row.highlight:SetAllPoints()
        row.highlight:SetColorTexture(0.3, 0.6, 0.3, 0.3)
        row.highlight:Hide()
        
        -- Click handler for claiming
        row:SetScript("OnClick", function(self)
            if self.questState and self.questState.completed and not self.questState.claimed then
                -- Use pcall to prevent crashes
                local success, err = pcall(function()
                    addon:ClaimQuestReward(self.questState, addon.selectedClass)
                end)
                if not success then
                    print("|cffff0000[Tetris]|r Error claiming quest: " .. tostring(err))
                end
                addon:UpdateQuestTracker()
            end
        end)
        
        -- Tooltip
        row:SetScript("OnEnter", function(self)
            if self.questState and self.questState.completed and not self.questState.claimed then
                GameTooltip:SetOwner(self, "ANCHOR_RIGHT")
                GameTooltip:SetText("|cff00ff00Click to Claim!|r")
                GameTooltip:Show()
            end
        end)
        row:SetScript("OnLeave", function() GameTooltip:Hide() end)
        
        gameFrame.questTrackerRows[i] = row
    end
    
    -- Board container (shifted right)
    local boardContainer = CreateFrame("Frame", nil, gameFrame, "BackdropTemplate")
    boardContainer:SetSize(boardW + 8, boardH + 8)
    boardContainer:SetPoint("TOPLEFT", leftPanel, "TOPRIGHT", 5, 0)
    boardContainer:SetBackdrop({bgFile = "Interface\\ChatFrame\\ChatFrameBackground", edgeFile = "Interface\\DialogFrame\\UI-DialogBox-Gold-Border", tile = true, tileSize = 16, edgeSize = 16, insets = {left=4, right=4, top=4, bottom=4}})
    boardContainer:SetBackdropColor(0.02, 0.02, 0.04, 1)
    
    -- Grid lines
    for i = 1, addon.BOARD_WIDTH - 1 do
        local line = boardContainer:CreateTexture(nil, "BACKGROUND", nil, 1)
        line:SetSize(1, boardH)
        line:SetPoint("TOPLEFT", 4 + i * blockSize, -4)
        line:SetColorTexture(0.12, 0.12, 0.15, 0.4)
    end
    for i = 1, addon.BOARD_HEIGHT - 1 do
        local line = boardContainer:CreateTexture(nil, "BACKGROUND", nil, 1)
        line:SetSize(boardW, 1)
        line:SetPoint("TOPLEFT", 4, -4 - i * blockSize)
        line:SetColorTexture(0.12, 0.12, 0.15, 0.4)
    end
    
    boardBackground = boardContainer:CreateTexture(nil, "BACKGROUND")
    boardBackground:SetPoint("TOPLEFT", 4, -4)
    boardBackground:SetPoint("BOTTOMRIGHT", -4, 4)
    boardBackground:SetAlpha(0.15)
    
    gameBoard = CreateFrame("Frame", nil, boardContainer)
    gameBoard:SetPoint("TOPLEFT", 4, -4)
    gameBoard:SetSize(boardW, boardH)
    
    boardBlocks = {}
    for y = 1, addon.BOARD_HEIGHT do
        boardBlocks[y] = {}
        for x = 1, addon.BOARD_WIDTH do
            local b = CreateBlock(gameBoard, blockSize)
            b:SetPoint("TOPLEFT", (x-1)*blockSize, -(y-1)*blockSize)
            boardBlocks[y][x] = b
        end
    end
    
    -- Right panel - more compact
    local rightPanel = CreateFrame("Frame", nil, gameFrame)
    rightPanel:SetSize(210, boardH + 8)
    rightPanel:SetPoint("TOPLEFT", boardContainer, "TOPRIGHT", 5, 0)
    
    -- Class info (compact)
    local classSection = CreateStyledPanel(rightPanel, 205, 70, "gold")
    classSection:SetPoint("TOP", 0, 0)
    
    gameFrame.classIcon = classSection:CreateTexture(nil, "ARTWORK")
    gameFrame.classIcon:SetSize(45, 45)
    gameFrame.classIcon:SetPoint("TOPLEFT", 8, -12)
    gameFrame.classIcon:SetTexCoord(0.08, 0.92, 0.08, 0.92)
    
    gameFrame.rankGlow = classSection:CreateTexture(nil, "BACKGROUND")
    gameFrame.rankGlow:SetSize(55, 55)
    gameFrame.rankGlow:SetPoint("CENTER", gameFrame.classIcon, "CENTER")
    gameFrame.rankGlow:SetTexture("Interface\\GLUES\\Models\\UI_Draenei\\GenericGlow64")
    gameFrame.rankGlow:SetBlendMode("ADD")
    gameFrame.rankGlow:SetAlpha(0.4)
    
    gameFrame.className = classSection:CreateFontString(nil, "OVERLAY", "GameFontNormal")
    gameFrame.className:SetPoint("TOPLEFT", gameFrame.classIcon, "TOPRIGHT", 8, -2)
    
    classLevelText = classSection:CreateFontString(nil, "OVERLAY", "GameFontNormalLarge")
    classLevelText:SetPoint("TOPLEFT", gameFrame.className, "BOTTOMLEFT", 0, -2)
    
    gameFrame.rankBadge = classSection:CreateFontString(nil, "OVERLAY", "GameFontNormalSmall")
    gameFrame.rankBadge:SetPoint("TOPLEFT", classLevelText, "BOTTOMLEFT", 0, -1)
    
    -- XP bar at bottom of class section
    local xpBg = classSection:CreateTexture(nil, "BACKGROUND")
    xpBg:SetSize(189, 8)
    xpBg:SetPoint("BOTTOM", 0, 6)
    xpBg:SetColorTexture(0.05, 0.05, 0.05, 1)
    
    xpBar = classSection:CreateTexture(nil, "ARTWORK")
    xpBar:SetSize(1, 6)
    xpBar:SetPoint("LEFT", xpBg, "LEFT", 1, 0)
    
    xpText = classSection:CreateFontString(nil, "OVERLAY", "GameFontNormalSmall")
    xpText:SetPoint("CENTER", xpBg, "CENTER")
    
    -- Stats section (2x2 grid, compact)
    local statsSection = CreateStyledPanel(rightPanel, 205, 60, "dark")
    statsSection:SetPoint("TOP", classSection, "BOTTOM", 0, -5)
    
    local function CreateStat(parent, label, x, y)
        local lbl = parent:CreateFontString(nil, "OVERLAY", "GameFontNormalSmall")
        lbl:SetPoint("TOPLEFT", x, y)
        lbl:SetText("|cff666666"..label.."|r")
        local val = parent:CreateFontString(nil, "OVERLAY", "GameFontNormal")
        val:SetPoint("TOPLEFT", lbl, "BOTTOMLEFT", 0, -1)
        return val
    end
    
    scoreText = CreateStat(statsSection, "SCORE", 10, -8)
    timeText = CreateStat(statsSection, "TIME", 110, -8)
    levelText = CreateStat(statsSection, "LEVEL", 10, -33)
    linesText = CreateStat(statsSection, "LINES", 110, -33)
    
    -- Ultimate section (with charge bar)
    ultimateFrame = CreateStyledPanel(rightPanel, 205, 65, "pvp")
    ultimateFrame:SetPoint("TOP", statsSection, "BOTTOM", 0, -5)
    ultimateFrame:EnableMouse(true)
    ultimateFrame:SetScript("OnEnter", function(self)
        if addon.selectedUltimate then
            GameTooltip:SetOwner(self, "ANCHOR_RIGHT")
            GameTooltip:SetText("|cffff6600" .. addon.selectedUltimate.name .. "|r")
            GameTooltip:AddLine(addon.selectedUltimate.description, 1, 1, 1, true)
            GameTooltip:AddLine(" ")
            local chargeReq = addon:GetUltimateChargeRequired()
            GameTooltip:AddLine("Charge Required: " .. chargeReq .. " points", 0.7, 0.7, 0.7)
            GameTooltip:AddLine("Cooldown: " .. (addon.selectedUltimate.cooldown or 30) .. "s", 0.7, 0.7, 0.7)
            GameTooltip:AddLine("Press [R] to use", 0, 1, 0)
            GameTooltip:Show()
        end
    end)
    ultimateFrame:SetScript("OnLeave", function() GameTooltip:Hide() end)
    
    local ultLabel = ultimateFrame:CreateFontString(nil, "OVERLAY", "GameFontNormalSmall")
    ultLabel:SetPoint("TOPLEFT", 8, -5)
    ultLabel:SetText("|cffff6600ULTIMATE [R]|r")
    
    ultimateFrame.icon = ultimateFrame:CreateTexture(nil, "ARTWORK")
    ultimateFrame.icon:SetSize(32, 32)
    ultimateFrame.icon:SetPoint("TOPLEFT", 8, -18)
    ultimateFrame.icon:SetTexCoord(0.08, 0.92, 0.08, 0.92)
    
    ultimateFrame.name = ultimateFrame:CreateFontString(nil, "OVERLAY", "GameFontNormalSmall")
    ultimateFrame.name:SetPoint("LEFT", ultimateFrame.icon, "RIGHT", 6, 6)
    ultimateFrame.name:SetWidth(100)
    
    ultimateCooldownText = ultimateFrame:CreateFontString(nil, "OVERLAY", "GameFontNormalSmall")
    ultimateCooldownText:SetPoint("LEFT", ultimateFrame.icon, "RIGHT", 6, -6)
    
    -- Charge bar background
    local chargeBg = ultimateFrame:CreateTexture(nil, "BACKGROUND")
    chargeBg:SetSize(189, 10)
    chargeBg:SetPoint("BOTTOM", 0, 5)
    chargeBg:SetColorTexture(0.1, 0.05, 0.05, 1)
    
    ultimateFrame.chargeBar = ultimateFrame:CreateTexture(nil, "ARTWORK")
    ultimateFrame.chargeBar:SetSize(1, 8)
    ultimateFrame.chargeBar:SetPoint("LEFT", chargeBg, "LEFT", 1, 0)
    ultimateFrame.chargeBar:SetColorTexture(1, 0.5, 0, 1)
    
    ultimateFrame.chargeText = ultimateFrame:CreateFontString(nil, "OVERLAY", "GameFontNormalSmall")
    ultimateFrame.chargeText:SetPoint("CENTER", chargeBg, "CENTER")
    
    -- Next pieces (horizontal row for first, then smaller)
    local nextLabel = rightPanel:CreateFontString(nil, "OVERLAY", "GameFontNormalSmall")
    nextLabel:SetPoint("TOP", ultimateFrame, "BOTTOM", 0, -8)
    nextLabel:SetText("|cffffd700NEXT|r")
    
    nextPieceFrames = {}
    local nf1 = CreateStyledPanel(rightPanel, 55, 55, "dark")
    nf1:SetPoint("TOP", nextLabel, "BOTTOM", -35, -3)
    nf1.blocks = {}
    for j = 1, 4 do nf1.blocks[j] = CreateBlock(nf1, 14) end
    nextPieceFrames[1] = nf1
    
    local nf2 = CreateStyledPanel(rightPanel, 45, 45, "dark")
    nf2:SetPoint("LEFT", nf1, "RIGHT", 5, 0)
    nf2.blocks = {}
    for j = 1, 4 do nf2.blocks[j] = CreateBlock(nf2, 12) end
    nextPieceFrames[2] = nf2
    
    local nf3 = CreateStyledPanel(rightPanel, 45, 45, "dark")
    nf3:SetPoint("LEFT", nf2, "RIGHT", 5, 0)
    nf3.blocks = {}
    for j = 1, 4 do nf3.blocks[j] = CreateBlock(nf3, 12) end
    nextPieceFrames[3] = nf3
    
    -- Hold and Racial side by side
    local holdLabel = rightPanel:CreateFontString(nil, "OVERLAY", "GameFontNormalSmall")
    holdLabel:SetPoint("TOP", nf1, "BOTTOM", 0, -8)
    holdLabel:SetText("|cff00ffffHOLD [C]|r")
    
    holdPieceFrame = CreateStyledPanel(rightPanel, 55, 55, "dark")
    holdPieceFrame:SetPoint("TOP", holdLabel, "BOTTOM", 0, -3)
    holdPieceFrame.blocks = {}
    for i = 1, 4 do holdPieceFrame.blocks[i] = CreateBlock(holdPieceFrame, 14) end
    
    -- Racial ability frame (next to hold)
    local racialLabel = rightPanel:CreateFontString(nil, "OVERLAY", "GameFontNormalSmall")
    racialLabel:SetPoint("TOP", nf1, "BOTTOM", 60, -8)
    racialLabel:SetText("|cff00ff00RACIAL [B]|r")
    addon.racialLabel = racialLabel
    
    local racialFrame = CreateFrame("Button", "WoWTetrisRacialFrame", rightPanel, "BackdropTemplate")
    racialFrame:SetSize(55, 55)
    racialFrame:SetPoint("TOP", racialLabel, "BOTTOM", 0, -3)
    racialFrame:SetBackdrop({
        bgFile = "Interface\\ChatFrame\\ChatFrameBackground",
        edgeFile = "Interface\\Tooltips\\UI-Tooltip-Border",
        tile = true, tileSize = 16, edgeSize = 10,
        insets = {left=2, right=2, top=2, bottom=2}
    })
    racialFrame:SetBackdropColor(0.1, 0.2, 0.1, 0.9)
    racialFrame:SetBackdropBorderColor(0.3, 0.6, 0.3, 1)
    
    racialFrame.icon = racialFrame:CreateTexture(nil, "ARTWORK")
    racialFrame.icon:SetSize(40, 40)
    racialFrame.icon:SetPoint("CENTER")
    racialFrame.icon:SetTexCoord(0.08, 0.92, 0.08, 0.92)
    racialFrame.icon:SetTexture("Interface\\Icons\\INV_Misc_QuestionMark")
    
    racialFrame.cooldownText = racialFrame:CreateFontString(nil, "OVERLAY", "GameFontNormalLarge")
    racialFrame.cooldownText:SetPoint("CENTER")
    racialFrame.cooldownText:SetText("")
    
    racialFrame:SetScript("OnEnter", function(self)
        local raceName = addon.selectedRace
        if raceName and addon.RACES and addon.RACES[raceName] then
            local raceData = addon.RACES[raceName]
            GameTooltip:SetOwner(self, "ANCHOR_RIGHT")
            local typeStr = raceData.abilityType == "pvp" and "|cffff4444[PvP]|r" or "|cff00ff00[Solo]|r"
            GameTooltip:SetText(raceData.name .. " " .. typeStr)
            GameTooltip:AddLine(raceData.ability.name, 0, 1, 0)
            GameTooltip:AddLine(raceData.ability.description, 1, 1, 1, true)
            GameTooltip:AddLine(" ")
            if addon.racialUsedThisRound then
                GameTooltip:AddLine("Already used this round!", 1, 0, 0)
            else
                GameTooltip:AddLine("Press [B] to use (once per round)", 0, 1, 0)
            end
            GameTooltip:Show()
        else
            GameTooltip:SetOwner(self, "ANCHOR_RIGHT")
            GameTooltip:SetText("No Race Selected")
            GameTooltip:AddLine("Select a race to use racial ability", 0.7, 0.7, 0.7)
            GameTooltip:Show()
        end
    end)
    racialFrame:SetScript("OnLeave", function() GameTooltip:Hide() end)
    racialFrame:SetScript("OnClick", function() addon:UseRacialAbility() end)
    
    racialFrame:Hide()  -- Only show when race is selected
    addon.racialFrame = racialFrame
    
    -- Bottom buttons
    local btnY = -boardH - 25
    
    local menuBtn = CreateSmallButton(gameFrame, 55, 26, "Menu")
    menuBtn:SetPoint("TOPLEFT", boardContainer, "BOTTOMLEFT", 0, -5)
    menuBtn:SetScript("OnClick", function() addon:ShowMenu() end)
    
    local newBtn = CreateSmallButton(gameFrame, 55, 26, "New", "gold")
    newBtn:SetPoint("LEFT", menuBtn, "RIGHT", 3, 0)
    newBtn:SetScript("OnClick", function() addon:StartGame() end)
    
    local pauseBtn = CreateSmallButton(gameFrame, 60, 26, "Pause")
    pauseBtn:SetPoint("LEFT", newBtn, "RIGHT", 3, 0)
    pauseBtn:SetScript("OnClick", function() addon:TogglePause() end)
    gameFrame.pauseBtn = pauseBtn
    
    local muteBtn = CreateSmallButton(gameFrame, 50, 26, "Music")
    muteBtn:SetPoint("LEFT", pauseBtn, "RIGHT", 3, 0)
    muteBtn:SetScript("OnClick", function()
        local enabled = addon:ToggleMusic()
        if enabled then
            muteBtn:SetText("|cff00ff00Music|r")
        else
            muteBtn:SetText("|cffff0000Muted|r")
        end
    end)
    gameFrame.muteBtn = muteBtn
    
    local pvpBtn = CreateSmallButton(gameFrame, 40, 26, "|cffff0000PvP|r", "red")
    pvpBtn:SetPoint("LEFT", muteBtn, "RIGHT", 3, 0)
    pvpBtn:SetScript("OnClick", function() addon:UsePvPAbility() end)
    gameFrame.pvpIndicator = pvpBtn
    pvpBtn:Hide()
    
    -- Overlays
    pauseOverlay = CreateFrame("Frame", nil, gameFrame)
    pauseOverlay:SetAllPoints(boardContainer)
    pauseOverlay:SetFrameLevel(gameBoard:GetFrameLevel() + 10)
    pauseOverlay:Hide()
    local pauseBg = pauseOverlay:CreateTexture(nil, "BACKGROUND")
    pauseBg:SetAllPoints()
    pauseBg:SetColorTexture(0, 0, 0, 0.85)
    local pauseText = pauseOverlay:CreateFontString(nil, "OVERLAY", "GameFontNormalHuge")
    pauseText:SetPoint("CENTER", 0, 10)
    pauseText:SetText("|cffffd700PAUSED|r")
    local pauseHint = pauseOverlay:CreateFontString(nil, "OVERLAY", "GameFontNormal")
    pauseHint:SetPoint("CENTER", 0, -20)
    pauseHint:SetText("|cff888888Press P to resume|r")
    
    gameOverOverlay = CreateFrame("Frame", nil, gameFrame)
    gameOverOverlay:SetAllPoints(boardContainer)
    gameOverOverlay:SetFrameLevel(gameBoard:GetFrameLevel() + 10)
    gameOverOverlay:Hide()
    local goBg = gameOverOverlay:CreateTexture(nil, "BACKGROUND")
    goBg:SetAllPoints()
    goBg:SetColorTexture(0.1, 0, 0, 0.9)
    gameOverOverlay.title = gameOverOverlay:CreateFontString(nil, "OVERLAY", "GameFontNormalHuge")
    gameOverOverlay.title:SetPoint("CENTER", 0, 30)
    gameOverOverlay.title:SetText("|cffff0000GAME OVER|r")
    gameOverOverlay.score = gameOverOverlay:CreateFontString(nil, "OVERLAY", "GameFontNormalLarge")
    gameOverOverlay.score:SetPoint("CENTER", 0, -5)
    gameOverOverlay.highScore = gameOverOverlay:CreateFontString(nil, "OVERLAY", "GameFontNormal")
    gameOverOverlay.highScore:SetPoint("CENTER", 0, -35)
    
    levelUpOverlay = CreateFrame("Frame", nil, gameFrame)
    levelUpOverlay:SetSize(180, 50)
    levelUpOverlay:SetPoint("CENTER", boardContainer, "CENTER")
    levelUpOverlay:SetFrameLevel(gameBoard:GetFrameLevel() + 5)
    levelUpOverlay:Hide()
    local luBg = levelUpOverlay:CreateTexture(nil, "BACKGROUND")
    luBg:SetAllPoints()
    luBg:SetColorTexture(0, 0.15, 0, 0.9)
    levelUpOverlay.text = levelUpOverlay:CreateFontString(nil, "OVERLAY", "GameFontNormalLarge")
    levelUpOverlay.text:SetPoint("CENTER")
    
    gameFrame:SetScript("OnUpdate", function(self, elapsed) addon:UpdateGame(elapsed) end)
    
    addon.gameFrame = gameFrame
    addon:CreateClassSelectionFrame()
    addon:CreateUltimateSelectionFrame()
end

function addon:ShowMenu()
    if gameFrame then gameFrame:Hide() end
    -- Unlock selections when returning to menu
    addon.ultimateLocked = false
    addon.pvpAbilityLocked = false
    
    -- Stop music when returning to menu
    addon:StopMusic(true)
    
    if menuFrame then menuFrame:Show() addon:UpdateMenuDisplay() end
end

function addon:ShowGame()
    if menuFrame then menuFrame:Hide() end
    if addon.classSelectFrame then addon.classSelectFrame:Hide() end
    if addon.ultimateSelectFrame then addon.ultimateSelectFrame:Hide() end
    if gameFrame then
        gameFrame:Show()
        if addon.mpState and addon.mpState.inMatch then gameFrame.pvpIndicator:Show() else gameFrame.pvpIndicator:Hide() end
    end
end

function addon:UpdateMenuDisplay()
    if not menuFrame then return end
    
    -- Update race display
    if addon.selectedRace and addon.RACES and addon.RACES[addon.selectedRace] then
        local rd = addon.RACES[addon.selectedRace]
        menuFrame.raceIcon:SetTexture(rd.icon)
        menuFrame.raceName:SetText(rd.name)
    else
        menuFrame.raceIcon:SetTexture("Interface\\Icons\\INV_Misc_QuestionMark")
        menuFrame.raceName:SetText("|cff888888Race|r")
    end
    
    -- Update class display
    if addon.selectedClass then
        local cd = addon.CLASSES[addon.selectedClass]
        local stats = addon:GetClassStats(addon.selectedClass)
        local rank = addon:GetLevelRank(stats.level)
        menuFrame.classIcon:SetTexture(cd.icon)
        menuFrame.className:SetText(cd.colorCode .. cd.name .. "|r")
        menuFrame.classLevel:SetText(rank.color .. "Level " .. stats.level .. "|r")
        menuFrame.rankText:SetText(rank.color .. "[ " .. rank.name .. " ]|r")
        menuFrame.classGlow:SetVertexColor(rank.rgb[1], rank.rgb[2], rank.rgb[3])
    else
        menuFrame.classIcon:SetTexture("Interface\\Icons\\INV_Misc_QuestionMark")
        menuFrame.className:SetText("|cff888888Class|r")
        menuFrame.classLevel:SetText("")
        menuFrame.rankText:SetText("|cff666666Select Race & Class|r")
        menuFrame.classGlow:SetVertexColor(0.3, 0.3, 0.3)
    end
    
    -- Update currency display
    if menuFrame.coinsText then
        local coins = addon:GetCurrency("coins")
        menuFrame.coinsText:SetText("|cffffd700Coins:|r " .. addon:FormatNumber(coins))
    end
    if menuFrame.tokensText then
        local tokens = addon:GetCurrency("pvpTokens")
        menuFrame.tokensText:SetText("|cffff4444PvP Tokens:|r " .. addon:FormatNumber(tokens))
    end
    
    -- Update PvP stats display
    if menuFrame.pvpStats then
        local wins = addon.db.pvpWins or 0
        local losses = addon.db.pvpLosses or 0
        local rating = addon.db.pvpRating or 1000
        local ratingColor = rating >= 1500 and "|cff00ff00" or (rating >= 1000 and "|cffffff00" or "|cffff0000")
        menuFrame.pvpStats:SetText("|cff00ff00" .. wins .. "W|r - |cffff0000" .. losses .. "L|r | " .. ratingColor .. rating .. " Rating|r")
    end
end

function addon:UpdateUI()
    if not gameFrame or not gameFrame:IsShown() then return end
    local state = addon.gameState
    local stats = addon.selectedClass and addon:GetClassStats(addon.selectedClass) or {level=1}
    local rank = addon:GetLevelRank(stats.level)
    
    if addon.selectedClass then
        local cd = addon.CLASSES[addon.selectedClass]
        gameFrame.classIcon:SetTexture(cd.icon)
        gameFrame.className:SetText(cd.colorCode .. cd.name .. "|r")
        classLevelText:SetText(rank.color .. "Lv " .. stats.level .. "|r")
        gameFrame.rankBadge:SetText(rank.color .. "[" .. rank.name .. "]|r")
        gameFrame.rankGlow:SetVertexColor(rank.rgb[1], rank.rgb[2], rank.rgb[3])
    end
    
    -- XP bar shows progress toward NEXT class level
    -- Current score in this game adds to totalXP at end
    local currentTotalXP = (stats.totalXP or 0) + state.score
    local xpNeeded = addon:GetXPForLevel(stats.level)
    local xpPct = math.min(currentTotalXP / xpNeeded, 1)
    xpBar:SetWidth(math.max(1, 187 * xpPct))
    xpBar:SetColorTexture(rank.rgb[1] * 0.8, rank.rgb[2] * 0.8, rank.rgb[3] * 0.8, 1)
    xpText:SetText(currentTotalXP .. "/" .. xpNeeded)
    
    scoreText:SetText("|cffffd700" .. addon:FormatNumber(state.score) .. "|r")
    levelText:SetText("|cff00ff00" .. stats.level .. "|r")
    linesText:SetText("|cff00ffff" .. state.totalLines .. "|r")
    
    -- Show time with combined score multiplier (time + speed bonuses)
    local timeMult = addon:GetTimeScoreMultiplier()
    local speedMult = addon:GetSpeedScoreMultiplier()
    local combinedBonus = math.floor((timeMult * speedMult - 1) * 100)
    local timeMultText = ""
    if combinedBonus > 0 then
        timeMultText = " |cff00ff00+" .. combinedBonus .. "%|r"
    end
    timeText:SetText("|cffffffff" .. addon:FormatTime(state.gameTime) .. "|r" .. timeMultText)
    
    if addon.selectedUltimate then
        ultimateFrame.icon:SetTexture(addon.selectedUltimate.icon)
        ultimateFrame.name:SetText(addon.selectedUltimate.name)
        
        -- Update charge bar
        local charge, chargeNeeded = addon:GetUltimateCharge()
        local chargePct = math.min(charge / chargeNeeded, 1)
        ultimateFrame.chargeBar:SetWidth(math.max(1, 187 * chargePct))
        
        local isCharged = addon:IsUltimateCharged()
        local effects = addon.pvpEffects or {}
        
        -- Check for SILENCED effect first
        if effects.ultimateDisabled then
            ultimateCooldownText:SetText("|cff8800ffSILENCED!|r")
            ultimateFrame.icon:SetDesaturated(true)
            ultimateFrame.chargeBar:SetColorTexture(0.3, 0, 0.5, 1)
            ultimateFrame.chargeText:SetText("|cff8800ffDISABLED|r")
        elseif addon.ultimateCooldown > 0 then
            ultimateCooldownText:SetText("|cffff0000CD: " .. math.ceil(addon.ultimateCooldown) .. "s|r")
            ultimateFrame.icon:SetDesaturated(true)
            ultimateFrame.chargeBar:SetColorTexture(0.5, 0.25, 0, 1)
            ultimateFrame.chargeText:SetText("|cff888888" .. charge .. "/" .. chargeNeeded .. "|r")
        elseif not isCharged then
            ultimateCooldownText:SetText("|cffff6600Charging...|r")
            ultimateFrame.icon:SetDesaturated(true)
            ultimateFrame.chargeBar:SetColorTexture(1, 0.5, 0, 1)
            ultimateFrame.chargeText:SetText("|cffff6600" .. charge .. "/" .. chargeNeeded .. "|r")
        else
            ultimateCooldownText:SetText("|cff00ff00READY!|r")
            ultimateFrame.icon:SetDesaturated(false)
            ultimateFrame.chargeBar:SetColorTexture(0, 1, 0, 1)
            ultimateFrame.chargeText:SetText("|cff00ff00CHARGED|r")
        end
    else
        ultimateFrame.icon:SetTexture("Interface\\Icons\\INV_Misc_QuestionMark")
        ultimateFrame.name:SetText("None")
        ultimateCooldownText:SetText("")
        ultimateFrame.chargeBar:SetWidth(1)
        ultimateFrame.chargeText:SetText("")
    end
    
    gameFrame.pauseBtn.text:SetText(state.isPaused and "Resume" or "Pause")
    if addon.mpState and addon.mpState.inMatch then gameFrame.pvpIndicator:Show() else gameFrame.pvpIndicator:Hide() end
    
    -- Update racial frame
    if addon.racialFrame then
        local raceName = addon.selectedRace
        if raceName and addon.RACES and addon.RACES[raceName] then
            local raceData = addon.RACES[raceName]
            addon.racialFrame.icon:SetTexture(raceData.icon)
            
            if addon.racialUsedThisRound then
                addon.racialFrame.icon:SetDesaturated(true)
                addon.racialFrame.cooldownText:SetText("|cffff0000X|r")
                addon.racialFrame:SetBackdropColor(0.2, 0.1, 0.1, 0.9)
                addon.racialFrame:SetBackdropBorderColor(0.5, 0.2, 0.2, 1)
            else
                addon.racialFrame.icon:SetDesaturated(false)
                addon.racialFrame.cooldownText:SetText("")
                if raceData.abilityType == "pvp" then
                    addon.racialFrame:SetBackdropColor(0.2, 0.1, 0.1, 0.9)
                    addon.racialFrame:SetBackdropBorderColor(0.6, 0.3, 0.3, 1)
                else
                    addon.racialFrame:SetBackdropColor(0.1, 0.2, 0.1, 0.9)
                    addon.racialFrame:SetBackdropBorderColor(0.3, 0.6, 0.3, 1)
                end
            end
            addon.racialFrame:Show()
        else
            addon.racialFrame:Hide()
        end
    end
    
    -- Track quest progress in real-time
    if state.isPlaying and addon.TrackQuestProgress then
        addon:TrackQuestProgress()
    end
    
    addon:RenderBoard()
    addon:RenderNextPieces()
    addon:RenderHoldPiece()
    addon:UpdateQuestTracker()  -- Update quest progress display
    pauseOverlay:SetShown(state.isPaused and state.isPlaying)
    if not state.isGameOver then gameOverOverlay:Hide() end
end

function addon:FormatNumber(n)
    local formatted = tostring(n)
    while true do
        formatted, k = string.gsub(formatted, "^(-?%d+)(%d%d%d)", "%1,%2")
        if k == 0 then break end
    end
    return formatted
end

function addon:RenderBoard()
    local state = addon.gameState
    local effects = addon.pvpEffects or {}
    
    -- Blackout effect - hide everything
    if effects.blackout then
        for y = 1, addon.BOARD_HEIGHT do
            for x = 1, addon.BOARD_WIDTH do
                boardBlocks[y][x].tex:SetTexture(nil)
                boardBlocks[y][x].tex:SetColorTexture(0, 0, 0, 1)
            end
        end
        return
    end
    
    -- Normal rendering
    for y = 1, addon.BOARD_HEIGHT do
        for x = 1, addon.BOARD_WIDTH do
            boardBlocks[y][x].tex:SetTexture(nil)
            boardBlocks[y][x].tex:SetColorTexture(0.03, 0.03, 0.05, 0.4)
        end
    end
    for y = 1, addon.BOARD_HEIGHT do
        for x = 1, addon.BOARD_WIDTH do
            local cell = state.board[y] and state.board[y][x]
            if cell then
                if cell.powerUp then
                    -- Power-up block: gold/yellow color with special icon
                    boardBlocks[y][x].tex:SetTexture("Interface\\Icons\\INV_Misc_Gift_05")
                    boardBlocks[y][x].tex:SetVertexColor(1, 0.84, 0, 1)
                elseif cell.garbage then
                    -- Garbage block: gray
                    boardBlocks[y][x].tex:SetColorTexture(0.35, 0.35, 0.35, 1)
                elseif cell.affix then
                    -- Affix-spawned block: darker color
                    local c = cell.color or {0.5, 0.5, 0.5}
                    boardBlocks[y][x].tex:SetColorTexture(c[1], c[2], c[3], 1)
                else
                    boardBlocks[y][x].tex:SetTexture(cell.texture or addon:GetPieceTexture(cell.type))
                    boardBlocks[y][x].tex:SetVertexColor(1, 1, 1, 1)
                end
            end
        end
    end
    -- Ghost piece (not if piece is hidden)
    if state.currentPiece and state.isPlaying and not state.isPaused and addon.db.ghostPieceEnabled and not effects.hidePiece then
        local ghostY = state.currentPiece.y
        while addon:IsValidPosition(state.currentPiece, 0, ghostY - state.currentPiece.y + 1) do ghostY = ghostY + 1 end
        if ghostY > state.currentPiece.y then
            local blocks = addon:GetPieceBlocks(state.currentPiece.type, state.currentPiece.rotation)
            local tex = addon:GetPieceTexture(state.currentPiece.type)
            for _, block in ipairs(blocks) do
                local bx = state.currentPiece.x + block[1] + 1  -- +1 for 1-indexed board
                local by = ghostY + block[2] + 1
                if by >= 1 and by <= addon.BOARD_HEIGHT and bx >= 1 and bx <= addon.BOARD_WIDTH then
                    if not (state.board[by] and state.board[by][bx]) then
                        boardBlocks[by][bx].tex:SetTexture(tex)
                        boardBlocks[by][bx].tex:SetVertexColor(0.4, 0.4, 0.4, 0.35)
                    end
                end
            end
        end
    end
    -- Current piece (check for hidePiece effect)
    if state.currentPiece and state.isPlaying and not state.isPaused and not effects.hidePiece then
        local blocks = addon:GetPieceBlocks(state.currentPiece.type, state.currentPiece.rotation)
        local tex = addon:GetPieceTexture(state.currentPiece.type)
        for _, block in ipairs(blocks) do
            local bx = state.currentPiece.x + block[1] + 1  -- +1 for 1-indexed board
            local by = state.currentPiece.y + block[2] + 1
            if by >= 1 and by <= addon.BOARD_HEIGHT and bx >= 1 and bx <= addon.BOARD_WIDTH then
                boardBlocks[by][bx].tex:SetTexture(tex)
                boardBlocks[by][bx].tex:SetVertexColor(1, 1, 1, 1)
            end
        end
    end
end

function addon:RenderNextPieces()
    local effects = addon.pvpEffects or {}
    -- Hide preview effect - show question marks instead
    if effects.hidePreview then
        for i, frame in ipairs(nextPieceFrames) do 
            for _, b in ipairs(frame.blocks) do 
                b:Show()
                b.tex:SetTexture("Interface\\Icons\\INV_Misc_QuestionMark")
                b.tex:SetVertexColor(0.5, 0.5, 0.5, 0.8)
            end
        end
        return
    end
    for i, frame in ipairs(nextPieceFrames) do RenderPreview(frame, addon.gameState.nextPieces[i]) end
end

function addon:RenderHoldPiece()
    RenderPreview(holdPieceFrame, addon.gameState.heldPiece)
    if not addon.gameState.canHold then
        for _, b in ipairs(holdPieceFrame.blocks) do if b:IsShown() then b.tex:SetVertexColor(0.4, 0.4, 0.4, 0.6) end end
    end
end

function addon:ShowGameOver()
    local state, stats = addon.gameState, addon:GetClassStats(addon.selectedClass)
    gameOverOverlay.score:SetText("|cffffd700Score: " .. addon:FormatNumber(state.score) .. "|r")
    gameOverOverlay.highScore:SetText(state.score > (stats.highScore or 0) and "|cff00ff00NEW HIGH SCORE!|r" or "|cff888888Best: " .. addon:FormatNumber(stats.highScore) .. "|r")
    gameOverOverlay:Show()
end

function addon:ShowLevelUp(newLevel)
    levelUpOverlay.text:SetText("|cff00ff00LEVEL UP!|r  |cffffd700Lv " .. newLevel .. "|r")
    levelUpOverlay:SetAlpha(1)
    levelUpOverlay:Show()
    local elapsed = 0
    levelUpOverlay:SetScript("OnUpdate", function(self, delta)
        elapsed = elapsed + delta
        if elapsed > 1.5 then self:SetAlpha(math.max(0, 1 - (elapsed - 1.5) / 0.5)) end
        if elapsed > 2 then self:Hide() self:SetScript("OnUpdate", nil) end
    end)
end

function addon:CreateClassSelectionFrame()
    local f = CreateFrame("Frame", "WoWTetrisClassSelect", mainFrame, "BackdropTemplate")
    f:SetSize(520, 480)
    f:SetPoint("CENTER")
    f:SetBackdrop({
        bgFile = "Interface\\ChatFrame\\ChatFrameBackground",
        edgeFile = "Interface\\Tooltips\\UI-Tooltip-Border",
        tile = true, tileSize = 16, edgeSize = 14,
        insets = {left=3, right=3, top=3, bottom=3}
    })
    f:SetBackdropColor(0.06, 0.06, 0.1, 0.98)
    f:SetBackdropBorderColor(0.5, 0.4, 0.2, 1)
    f:SetFrameLevel(mainFrame:GetFrameLevel() + 50)
    f:Hide()
    
    f.currentTab = 1  -- 1=Race, 2=Ultimate
    
    -- Title
    f.title = f:CreateFontString(nil, "OVERLAY", "GameFontNormalLarge")
    f.title:SetPoint("TOP", 0, -12)
    f.title:SetText("|cffffd700Step 1: Choose Race & Class|r")
    
    -- Close button
    local closeBtn = CreateFrame("Button", nil, f, "UIPanelCloseButton")
    closeBtn:SetPoint("TOPRIGHT", 0, 0)
    closeBtn:SetSize(24, 24)
    closeBtn:SetScript("OnClick", function() f:Hide() addon:ShowMenu() end)
    
    -- Current selection display (top bar)
    f.selectionBar = CreateFrame("Frame", nil, f, "BackdropTemplate")
    f.selectionBar:SetSize(480, 45)
    f.selectionBar:SetPoint("TOP", 0, -35)
    f.selectionBar:SetBackdrop({
        bgFile = "Interface\\ChatFrame\\ChatFrameBackground",
        edgeFile = "Interface\\Tooltips\\UI-Tooltip-Border",
        tile = true, tileSize = 16, edgeSize = 8,
        insets = {left=2, right=2, top=2, bottom=2}
    })
    f.selectionBar:SetBackdropColor(0.03, 0.03, 0.05, 0.9)
    
    -- Race display in selection bar
    f.selectedRaceIcon = f.selectionBar:CreateTexture(nil, "ARTWORK")
    f.selectedRaceIcon:SetSize(35, 35)
    f.selectedRaceIcon:SetPoint("LEFT", 8, 0)
    f.selectedRaceIcon:SetTexCoord(0.08, 0.92, 0.08, 0.92)
    f.selectedRaceIcon:SetTexture("Interface\\Icons\\INV_Misc_QuestionMark")
    
    f.selectedRaceName = f.selectionBar:CreateFontString(nil, "OVERLAY", "GameFontNormalSmall")
    f.selectedRaceName:SetPoint("LEFT", f.selectedRaceIcon, "RIGHT", 5, 0)
    f.selectedRaceName:SetText("|cff666666No Race|r")
    
    -- Plus sign
    f.plusSign = f.selectionBar:CreateFontString(nil, "OVERLAY", "GameFontNormalLarge")
    f.plusSign:SetPoint("CENTER", -60, 0)
    f.plusSign:SetText("|cff444444+|r")
    
    -- Class display in selection bar
    f.selectedClassIcon = f.selectionBar:CreateTexture(nil, "ARTWORK")
    f.selectedClassIcon:SetSize(35, 35)
    f.selectedClassIcon:SetPoint("CENTER", 0, 0)
    f.selectedClassIcon:SetTexCoord(0.08, 0.92, 0.08, 0.92)
    f.selectedClassIcon:SetTexture("Interface\\Icons\\INV_Misc_QuestionMark")
    
    f.selectedClassName = f.selectionBar:CreateFontString(nil, "OVERLAY", "GameFontNormalSmall")
    f.selectedClassName:SetPoint("LEFT", f.selectedClassIcon, "RIGHT", 5, 0)
    f.selectedClassName:SetText("|cff666666No Class|r")
    
    -- Arrow
    f.arrowSign = f.selectionBar:CreateFontString(nil, "OVERLAY", "GameFontNormalLarge")
    f.arrowSign:SetPoint("CENTER", 120, 0)
    f.arrowSign:SetText("|cff444444→|r")
    
    -- Ultimate display
    f.selectedUltIcon = f.selectionBar:CreateTexture(nil, "ARTWORK")
    f.selectedUltIcon:SetSize(35, 35)
    f.selectedUltIcon:SetPoint("RIGHT", -50, 0)
    f.selectedUltIcon:SetTexCoord(0.08, 0.92, 0.08, 0.92)
    f.selectedUltIcon:SetTexture("Interface\\Icons\\INV_Misc_QuestionMark")
    
    -- Content area
    f.contentArea = CreateFrame("Frame", nil, f)
    f.contentArea:SetSize(490, 320)
    f.contentArea:SetPoint("TOP", 0, -85)
    
    -- === TAB 1: RACE SELECTION ===
    f.raceTab = CreateFrame("Frame", nil, f.contentArea)
    f.raceTab:SetAllPoints()
    
    f.raceButtons = {}
    local raceList = {"HUMAN", "DWARF", "NIGHTELF", "GNOME", "DRAENEI", "WORGEN", "ORC", "UNDEAD", "TAUREN", "TROLL", "BLOODELF", "GOBLIN", "PANDAREN", "DRACTHYR"}
    
    for i, raceName in ipairs(raceList) do
        local raceData = addon.RACES and addon.RACES[raceName]
        if raceData then
            local col, row = ((i-1) % 7), math.floor((i-1) / 7)
            
            local btn = CreateFrame("Button", nil, f.raceTab, "BackdropTemplate")
            btn:SetSize(65, 70)
            btn:SetPoint("TOPLEFT", 8 + col * 69, -5 - row * 75)
            btn:SetBackdrop({
                bgFile = "Interface\\ChatFrame\\ChatFrameBackground",
                edgeFile = "Interface\\Tooltips\\UI-Tooltip-Border",
                tile = true, tileSize = 16, edgeSize = 6,
                insets = {left=1, right=1, top=1, bottom=1}
            })
            btn:SetBackdropColor(0.08, 0.08, 0.12, 0.95)
            
            btn.icon = btn:CreateTexture(nil, "ARTWORK")
            btn.icon:SetSize(40, 40)
            btn.icon:SetPoint("TOP", 0, -5)
            btn.icon:SetTexture(raceData.icon)
            btn.icon:SetTexCoord(0.08, 0.92, 0.08, 0.92)
            
            btn.nameText = btn:CreateFontString(nil, "OVERLAY", "GameFontNormalSmall")
            btn.nameText:SetPoint("BOTTOM", 0, 3)
            btn.nameText:SetText(raceData.name)
            btn.nameText:SetWidth(62)
            
            btn.lockOverlay = btn:CreateTexture(nil, "OVERLAY")
            btn.lockOverlay:SetAllPoints(btn.icon)
            btn.lockOverlay:SetColorTexture(0, 0, 0, 0.6)
            btn.lockOverlay:Hide()
            
            btn.raceName = raceName
            
            btn:SetScript("OnClick", function()
                addon:SelectRaceAndShowClasses(raceName)
            end)
            
            btn:SetScript("OnEnter", function(self)
                self:SetBackdropColor(0.15, 0.15, 0.2, 1)
                GameTooltip:SetOwner(self, "ANCHOR_RIGHT")
                GameTooltip:SetText(raceData.name)
                GameTooltip:AddLine(raceData.faction, 0.6, 0.6, 0.6)
                GameTooltip:AddLine(" ")
                local typeStr = raceData.abilityType == "pvp" and "|cffff4444[PvP]|r " or "|cff00ff00[Solo]|r "
                GameTooltip:AddLine(typeStr .. raceData.ability.name, 1, 0.8, 0)
                GameTooltip:AddLine(raceData.ability.description, 1, 1, 1, true)
                if raceData.cost > 0 and not (addon.IsRaceUnlocked and addon:IsRaceUnlocked(raceName)) then
                    GameTooltip:AddLine(" ")
                    GameTooltip:AddLine("Cost: " .. raceData.cost .. " Coins", 1, 0.5, 0)
                end
                GameTooltip:Show()
            end)
            btn:SetScript("OnLeave", function(self)
                GameTooltip:Hide()
                addon:UpdateRaceButtonHighlight(self)
            end)
            
            f.raceButtons[i] = btn
        end
    end
    
    -- Racial ability preview (bottom of race tab)
    f.racialPreview = CreateFrame("Frame", nil, f.raceTab, "BackdropTemplate")
    f.racialPreview:SetSize(480, 55)
    f.racialPreview:SetPoint("BOTTOM", 0, 5)
    f.racialPreview:SetBackdrop({
        bgFile = "Interface\\ChatFrame\\ChatFrameBackground",
        edgeFile = "Interface\\Tooltips\\UI-Tooltip-Border",
        tile = true, tileSize = 16, edgeSize = 8,
        insets = {left=2, right=2, top=2, bottom=2}
    })
    f.racialPreview:SetBackdropColor(0.05, 0.08, 0.05, 0.9)
    f.racialPreview:SetBackdropBorderColor(0.3, 0.5, 0.3, 1)
    
    f.racialPreviewIcon = f.racialPreview:CreateTexture(nil, "ARTWORK")
    f.racialPreviewIcon:SetSize(40, 40)
    f.racialPreviewIcon:SetPoint("LEFT", 10, 0)
    f.racialPreviewIcon:SetTexCoord(0.08, 0.92, 0.08, 0.92)
    
    f.racialPreviewName = f.racialPreview:CreateFontString(nil, "OVERLAY", "GameFontNormal")
    f.racialPreviewName:SetPoint("TOPLEFT", f.racialPreviewIcon, "TOPRIGHT", 10, -5)
    f.racialPreviewName:SetText("|cff888888Hover over a race to see its ability|r")
    
    f.racialPreviewDesc = f.racialPreview:CreateFontString(nil, "OVERLAY", "GameFontNormalSmall")
    f.racialPreviewDesc:SetPoint("TOPLEFT", f.racialPreviewName, "BOTTOMLEFT", 0, -3)
    f.racialPreviewDesc:SetWidth(410)
    f.racialPreviewDesc:SetJustifyH("LEFT")
    f.racialPreviewDesc:SetText("")
    
    -- === CLASS POPUP (side panel) ===
    f.classPopup = CreateFrame("Frame", nil, f, "BackdropTemplate")
    f.classPopup:SetSize(200, 320)
    f.classPopup:SetPoint("LEFT", f, "RIGHT", 5, 0)
    f.classPopup:SetBackdrop({
        bgFile = "Interface\\ChatFrame\\ChatFrameBackground",
        edgeFile = "Interface\\Tooltips\\UI-Tooltip-Border",
        tile = true, tileSize = 16, edgeSize = 12,
        insets = {left=2, right=2, top=2, bottom=2}
    })
    f.classPopup:SetBackdropColor(0.06, 0.06, 0.1, 0.98)
    f.classPopup:SetBackdropBorderColor(0.5, 0.4, 0.2, 1)
    f.classPopup:Hide()
    
    f.classPopup.title = f.classPopup:CreateFontString(nil, "OVERLAY", "GameFontNormal")
    f.classPopup.title:SetPoint("TOP", 0, -10)
    f.classPopup.title:SetText("|cffffd700Available Classes|r")
    
    f.classPopup.raceIcon = f.classPopup:CreateTexture(nil, "ARTWORK")
    f.classPopup.raceIcon:SetSize(30, 30)
    f.classPopup.raceIcon:SetPoint("TOPLEFT", 10, -30)
    f.classPopup.raceIcon:SetTexCoord(0.08, 0.92, 0.08, 0.92)
    
    f.classPopup.raceName = f.classPopup:CreateFontString(nil, "OVERLAY", "GameFontNormalSmall")
    f.classPopup.raceName:SetPoint("LEFT", f.classPopup.raceIcon, "RIGHT", 5, 0)
    
    f.classButtons = {}
    local allClasses = {"WARRIOR", "PALADIN", "HUNTER", "ROGUE", "PRIEST", "DEATHKNIGHT", "SHAMAN", "MAGE", "WARLOCK", "DRUID", "MONK", "DEMONHUNTER", "EVOKER"}
    
    for i, className in ipairs(allClasses) do
        local cd = addon.CLASSES[className]
        local col, row = ((i-1) % 3), math.floor((i-1) / 3)
        
        local btn = CreateFrame("Button", nil, f.classPopup, "BackdropTemplate")
        btn:SetSize(58, 58)
        btn:SetPoint("TOPLEFT", 10 + col * 62, -65 - row * 62)
        btn:SetBackdrop({
            bgFile = "Interface\\ChatFrame\\ChatFrameBackground",
            edgeFile = "Interface\\Tooltips\\UI-Tooltip-Border",
            tile = true, tileSize = 16, edgeSize = 6,
            insets = {left=1, right=1, top=1, bottom=1}
        })
        btn:SetBackdropColor(0.1, 0.1, 0.15, 0.95)
        
        btn.icon = btn:CreateTexture(nil, "ARTWORK")
        btn.icon:SetSize(40, 40)
        btn.icon:SetPoint("TOP", 0, -3)
        btn.icon:SetTexture(cd.icon)
        btn.icon:SetTexCoord(0.08, 0.92, 0.08, 0.92)
        
        btn.nameText = btn:CreateFontString(nil, "OVERLAY", "GameFontNormalSmall")
        btn.nameText:SetPoint("BOTTOM", 0, 2)
        btn.nameText:SetText(cd.colorCode .. string.sub(cd.name, 1, 6) .. "|r")
        
        btn.lockOverlay = btn:CreateTexture(nil, "OVERLAY")
        btn.lockOverlay:SetAllPoints(btn.icon)
        btn.lockOverlay:SetColorTexture(0, 0, 0, 0.7)
        btn.lockOverlay:Hide()
        
        btn.lockIcon = btn:CreateTexture(nil, "OVERLAY")
        btn.lockIcon:SetSize(16, 16)
        btn.lockIcon:SetPoint("CENTER", btn.icon)
        btn.lockIcon:SetTexture("Interface\\PetBattles\\PetBattle-LockIcon")
        btn.lockIcon:Hide()
        
        btn.unavailable = btn:CreateTexture(nil, "OVERLAY")
        btn.unavailable:SetAllPoints(btn.icon)
        btn.unavailable:SetColorTexture(0.3, 0, 0, 0.6)
        btn.unavailable:Hide()
        
        btn.className = className
        btn.isPremium = cd.premium
        
        btn:SetScript("OnClick", function()
            addon:SelectClassFromPopup(className)
        end)
        
        btn:SetScript("OnEnter", function(self)
            self:SetBackdropColor(0.2, 0.2, 0.25, 1)
            GameTooltip:SetOwner(self, "ANCHOR_RIGHT")
            GameTooltip:SetText(cd.colorCode .. cd.name .. "|r")
            if self.isUnavailable then
                GameTooltip:AddLine("Not available for this race", 1, 0.3, 0.3)
            elseif cd.premium and not addon:OwnsItem(className, "class") then
                GameTooltip:AddLine("LOCKED - Purchase from Shop", 1, 0.3, 0.3)
            else
                local stats = addon:GetClassStats(className)
                local rank = addon:GetLevelRank(stats.level)
                GameTooltip:AddLine("Level " .. stats.level .. " - " .. rank.name, rank.rgb[1], rank.rgb[2], rank.rgb[3])
            end
            GameTooltip:Show()
        end)
        btn:SetScript("OnLeave", function(self)
            GameTooltip:Hide()
            self:SetBackdropColor(0.1, 0.1, 0.15, 0.95)
        end)
        
        f.classButtons[i] = btn
    end
    
    -- === TAB 2: ULTIMATE SELECTION ===
    f.ultTab = CreateFrame("Frame", nil, f.contentArea)
    f.ultTab:SetAllPoints()
    f.ultTab:Hide()
    
    f.ultimateButtons = {}
    for i = 1, 9 do
        local btn = CreateFrame("Button", nil, f.ultTab, "BackdropTemplate")
        btn:SetSize(90, 95)
        local row = math.ceil(i / 5)
        local col = ((i - 1) % 5) + 1
        btn:SetPoint("TOPLEFT", 5 + (col-1) * 96, -5 - (row-1) * 100)
        btn:SetBackdrop({
            bgFile = "Interface\\ChatFrame\\ChatFrameBackground",
            edgeFile = "Interface\\Tooltips\\UI-Tooltip-Border",
            tile = true, tileSize = 16, edgeSize = 8,
            insets = {left=2, right=2, top=2, bottom=2}
        })
        btn:SetBackdropColor(0.1, 0.06, 0.02, 0.95)
        btn:SetBackdropBorderColor(0.5, 0.3, 0.1, 1)
        
        btn.icon = btn:CreateTexture(nil, "ARTWORK")
        btn.icon:SetSize(50, 50)
        btn.icon:SetPoint("TOP", 0, -5)
        btn.icon:SetTexCoord(0.08, 0.92, 0.08, 0.92)
        
        btn.name = btn:CreateFontString(nil, "OVERLAY", "GameFontNormalSmall")
        btn.name:SetPoint("BOTTOM", 0, 15)
        btn.name:SetWidth(85)
        
        btn.locked = btn:CreateFontString(nil, "OVERLAY", "GameFontNormalSmall")
        btn.locked:SetPoint("BOTTOM", 0, 3)
        
        btn.shopBadge = btn:CreateFontString(nil, "OVERLAY", "GameFontNormalSmall")
        btn.shopBadge:SetPoint("TOPRIGHT", -3, -3)
        
        btn:SetScript("OnEnter", function(self)
            if self.ultData then
                GameTooltip:SetOwner(self, "ANCHOR_RIGHT")
                GameTooltip:SetText("|cffff6600" .. self.ultData.name .. "|r")
                GameTooltip:AddLine(self.ultData.description, 1, 1, 1, true)
                if self.ultData.isShopItem then
                    GameTooltip:AddLine("[Shop Ultimate]", 0, 1, 0)
                end
                if self.ultData.locked then
                    GameTooltip:AddLine("Unlocks at Level " .. self.ultData.unlockLevel, 1, 0, 0)
                end
                GameTooltip:Show()
            end
        end)
        btn:SetScript("OnLeave", function() GameTooltip:Hide() end)
        
        f.ultimateButtons[i] = btn
        btn:Hide()
    end
    
    -- PvP Section at bottom of ultimate tab
    f.pvpSection = CreateFrame("Frame", nil, f.ultTab)
    f.pvpSection:SetSize(480, 65)
    f.pvpSection:SetPoint("BOTTOM", 0, 5)
    f.pvpSection:Hide()
    
    f.pvpLabel = f.pvpSection:CreateFontString(nil, "OVERLAY", "GameFontNormalSmall")
    f.pvpLabel:SetPoint("TOPLEFT", 5, 0)
    f.pvpLabel:SetText("|cffff0000PvP Sabotage:|r")
    
    f.pvpButtons = {}
    for i = 1, 3 do
        local btn = CreateFrame("Button", nil, f.pvpSection, "BackdropTemplate")
        btn:SetSize(155, 48)
        btn:SetPoint("TOPLEFT", 5 + (i-1) * 160, -15)
        btn:SetBackdrop({
            bgFile = "Interface\\ChatFrame\\ChatFrameBackground",
            edgeFile = "Interface\\Tooltips\\UI-Tooltip-Border",
            tile = true, tileSize = 16, edgeSize = 6,
            insets = {left=1, right=1, top=1, bottom=1}
        })
        btn:SetBackdropColor(0.12, 0.05, 0.05, 0.95)
        btn:SetBackdropBorderColor(0.4, 0.2, 0.2, 1)
        
        btn.icon = btn:CreateTexture(nil, "ARTWORK")
        btn.icon:SetSize(35, 35)
        btn.icon:SetPoint("LEFT", 5, 0)
        btn.icon:SetTexCoord(0.08, 0.92, 0.08, 0.92)
        
        btn.name = btn:CreateFontString(nil, "OVERLAY", "GameFontNormalSmall")
        btn.name:SetPoint("LEFT", btn.icon, "RIGHT", 5, 0)
        btn.name:SetWidth(100)
        btn.name:SetJustifyH("LEFT")
        
        btn:SetScript("OnEnter", function(self)
            if self.pvpData then
                GameTooltip:SetOwner(self, "ANCHOR_TOP")
                GameTooltip:SetText("|cffff0000" .. self.pvpData.name .. "|r")
                GameTooltip:AddLine(self.pvpData.description, 1, 1, 1, true)
                GameTooltip:Show()
            end
        end)
        btn:SetScript("OnLeave", function() GameTooltip:Hide() end)
        
        f.pvpButtons[i] = btn
    end
    
    -- PvP checkbox
    f.pvpCheckbox = CreateFrame("CheckButton", nil, f, "UICheckButtonTemplate")
    f.pvpCheckbox:SetSize(18, 18)
    f.pvpCheckbox:SetPoint("BOTTOMLEFT", 120, 15)
    f.pvpCheckbox.text = f.pvpCheckbox:CreateFontString(nil, "OVERLAY", "GameFontNormalSmall")
    f.pvpCheckbox.text:SetPoint("LEFT", f.pvpCheckbox, "RIGHT", 2, 0)
    f.pvpCheckbox.text:SetText("|cff888888PvP Talents|r")
    f.pvpCheckbox:SetScript("OnClick", function(self)
        f.pvpSection:SetShown(self:GetChecked())
        if self:GetChecked() then addon:UpdatePvPButtons() end
    end)
    f.pvpCheckbox:Hide()
    
    -- === NAVIGATION ===
    f.backBtn = CreateFrame("Button", nil, f, "BackdropTemplate")
    f.backBtn:SetSize(90, 28)
    f.backBtn:SetPoint("BOTTOMLEFT", 15, 12)
    f.backBtn:SetBackdrop({
        bgFile = "Interface\\ChatFrame\\ChatFrameBackground",
        edgeFile = "Interface\\Tooltips\\UI-Tooltip-Border",
        tile = true, tileSize = 16, edgeSize = 8,
        insets = {left=2, right=2, top=2, bottom=2}
    })
    f.backBtn:SetBackdropColor(0.15, 0.1, 0.1, 0.9)
    f.backBtn.text = f.backBtn:CreateFontString(nil, "OVERLAY", "GameFontNormalSmall")
    f.backBtn.text:SetPoint("CENTER")
    f.backBtn.text:SetText("|cffaaaaaaMenu|r")
    f.backBtn:SetScript("OnEnter", function(self) self:SetBackdropColor(0.25, 0.15, 0.15, 1) end)
    f.backBtn:SetScript("OnLeave", function(self) self:SetBackdropColor(0.15, 0.1, 0.1, 0.9) end)
    f.backBtn:SetScript("OnClick", function()
        if f.currentTab == 1 then
            f:Hide()
            f.classPopup:Hide()
            addon:ShowMenu()
        else
            addon:SetClassSelectTab(1)
        end
    end)
    
    f.confirmBtn = CreateFrame("Button", nil, f, "BackdropTemplate")
    f.confirmBtn:SetSize(130, 32)
    f.confirmBtn:SetPoint("BOTTOMRIGHT", -15, 10)
    f.confirmBtn:SetBackdrop({
        bgFile = "Interface\\ChatFrame\\ChatFrameBackground",
        edgeFile = "Interface\\Tooltips\\UI-Tooltip-Border",
        tile = true, tileSize = 16, edgeSize = 10,
        insets = {left=2, right=2, top=2, bottom=2}
    })
    f.confirmBtn:SetBackdropColor(0.1, 0.35, 0.1, 0.95)
    f.confirmBtn:SetBackdropBorderColor(0.3, 0.6, 0.3, 1)
    f.confirmBtn.text = f.confirmBtn:CreateFontString(nil, "OVERLAY", "GameFontNormal")
    f.confirmBtn.text:SetPoint("CENTER")
    f.confirmBtn.text:SetText("|cffffffffNext|r")
    f.confirmBtn:SetScript("OnEnter", function(self) self:SetBackdropColor(0.15, 0.45, 0.15, 1) end)
    f.confirmBtn:SetScript("OnLeave", function(self) self:SetBackdropColor(0.1, 0.35, 0.1, 0.95) end)
    f.confirmBtn:SetScript("OnClick", function()
        if f.currentTab == 1 then
            if not addon.selectedClass then
                print("|cffff0000[Tetris]|r Please select a class!")
                return
            end
            addon:SetClassSelectTab(2)
        elseif f.currentTab == 2 then
            if not addon.selectedUltimate then
                print("|cffff0000[Tetris]|r Please select an ultimate!")
                return
            end
            if f.forPvP and not addon.mpState.selectedPvPAbility then
                print("|cffff0000[Tetris]|r Please select a PvP sabotage!")
                return
            end
            f:Hide()
            f.classPopup:Hide()
            addon.ultimateLocked = true
            addon.pvpAbilityLocked = true
            
            -- Update menu display
            addon:UpdateMenuDisplay()
            
            if f.forPvP then
                if f.onReady then f.onReady() end
            elseif f.menuOnly then
                -- Just return to menu, don't start game
                addon:ShowMenu()
                print("|cff00ff00[Tetris]|r Selection saved! Ready to play.")
            else
                addon:StartGame()
            end
        end
    end)
    
    addon.classSelectFrame = f
end

-- Select race and show class popup
function addon:SelectRaceAndShowClasses(raceName)
    local f = addon.classSelectFrame
    if not f then return end
    
    local raceData = addon.RACES and addon.RACES[raceName]
    if not raceData then return end
    
    -- Check if locked
    if raceData.cost > 0 and not (addon.IsRaceUnlocked and addon:IsRaceUnlocked(raceName)) then
        print("|cffff0000[Tetris]|r This race is locked! Purchase from Shop.")
        return
    end
    
    addon.selectedRace = raceName
    addon.db.selectedRace = raceName
    
    -- Update selection bar
    f.selectedRaceIcon:SetTexture(raceData.icon)
    f.selectedRaceName:SetText(raceData.name)
    
    -- Update race button highlights
    addon:UpdateRaceButtons()
    
    -- Show class popup
    f.classPopup.raceIcon:SetTexture(raceData.icon)
    f.classPopup.raceName:SetText(raceData.name)
    
    -- Update class buttons for this race
    for i, btn in ipairs(f.classButtons) do
        local className = btn.className
        local cd = addon.CLASSES[className]
        local canUse = addon:CanRaceUseClass(raceName, className)
        local isOwned = not cd.premium or addon:OwnsItem(className, "class")
        
        btn.unavailable:SetShown(not canUse)
        btn.lockOverlay:SetShown(not isOwned and canUse)
        btn.lockIcon:SetShown(not isOwned and canUse)
        btn.icon:SetDesaturated(not canUse or not isOwned)
        btn.isUnavailable = not canUse
        
        if canUse and isOwned then
            btn:SetBackdropBorderColor(0.4, 0.4, 0.4, 1)
        else
            btn:SetBackdropBorderColor(0.3, 0.2, 0.2, 1)
        end
    end
    
    f.classPopup:Show()
end

-- Select class from popup
function addon:SelectClassFromPopup(className)
    local f = addon.classSelectFrame
    if not f then return end
    
    local cd = addon.CLASSES[className]
    
    -- Check if available for race
    if addon.selectedRace and not addon:CanRaceUseClass(addon.selectedRace, className) then
        print("|cffff0000[Tetris]|r This race cannot be this class!")
        return
    end
    
    -- Check if owned
    if cd.premium and not addon:OwnsItem(className, "class") then
        print("|cffff0000[Tetris]|r This class is locked! Purchase from Shop.")
        return
    end
    
    addon.selectedClass = className
    addon.db.selectedClass = className
    addon.selectedUltimate = nil
    
    -- Update selection bar
    f.selectedClassIcon:SetTexture(cd.icon)
    f.selectedClassName:SetText(cd.colorCode .. cd.name .. "|r")
    
    -- Highlight selected class
    for i, btn in ipairs(f.classButtons) do
        if btn.className == className then
            btn:SetBackdropColor(0.2, 0.4, 0.2, 1)
            btn:SetBackdropBorderColor(0.3, 0.7, 0.3, 1)
        else
            btn:SetBackdropColor(0.1, 0.1, 0.15, 0.95)
            if not btn.isUnavailable then
                btn:SetBackdropBorderColor(0.4, 0.4, 0.4, 1)
            end
        end
    end
    
    addon:UpdateMenuDisplay()
end

-- Set which tab is shown in class selection
function addon:SetClassSelectTab(tabNum)
    local f = addon.classSelectFrame
    if not f then return end
    
    f.currentTab = tabNum
    f.raceTab:Hide()
    f.ultTab:Hide()
    f.classPopup:Hide()
    f.pvpCheckbox:Hide()
    
    if tabNum == 1 then
        f.title:SetText("|cffffd700Step 1: Choose Race & Class|r")
        f.raceTab:Show()
        f.backBtn.text:SetText("|cffaaaaaaMenu|r")
        f.confirmBtn.text:SetText("|cffffffffNext|r")
        addon:UpdateRaceButtons()
        -- Show class popup if race selected
        if addon.selectedRace then
            addon:SelectRaceAndShowClasses(addon.selectedRace)
        end
    elseif tabNum == 2 then
        f.title:SetText("|cffff6600Step 2: Choose Ultimate|r")
        f.ultTab:Show()
        f.backBtn.text:SetText("|cffaaaaaaBack|r")
        if f.forPvP then
            f.confirmBtn.text:SetText("|cffffffffREADY|r")
            f.pvpSection:Show()
            addon:UpdatePvPButtons()
        elseif f.menuOnly then
            f.confirmBtn.text:SetText("|cffffffffOK|r")
            f.pvpCheckbox:Show()
        else
            f.confirmBtn.text:SetText("|cffffffffSTART|r")
            f.pvpCheckbox:Show()
        end
        addon:UpdateUltimateButtons()
    end
    
    -- Update selection bar
    addon:UpdateSelectionBar()
end

-- Update the top selection bar
function addon:UpdateSelectionBar()
    local f = addon.classSelectFrame
    if not f then return end
    
    -- Race
    if addon.selectedRace and addon.RACES[addon.selectedRace] then
        local rd = addon.RACES[addon.selectedRace]
        f.selectedRaceIcon:SetTexture(rd.icon)
        f.selectedRaceName:SetText(rd.name)
    else
        f.selectedRaceIcon:SetTexture("Interface\\Icons\\INV_Misc_QuestionMark")
        f.selectedRaceName:SetText("|cff666666Race|r")
    end
    
    -- Class
    if addon.selectedClass and addon.CLASSES[addon.selectedClass] then
        local cd = addon.CLASSES[addon.selectedClass]
        f.selectedClassIcon:SetTexture(cd.icon)
        f.selectedClassName:SetText(cd.colorCode .. cd.name .. "|r")
    else
        f.selectedClassIcon:SetTexture("Interface\\Icons\\INV_Misc_QuestionMark")
        f.selectedClassName:SetText("|cff666666Class|r")
    end
    
    -- Ultimate
    if addon.selectedUltimate then
        f.selectedUltIcon:SetTexture(addon.selectedUltimate.icon)
    else
        f.selectedUltIcon:SetTexture("Interface\\Icons\\INV_Misc_QuestionMark")
    end
end

function addon:UpdateFrameSize()
    local f = addon.classSelectFrame
    if not f then return end
    
    local showPvP = f.pvpSection:IsShown()
    if showPvP then
        f:SetSize(580, 975)  -- With PvP section (taller for 2 rows of ultimates)
        if not f.forPvP then
            f.pvpLabel:SetText("|cff888888PvP Sabotage (Preview):|r")
        end
    else
        f:SetSize(580, 885)  -- Default (taller for 2 rows of ultimates)
    end
end

-- Race selection
function addon:SelectRace(raceName)
    local raceData = addon.RACES and addon.RACES[raceName]
    if not raceData then return end
    
    -- Check if race is unlocked
    if raceData.cost > 0 and not (addon.IsRaceUnlocked and addon:IsRaceUnlocked(raceName)) then
        print("|cffff0000[Tetris]|r This race is locked! Purchase it from the Shop.")
        return
    end
    
    -- Check if race can use current class
    if addon.selectedClass and not addon:CanRaceUseClass(raceName, addon.selectedClass) then
        print("|cffff0000[Tetris]|r " .. raceData.name .. " cannot be a " .. addon.CLASSES[addon.selectedClass].name .. "!")
        return
    end
    
    -- Check if changing race with same class (progression reset warning)
    local oldRace = addon.selectedRace
    if oldRace and oldRace ~= raceName and addon.selectedClass then
        -- Different race for same class = new progression
        local stats = addon:GetClassStats(addon.selectedClass, raceName)
        if stats.level == 1 then
            print("|cffffff00[Tetris]|r New combination! " .. raceData.name .. " " .. addon.CLASSES[addon.selectedClass].name .. " starts at Level 1.")
        end
    end
    
    addon.selectedRace = raceName
    addon.db.selectedRace = raceName
    
    -- Update race buttons
    addon:UpdateRaceButtons()
    
    -- Update menu display
    addon:UpdateMenuDisplay()
    
    -- Show race ability info
    if addon.classSelectFrame and addon.classSelectFrame.raceInfo then
        addon.classSelectFrame.raceInfo:SetText("|cff00ff00" .. raceData.ability.name .. "|r")
    end
end

function addon:UpdateRaceButtons()
    if not addon.classSelectFrame or not addon.classSelectFrame.raceButtons then return end
    
    for i, btn in ipairs(addon.classSelectFrame.raceButtons) do
        addon:UpdateRaceButtonHighlight(btn)
    end
end

function addon:UpdateRaceButtonHighlight(btn)
    if not btn or not btn.raceName then return end
    
    local raceName = btn.raceName
    local raceData = addon.RACES and addon.RACES[raceName]
    if not raceData then return end
    
    local isSelected = addon.selectedRace == raceName
    local isUnlocked = raceData.cost == 0 or (addon.IsRaceUnlocked and addon:IsRaceUnlocked(raceName))
    local canUseClass = not addon.selectedClass or addon:CanRaceUseClass(raceName, addon.selectedClass)
    
    if isSelected then
        btn:SetBackdropColor(0.1, 0.3, 0.1, 1)
        btn:SetBackdropBorderColor(0.3, 0.9, 0.3, 1)
    elseif not isUnlocked then
        btn:SetBackdropColor(0.15, 0.1, 0.1, 0.95)
        btn:SetBackdropBorderColor(0.5, 0.3, 0.3, 1)
        btn.lockOverlay:Show()
    elseif not canUseClass then
        btn:SetBackdropColor(0.1, 0.1, 0.1, 0.7)
        btn:SetBackdropBorderColor(0.3, 0.3, 0.3, 0.7)
        btn.icon:SetDesaturated(true)
        btn.lockOverlay:Hide()
    else
        btn:SetBackdropColor(0.05, 0.1, 0.05, 0.95)
        btn:SetBackdropBorderColor(0.3, 0.5, 0.3, 1)
        btn.icon:SetDesaturated(false)
        btn.lockOverlay:Hide()
    end
end

-- Check if race can use class
function addon:CanRaceUseClass(raceKey, classKey)
    local raceData = addon.RACES and addon.RACES[raceKey]
    if not raceData then return false end
    for _, allowedClass in ipairs(raceData.classes) do
        if allowedClass == classKey then return true end
    end
    return false
end

function addon:UpdateClassButtonHighlight(btn)
    if not btn then return end
    local className = btn.className
    local isPremium = btn.isPremium
    local isOwned = not isPremium or addon:OwnsItem(className, "class")
    local isSelected = addon.selectedClass == className
    
    if isSelected and isOwned then
        btn:SetBackdropColor(0.1, 0.25, 0.1, 1)
        btn:SetBackdropBorderColor(0.3, 0.8, 0.3, 1)
        btn.icon:SetDesaturated(false)
        btn.lockOverlay:Hide()
        btn.lockIcon:Hide()
    elseif not isOwned then
        btn:SetBackdropColor(0.1, 0.05, 0.05, 0.95)
        btn:SetBackdropBorderColor(0.5, 0.3, 0.3, 1)
        btn.icon:SetDesaturated(true)
        btn.lockOverlay:Show()
        btn.lockIcon:Show()
    else
        btn:SetBackdropColor(0.08, 0.08, 0.1, 0.95)
        btn:SetBackdropBorderColor(0.4, 0.4, 0.45, 1)
        btn.icon:SetDesaturated(false)
        btn.lockOverlay:Hide()
        btn.lockIcon:Hide()
    end
end

function addon:UpdateClassSelectionHighlight()
    if not addon.classSelectFrame then return end
    for _, btn in ipairs(addon.classSelectFrame.classButtons) do
        addon:UpdateClassButtonHighlight(btn)
    end
    
    -- Also update race buttons when class changes
    addon:UpdateRaceButtons()
end

function addon:UpdateUltimateButtons()
    if not addon.classSelectFrame or not addon.selectedClass then return end
    
    local ultimates = addon:GetAvailableUltimates()
    local f = addon.classSelectFrame
    
    for i, btn in ipairs(f.ultimateButtons) do
        local ult = ultimates[i]
        if ult then
            btn.ultData = ult
            btn.icon:SetTexture(ult.icon)
            btn.name:SetText(ult.name)
            
            -- Show shop badge for shop ultimates
            if ult.isShopItem then
                btn.shopBadge:SetText("|cff00ff00$|r")
            else
                btn.shopBadge:SetText("")
            end
            
            if ult.locked then
                btn.locked:SetText("|cffff0000Lv " .. ult.unlockLevel .. "|r")
                btn.icon:SetDesaturated(true)
                btn:SetBackdropColor(0.05, 0.05, 0.05, 0.9)
                btn:SetScript("OnClick", nil)
            else
                btn.locked:SetText("")
                btn.icon:SetDesaturated(false)
                btn:SetBackdropColor(0.1, 0.05, 0.02, 0.95)
                btn:SetScript("OnClick", function()
                    addon.selectedUltimate = ult
                    addon.db.selectedUltimateName = ult.name  -- Save ultimate name
                    addon:UpdateUltimateHighlight()
                end)
            end
            btn:Show()
        else
            btn:Hide()
        end
    end
    
    -- Select first available ultimate by default
    if not addon.selectedUltimate then
        for _, ult in ipairs(ultimates) do
            if not ult.locked then
                addon.selectedUltimate = ult
                addon.db.selectedUltimateName = ult.name  -- Save ultimate name
                break
            end
        end
    end
    addon:UpdateUltimateHighlight()
    
    -- Update PvP buttons if visible
    addon:UpdatePvPButtons()
end

function addon:UpdateUltimateHighlight()
    if not addon.classSelectFrame then return end
    for _, btn in ipairs(addon.classSelectFrame.ultimateButtons) do
        if btn.ultData and addon.selectedUltimate and btn.ultData.name == addon.selectedUltimate.name then
            btn:SetBackdropColor(0.2, 0.15, 0.05, 1)
            btn:SetBackdropBorderColor(0.8, 0.6, 0.2, 1)
        elseif btn.ultData and not btn.ultData.locked then
            btn:SetBackdropColor(0.1, 0.05, 0.02, 0.95)
            btn:SetBackdropBorderColor(0.5, 0.3, 0.1, 1)
        end
    end
end

function addon:UpdatePvPButtons()
    if not addon.classSelectFrame or not addon.selectedClass then return end
    local f = addon.classSelectFrame
    
    if not f.pvpSection:IsShown() then return end
    
    local abilities = addon.PVP_ABILITIES[addon.selectedClass]
    if not abilities then return end
    
    local stats = addon:GetClassStats(addon.selectedClass)
    local playerLevel = stats.level or 1
    
    for i, btn in ipairs(f.pvpButtons) do
        local ability = abilities[i]
        if ability then
            local isLocked = playerLevel < (ability.unlockLevel or 1)
            btn.pvpData = ability
            btn.pvpData.locked = isLocked
            btn.icon:SetTexture(ability.icon)
            btn.icon:SetDesaturated(isLocked)
            
            if isLocked then
                btn.name:SetText("|cff666666Lv " .. ability.unlockLevel .. "|r")
                btn:SetBackdropColor(0.1, 0.1, 0.1, 0.9)
                btn:SetBackdropBorderColor(0.3, 0.3, 0.3, 1)
                btn:SetScript("OnClick", function()
                    print("|cffff0000[Tetris]|r " .. ability.name .. " unlocks at Level " .. ability.unlockLevel .. "!")
                end)
            else
                btn.name:SetText(ability.name)
                btn:SetScript("OnClick", function()
                    addon.mpState.selectedPvPAbility = ability
                    addon:UpdatePvPHighlight()
                end)
            end
            btn:Show()
        else
            btn:Hide()
        end
    end
    
    -- Select first unlocked ability by default
    if not addon.mpState.selectedPvPAbility or addon.mpState.selectedPvPAbility.locked then
        for _, ability in ipairs(abilities) do
            if playerLevel >= (ability.unlockLevel or 1) then
                addon.mpState.selectedPvPAbility = ability
                break
            end
        end
    end
    addon:UpdatePvPHighlight()
end

function addon:UpdatePvPHighlight()
    if not addon.classSelectFrame then return end
    for _, btn in ipairs(addon.classSelectFrame.pvpButtons) do
        if btn.pvpData and addon.mpState.selectedPvPAbility and btn.pvpData.name == addon.mpState.selectedPvPAbility.name then
            btn:SetBackdropColor(0.3, 0.1, 0.1, 1)
            btn:SetBackdropBorderColor(1, 0.3, 0.3, 1)
        elseif btn.pvpData then
            btn:SetBackdropColor(0.15, 0.05, 0.05, 0.95)
            btn:SetBackdropBorderColor(0.6, 0.2, 0.2, 1)
        end
    end
end

function addon:ShowClassSelection(forPvP, onReadyCallback, menuOnly)
    -- Force recreate frame if needed
    if addon.classSelectFrame and addon.classSelectFrame.ultimateButtons and #addon.classSelectFrame.ultimateButtons < 9 then
        addon.classSelectFrame:Hide()
        addon.classSelectFrame = nil
    end
    
    if not addon.classSelectFrame then
        addon:CreateClassSelectionFrame()
    end
    
    if addon.classSelectFrame then 
        local f = addon.classSelectFrame
        f.forPvP = forPvP
        f.onReady = onReadyCallback
        f.menuOnly = menuOnly  -- Just selecting, not starting game
        
        -- Always start at tab 1 (class selection)
        addon:SetClassSelectTab(1)
        
        -- Set PvP mode settings
        if forPvP then
            f.pvpCheckbox:SetChecked(true)
        end
        
        f:Show() 
    end
end

function addon:CreateUltimateSelectionFrame()
    local f = CreateFrame("Frame", "WoWTetrisUltSelect", mainFrame, "BackdropTemplate")
    f:SetSize(350, 400)
    f:SetPoint("CENTER")
    f:SetBackdrop({bgFile = "Interface\\DialogFrame\\UI-DialogBox-Background-Dark", edgeFile = "Interface\\DialogFrame\\UI-DialogBox-Gold-Border", tile = true, tileSize = 32, edgeSize = 32, insets = {left=8, right=8, top=8, bottom=8}})
    f:SetFrameLevel(mainFrame:GetFrameLevel() + 50)
    f:Hide()
    local title = f:CreateFontString(nil, "OVERLAY", "GameFontNormalLarge")
    title:SetPoint("TOP", 0, -15)
    title:SetText("|cffff6600Select Ultimate|r")
    local closeBtn = CreateFrame("Button", nil, f, "UIPanelCloseButton")
    closeBtn:SetPoint("TOPRIGHT", -5, -5)
    f.buttons = {}
    addon.ultimateSelectFrame = f
end

function addon:ShowUltimateSelection()
    -- During a game, ultimate is locked
    if addon.ultimateLocked and addon.gameState.isPlaying then
        print("|cffff0000[Tetris]|r Ultimate is locked during the game!")
        return
    end
    
    local f = addon.ultimateSelectFrame
    if not f then return end
    for _, btn in pairs(f.buttons) do btn:Hide() end
    local ultimates = addon:GetAvailableUltimates()
    for i, ult in ipairs(ultimates) do
        local btn = f.buttons[i]
        if not btn then
            btn = CreateFrame("Button", nil, f, "BackdropTemplate")
            btn:SetSize(310, 65)
            btn:SetBackdrop({bgFile = "Interface\\ChatFrame\\ChatFrameBackground", edgeFile = "Interface\\Tooltips\\UI-Tooltip-Border", tile = true, tileSize = 16, edgeSize = 10, insets = {left=2, right=2, top=2, bottom=2}})
            btn:SetBackdropColor(0.08, 0.08, 0.1, 0.95)
            btn.icon = btn:CreateTexture(nil, "ARTWORK")
            btn.icon:SetSize(50, 50)
            btn.icon:SetPoint("LEFT", 8, 0)
            btn.icon:SetTexCoord(0.08, 0.92, 0.08, 0.92)
            btn.name = btn:CreateFontString(nil, "OVERLAY", "GameFontNormal")
            btn.name:SetPoint("TOPLEFT", btn.icon, "TOPRIGHT", 10, -5)
            btn.desc = btn:CreateFontString(nil, "OVERLAY", "GameFontNormalSmall")
            btn.desc:SetPoint("TOPLEFT", btn.name, "BOTTOMLEFT", 0, -5)
            btn.desc:SetWidth(230)
            btn.desc:SetJustifyH("LEFT")
            btn.locked = btn:CreateFontString(nil, "OVERLAY", "GameFontNormalSmall")
            btn.locked:SetPoint("TOPRIGHT", -10, -10)
            f.buttons[i] = btn
        end
        btn:SetPoint("TOP", f, "TOP", 0, -45 - (i-1)*73)
        btn.icon:SetTexture(ult.icon)
        btn.name:SetText("|cffff6600" .. ult.name .. "|r")
        btn.desc:SetText(ult.description)
        if ult.locked then
            btn.locked:SetText("|cffff0000Lv " .. ult.unlockLevel .. "|r")
            btn.icon:SetDesaturated(true)
            btn:SetBackdropColor(0.05, 0.05, 0.05, 0.9)
            btn:SetScript("OnClick", nil)
        else
            btn.locked:SetText("")
            btn.icon:SetDesaturated(false)
            btn:SetScript("OnClick", function() 
                addon.selectedUltimate = ult 
                addon.db.selectedUltimateName = ult.name
                f:Hide() 
                addon:UpdateUI() 
            end)
        end
        btn:Show()
    end
    f:Show()
end

function addon:UpdateClassBackground()
    if not boardBackground or not addon.selectedClass then return end
    local cd = addon.CLASSES[addon.selectedClass]
    if cd and cd.background then boardBackground:SetTexture(cd.background) boardBackground:SetAlpha(0.12)
    else boardBackground:SetTexture(nil) end
end

function addon:FormatTime(seconds)
    return string.format("%02d:%02d", math.floor(seconds / 60), math.floor(seconds % 60))
end

function addon:PauseGame()
    if addon.gameState.isPlaying and not addon.gameState.isGameOver then
        addon.gameState.isPaused = true
        addon:UpdateUI()
    end
end

function addon:TogglePause()
    if addon.gameState.isPlaying and not addon.gameState.isGameOver then
        addon.gameState.isPaused = not addon.gameState.isPaused
        addon:UpdateUI()
    end
end

function addon:ShowLeaderboard()
    if addon.leaderboardFrame then addon.leaderboardFrame:Show() addon:UpdateLeaderboardDisplay()
    else addon:CreateLeaderboardFrame() if addon.leaderboardFrame then addon.leaderboardFrame:Show() end end
end

function addon:ShowStats()
    print("|cffffd700[WoW Tetris Stats]|r")
    print("Games Played: " .. (addon.db.gamesPlayed or 0))
    if addon.selectedClass then
        local stats = addon:GetClassStats(addon.selectedClass)
        local rank = addon:GetLevelRank(stats.level)
        local cd = addon.CLASSES[addon.selectedClass]
        print(cd.colorCode .. cd.name .. "|r: " .. rank.color .. "Lv " .. stats.level .. " (" .. rank.name .. ")|r")
        print("High Score: |cffffd700" .. addon:FormatNumber(stats.highScore) .. "|r")
    end
end

-- Show ultimate activation flash effect
function addon:ShowUltimateFlash()
    if not addon.mainFrame then return end
    
    -- Create flash overlay if it doesn't exist
    if not addon.ultimateFlash then
        local flash = addon.mainFrame:CreateTexture(nil, "OVERLAY", nil, 7)
        flash:SetAllPoints()
        flash:SetColorTexture(1, 0.8, 0, 0.5)
        flash:SetBlendMode("ADD")
        flash:Hide()
        addon.ultimateFlash = flash
    end
    
    -- Show and fade the flash
    local flash = addon.ultimateFlash
    flash:SetAlpha(0.6)
    flash:Show()
    
    local elapsed = 0
    local ticker
    ticker = C_Timer.NewTicker(0.02, function()
        elapsed = elapsed + 0.02
        local alpha = 0.6 * (1 - elapsed / 0.3)
        if alpha <= 0 then
            flash:Hide()
            ticker:Cancel()
        else
            flash:SetAlpha(alpha)
        end
    end)
end

-- =====================
-- AFFIX SELECTION UI
-- =====================

function addon:ShowAffixSelection()
    if not addon.affixFrame then
        addon:CreateAffixFrame()
    end
    addon:UpdateAffixDisplay()
    addon.affixFrame:Show()
end

function addon:CreateAffixFrame()
    local f = CreateFrame("Frame", "WoWTetrisAffixFrame", UIParent, "BackdropTemplate")
    f:SetSize(420, 580)  -- Taller to fit all affixes
    f:SetPoint("CENTER")
    f:SetBackdrop({
        bgFile = "Interface\\DialogFrame\\UI-DialogBox-Background-Dark",
        edgeFile = "Interface\\DialogFrame\\UI-DialogBox-Gold-Border",
        tile = true, tileSize = 32, edgeSize = 32,
        insets = {left=8, right=8, top=8, bottom=8}
    })
    f:SetFrameStrata("DIALOG")
    f:SetFrameLevel(100)
    
    local title = f:CreateFontString(nil, "OVERLAY", "GameFontNormalHuge")
    title:SetPoint("TOP", 0, -15)
    title:SetText("|cffff6600Affixes|r")
    
    local subtitle = f:CreateFontString(nil, "OVERLAY", "GameFontNormal")
    subtitle:SetPoint("TOP", title, "BOTTOM", 0, -5)
    subtitle:SetText("|cff888888Each affix adds +50% score bonus|r")
    
    local closeBtn = CreateFrame("Button", nil, f, "UIPanelCloseButton")
    closeBtn:SetPoint("TOPRIGHT", -5, -5)
    
    f.checkboxes = {}
    f.affixRows = {}
    
    for i, affix in ipairs(addon.AFFIXES) do
        local row = CreateFrame("Frame", nil, f, "BackdropTemplate")
        row:SetSize(360, 40)
        row:SetPoint("TOP", 0, -55 - (i-1) * 42)
        row:SetBackdrop({
            bgFile = "Interface\\ChatFrame\\ChatFrameBackground",
            edgeFile = "Interface\\Tooltips\\UI-Tooltip-Border",
            tile = true, tileSize = 16, edgeSize = 10,
            insets = {left=2, right=2, top=2, bottom=2}
        })
        row:SetBackdropColor(0.1, 0.05, 0.02, 0.8)
        row:SetBackdropBorderColor(0.5, 0.3, 0.1, 1)
        
        local checkbox = CreateFrame("CheckButton", nil, row, "UICheckButtonTemplate")
        checkbox:SetSize(24, 24)
        checkbox:SetPoint("LEFT", 10, 0)
        checkbox.affixId = affix.id
        checkbox:SetScript("OnClick", function(self)
            addon:ToggleAffix(affix.id, self:GetChecked())
        end)
        
        local name = row:CreateFontString(nil, "OVERLAY", "GameFontNormal")
        name:SetPoint("LEFT", checkbox, "RIGHT", 5, 0)
        name:SetText("|cffff6600" .. affix.name .. "|r")
        row.nameText = name
        
        local desc = row:CreateFontString(nil, "OVERLAY", "GameFontNormalSmall")
        desc:SetPoint("LEFT", name, "RIGHT", 10, 0)
        desc:SetWidth(200)
        desc:SetJustifyH("LEFT")
        desc:SetText("|cff888888" .. affix.description .. "|r")
        
        -- Show tier-based bonus percentage
        local bonusText = "+" .. math.floor(affix.scoreBonus * 100) .. "%"
        local bonusColor = "|cff00ff00"  -- Green for easy
        if affix.tier == 2 then bonusColor = "|cffffff00"  -- Yellow for medium
        elseif affix.tier == 3 then bonusColor = "|cffff6600"  -- Orange for hard
        elseif affix.tier == 4 then bonusColor = "|cffff0000"  -- Red for nightmare
        end
        
        local bonus = row:CreateFontString(nil, "OVERLAY", "GameFontNormalSmall")
        bonus:SetPoint("RIGHT", -10, 0)
        bonus:SetText(bonusColor .. bonusText .. "|r")
        row.bonusText = bonus
        
        -- Lock icon for non-rotation affixes
        local lockIcon = row:CreateTexture(nil, "OVERLAY")
        lockIcon:SetSize(16, 16)
        lockIcon:SetPoint("RIGHT", bonus, "LEFT", -5, 0)
        lockIcon:SetTexture("Interface\\PetBattles\\PetBattle-LockIcon")
        lockIcon:Hide()
        row.lockIcon = lockIcon
        
        f.checkboxes[i] = checkbox
        f.affixRows[i] = row
    end
    
    -- Total bonus display
    f.totalBonus = f:CreateFontString(nil, "OVERLAY", "GameFontNormalLarge")
    f.totalBonus:SetPoint("BOTTOM", 0, 65)
    
    -- Rotation info
    f.rotationInfo = f:CreateFontString(nil, "OVERLAY", "GameFontNormalSmall")
    f.rotationInfo:SetPoint("BOTTOM", 0, 48)
    
    -- Clear all button
    local clearBtn = CreateFrame("Button", nil, f, "UIPanelButtonTemplate")
    clearBtn:SetSize(100, 25)
    clearBtn:SetPoint("BOTTOMLEFT", 20, 15)
    clearBtn:SetText("Clear All")
    clearBtn:SetScript("OnClick", function()
        addon.activeAffixes = {}
        addon:UpdateAffixDisplay()
        addon:UpdateMenuAffixCount()
    end)
    
    addon.affixFrame = f
end

function addon:ToggleAffix(affixId, enabled)
    if enabled then
        -- Add affix
        local found = false
        for _, id in ipairs(addon.activeAffixes) do
            if id == affixId then found = true break end
        end
        if not found then
            table.insert(addon.activeAffixes, affixId)
        end
    else
        -- Remove affix
        for i, id in ipairs(addon.activeAffixes) do
            if id == affixId then
                table.remove(addon.activeAffixes, i)
                break
            end
        end
    end
    addon:UpdateAffixDisplay()
    addon:UpdateMenuAffixCount()
end

function addon:UpdateAffixDisplay()
    if not addon.affixFrame then return end
    
    -- Check which affixes are in the current rotation
    local rotationAffixes = addon.affixRotation and addon.affixRotation.currentAffixes or {}
    
    for i, checkbox in ipairs(addon.affixFrame.checkboxes) do
        local isActive = false
        local isRotation = false
        
        for _, id in ipairs(addon.activeAffixes) do
            if id == checkbox.affixId then
                isActive = true
                break
            end
        end
        
        for _, id in ipairs(rotationAffixes) do
            if id == checkbox.affixId then
                isRotation = true
                break
            end
        end
        
        checkbox:SetChecked(isActive)
        
        -- Get the row
        local row = addon.affixFrame.affixRows and addon.affixFrame.affixRows[i] or checkbox:GetParent()
        
        if isRotation then
            -- Rotation affix - enabled, gold border
            row:SetBackdropBorderColor(1, 0.6, 0, 1)
            row:SetBackdropColor(0.1, 0.05, 0.02, 0.8)
            checkbox:Enable()
            if row.lockIcon then row.lockIcon:Hide() end
            if row.nameText then row.nameText:SetText("|cffff6600" .. (addon.AFFIXES[i] and addon.AFFIXES[i].name or "") .. "|r") end
        else
            -- Non-rotation affix - disabled, gray, locked
            row:SetBackdropBorderColor(0.3, 0.3, 0.3, 1)
            row:SetBackdropColor(0.05, 0.05, 0.05, 0.8)
            checkbox:Disable()
            checkbox:SetChecked(false)
            if row.lockIcon then row.lockIcon:Show() end
            if row.nameText then row.nameText:SetText("|cff666666" .. (addon.AFFIXES[i] and addon.AFFIXES[i].name or "") .. " (Locked)|r") end
            
            -- Remove from active if it was somehow active
            for j, id in ipairs(addon.activeAffixes) do
                if id == checkbox.affixId then
                    table.remove(addon.activeAffixes, j)
                    break
                end
            end
        end
    end
    
    local totalBonus = #addon.activeAffixes * 50
    addon.affixFrame.totalBonus:SetText("|cffffd700Total Score Bonus: |cff00ff00+" .. totalBonus .. "%|r")
    
    -- Show rotation info
    if addon.affixFrame.rotationInfo then
        local numRotation = #rotationAffixes
        addon.affixFrame.rotationInfo:SetText("|cffff6600This Week's Rotation:|r " .. numRotation .. " affixes (gold border)")
    end
end

function addon:UpdateMenuAffixCount()
    if menuFrame and menuFrame.affixCount then
        local count = #addon.activeAffixes
        if count > 0 then
            local bonus = count * 50
            menuFrame.affixCount:SetText("|cffff6600" .. count .. " affix" .. (count > 1 and "es" or "") .. " active (+" .. bonus .. "%)|r")
        else
            menuFrame.affixCount:SetText("")
        end
    end
end

-- =====================
-- QUEST FRAME UI
-- =====================

function addon:ShowQuestFrame()
    if not addon.questFrame then
        addon:CreateQuestFrame()
    end
    addon:UpdateQuestFrame()
    addon.questFrame:Show()
end

function addon:CreateQuestRow(parent, x, y)
    local row = CreateFrame("Frame", nil, parent, "BackdropTemplate")
    row:SetSize(460, 35)
    row:SetPoint("TOPLEFT", x, y)
    row:SetBackdrop({
        bgFile = "Interface\\ChatFrame\\ChatFrameBackground",
        edgeFile = "Interface\\Tooltips\\UI-Tooltip-Border",
        tile = true, tileSize = 16, edgeSize = 8,
        insets = {left=2, right=2, top=2, bottom=2}
    })
    row:SetBackdropColor(0.1, 0.08, 0.05, 0.9)
    row:SetBackdropBorderColor(0.4, 0.35, 0.2, 1)
    
    row.name = row:CreateFontString(nil, "OVERLAY", "GameFontNormal")
    row.name:SetPoint("LEFT", 10, 5)
    row.name:SetWidth(200)
    row.name:SetJustifyH("LEFT")
    
    row.desc = row:CreateFontString(nil, "OVERLAY", "GameFontNormalSmall")
    row.desc:SetPoint("LEFT", 10, -8)
    row.desc:SetWidth(280)
    row.desc:SetJustifyH("LEFT")
    
    row.progress = row:CreateFontString(nil, "OVERLAY", "GameFontNormalSmall")
    row.progress:SetPoint("RIGHT", -80, 0)
    
    row.claimBtn = CreateFrame("Button", nil, row, "UIPanelButtonTemplate")
    row.claimBtn:SetSize(60, 22)
    row.claimBtn:SetPoint("RIGHT", -10, 0)
    row.claimBtn:SetText("Claim")
    
    return row
end

function addon:CreateQuestFrame()
    local f = CreateFrame("Frame", "WoWTetrisQuestFrame", UIParent, "BackdropTemplate")
    f:SetSize(500, 480)
    f:SetPoint("CENTER")
    f:SetBackdrop({
        bgFile = "Interface\\DialogFrame\\UI-DialogBox-Background-Dark",
        edgeFile = "Interface\\DialogFrame\\UI-DialogBox-Gold-Border",
        tile = true, tileSize = 32, edgeSize = 32,
        insets = {left=8, right=8, top=8, bottom=8}
    })
    f:SetFrameStrata("DIALOG")
    f:SetFrameLevel(100)
    
    local title = f:CreateFontString(nil, "OVERLAY", "GameFontNormalHuge")
    title:SetPoint("TOP", 0, -15)
    title:SetText("|cffffff00Daily Quests|r")
    
    local closeBtn = CreateFrame("Button", nil, f, "UIPanelCloseButton")
    closeBtn:SetPoint("TOPRIGHT", -5, -5)
    
    -- Class Quests Section
    local classLabel = f:CreateFontString(nil, "OVERLAY", "GameFontNormal")
    classLabel:SetPoint("TOPLEFT", 20, -45)
    classLabel:SetText("|cff00ff00Class Quests|r - Complete as any class")
    
    f.classQuestRows = {}
    for i = 1, 4 do
        local row = addon:CreateQuestRow(f, 20, -65 - (i-1) * 40)
        f.classQuestRows[i] = row
    end
    
    -- Bonus Quests Section
    local bonusLabel = f:CreateFontString(nil, "OVERLAY", "GameFontNormal")
    bonusLabel:SetPoint("TOPLEFT", 20, -235)
    bonusLabel:SetText("|cffff6600Bonus Quests|r - Class-specific")
    
    f.bonusQuestRows = {}
    for i = 1, 2 do
        local row = addon:CreateQuestRow(f, 20, -255 - (i-1) * 40)
        f.bonusQuestRows[i] = row
    end
    
    -- PvP Quests Section
    local pvpLabel = f:CreateFontString(nil, "OVERLAY", "GameFontNormal")
    pvpLabel:SetPoint("TOPLEFT", 20, -345)
    pvpLabel:SetText("|cffff0000PvP Quests|r")
    
    f.pvpQuestRows = {}
    for i = 1, 3 do
        local row = addon:CreateQuestRow(f, 20, -365 - (i-1) * 40)
        f.pvpQuestRows[i] = row
    end
    
    addon.questFrame = f
end

function addon:UpdateQuestFrame()
    if not addon.questFrame then return end
    local f = addon.questFrame
    
    -- Ensure quests are initialized
    if not addon.questState or not addon.questState.dailyQuests or #addon.questState.dailyQuests == 0 then
        addon:ResetDailyQuests()
    end
    
    -- Update class quests (show first 4)
    for i, row in ipairs(f.classQuestRows) do
        local questState = addon.questState.dailyQuests[i]
        if questState then
            local quest = addon:GetQuestById(questState.questId)
            if quest then
                row.name:SetText(quest.name)
                row.desc:SetText("|cff888888" .. quest.description .. "|r")
                row.progress:SetText(questState.progress .. "/" .. quest.target)
                
                if questState.claimed then
                    row:SetBackdropColor(0.05, 0.15, 0.05, 0.9)
                    row.claimBtn:SetText("Done")
                    row.claimBtn:Disable()
                elseif questState.completed then
                    row:SetBackdropColor(0.15, 0.15, 0.05, 0.9)
                    row.claimBtn:SetText("Claim")
                    row.claimBtn:Enable()
                    row.claimBtn:SetScript("OnClick", function()
                        addon:ClaimQuestReward(questState, addon.selectedClass)
                        addon:UpdateQuestFrame()
                    end)
                else
                    row:SetBackdropColor(0.1, 0.08, 0.05, 0.9)
                    row.claimBtn:SetText(quest.xpReward .. " XP")
                    row.claimBtn:Disable()
                end
                row:Show()
            else
                row:Hide()
            end
        else
            row:Hide()
        end
    end
    
    -- Update bonus quests
    for i, row in ipairs(f.bonusQuestRows) do
        local questState = addon.questState.bonusQuests[i]
        if questState then
            local quest = addon:GetQuestById(questState.questId)
            local classData = addon.CLASSES[questState.classId]
            if quest and classData then
                row.name:SetText(classData.colorCode .. "[" .. classData.name .. "]|r " .. quest.name)
                row.desc:SetText("|cff888888" .. quest.description .. "|r")
                row.progress:SetText(questState.progress .. "/" .. quest.target)
                
                if questState.claimed then
                    row:SetBackdropColor(0.05, 0.15, 0.05, 0.9)
                    row.claimBtn:SetText("Done")
                    row.claimBtn:Disable()
                elseif questState.completed then
                    row:SetBackdropColor(0.15, 0.1, 0.05, 0.9)
                    row.claimBtn:SetText("Claim")
                    row.claimBtn:Enable()
                    row.claimBtn:SetScript("OnClick", function()
                        addon:ClaimQuestReward(questState, questState.classId)
                        addon:UpdateQuestFrame()
                    end)
                else
                    row:SetBackdropColor(0.1, 0.08, 0.05, 0.9)
                    row.claimBtn:SetText(quest.xpReward .. " XP")
                    row.claimBtn:Disable()
                end
                row:Show()
            end
        else
            row:Hide()
        end
    end
    
    -- Update PvP quests
    for i, row in ipairs(f.pvpQuestRows) do
        local questState = addon.questState.pvpQuests[i]
        if questState then
            local quest = addon:GetQuestById(questState.questId)
            if quest then
                row.name:SetText("|cffff0000[PvP]|r " .. quest.name)
                row.desc:SetText("|cff888888" .. quest.description .. "|r")
                row.progress:SetText(questState.progress .. "/" .. quest.target)
                
                if questState.claimed then
                    row:SetBackdropColor(0.05, 0.15, 0.05, 0.9)
                    row.claimBtn:SetText("Done")
                    row.claimBtn:Disable()
                elseif questState.completed then
                    row:SetBackdropColor(0.15, 0.05, 0.05, 0.9)
                    row.claimBtn:SetText("Claim")
                    row.claimBtn:Enable()
                    row.claimBtn:SetScript("OnClick", function()
                        addon:ClaimQuestReward(questState, addon.selectedClass)
                        addon:UpdateQuestFrame()
                    end)
                else
                    row:SetBackdropColor(0.1, 0.05, 0.05, 0.9)
                    row.claimBtn:SetText(quest.xpReward .. " XP")
                    row.claimBtn:Disable()
                end
                row:Show()
            end
        else
            row:Hide()
        end
    end
end

-- Update in-game quest tracker
function addon:UpdateQuestTracker()
    if not gameFrame or not gameFrame.questTrackerRows then return end
    if not addon.questState or not addon.questState.dailyQuests then return end
    
    -- Helper to format time display
    local function formatQuestProgress(quest, questState)
        if quest.type == "time" then
            -- Format as minutes:seconds
            local currentSec = math.floor(questState.progress)
            local targetSec = quest.target
            local currentMin = math.floor(currentSec / 60)
            local currentRemSec = currentSec % 60
            local targetMin = math.floor(targetSec / 60)
            local targetRemSec = targetSec % 60
            return string.format("%d:%02d/%d:%02d", currentMin, currentRemSec, targetMin, targetRemSec)
        else
            return questState.progress .. "/" .. quest.target
        end
    end
    
    local rowIndex = 1
    local maxRows = 6
    
    -- Show active (not claimed) quests
    for i, questState in ipairs(addon.questState.dailyQuests) do
        if rowIndex > maxRows then break end
        if not questState.claimed then
            local quest = addon:GetQuestById(questState.questId)
            if quest then
                local row = gameFrame.questTrackerRows[rowIndex]
                row.questState = questState  -- Store for click handler
                row.name:SetText(quest.name)
                
                local pct = math.min(questState.progress / quest.target, 1)
                if questState.completed then
                    row.progress:SetText("|cff00ff00CLICK TO CLAIM!|r")
                    row.bar:SetColorTexture(0.2, 0.8, 0.2, 1)
                    row.highlight:Show()
                    row:EnableMouse(true)
                else
                    row.progress:SetText(formatQuestProgress(quest, questState))
                    row.bar:SetColorTexture(0.6, 0.6, 0.2, 1)
                    row.highlight:Hide()
                    row:EnableMouse(false)
                end
                row.bar:SetWidth(math.max(1, 138 * pct))
                row:Show()
                rowIndex = rowIndex + 1
            end
        end
    end
    
    -- Also show bonus quests for current class
    for i, questState in ipairs(addon.questState.bonusQuests or {}) do
        if rowIndex > maxRows then break end
        if not questState.claimed and questState.classId == addon.selectedClass then
            local quest = addon:GetQuestById(questState.questId)
            if quest then
                local row = gameFrame.questTrackerRows[rowIndex]
                row.questState = questState  -- Store for click handler
                row.name:SetText("|cffff6600[B]|r " .. quest.name)
                
                local pct = math.min(questState.progress / quest.target, 1)
                if questState.completed then
                    row.progress:SetText("|cff00ff00CLICK TO CLAIM!|r")
                    row.bar:SetColorTexture(0.8, 0.5, 0.2, 1)
                    row.highlight:Show()
                    row:EnableMouse(true)
                else
                    row.progress:SetText(formatQuestProgress(quest, questState))
                    row.bar:SetColorTexture(0.6, 0.4, 0.1, 1)
                    row.highlight:Hide()
                    row:EnableMouse(false)
                end
                row.bar:SetWidth(math.max(1, 138 * pct))
                row:Show()
                rowIndex = rowIndex + 1
            end
        end
    end
    
    -- Hide unused rows
    for i = rowIndex, maxRows do
        local row = gameFrame.questTrackerRows[i]
        row.questState = nil
        row.highlight:Hide()
        row:EnableMouse(false)
        row:Hide()
    end
end

-- =====================
-- SHOP FRAME UI  
-- =====================

function addon:ShowShopFrame()
    if not addon.shopFrame then
        addon:CreateShopFrame()
    end
    addon:UpdateShopFrame()
    addon.shopFrame:Show()
end

function addon:CreateShopFrame()
    local f = CreateFrame("Frame", "WoWTetrisShopFrame", UIParent, "BackdropTemplate")
    f:SetSize(600, 500)
    f:SetPoint("CENTER")
    f:SetBackdrop({
        bgFile = "Interface\\DialogFrame\\UI-DialogBox-Background-Dark",
        edgeFile = "Interface\\DialogFrame\\UI-DialogBox-Gold-Border",
        tile = true, tileSize = 32, edgeSize = 32,
        insets = {left=8, right=8, top=8, bottom=8}
    })
    f:SetFrameStrata("DIALOG")
    f:SetFrameLevel(100)
    
    local title = f:CreateFontString(nil, "OVERLAY", "GameFontNormalHuge")
    title:SetPoint("TOP", 0, -15)
    title:SetText("|cffffd700Shop|r")
    
    local closeBtn = CreateFrame("Button", nil, f, "UIPanelCloseButton")
    closeBtn:SetPoint("TOPRIGHT", -5, -5)
    
    -- Currency display
    f.coinsDisplay = f:CreateFontString(nil, "OVERLAY", "GameFontNormalLarge")
    f.coinsDisplay:SetPoint("TOPLEFT", 25, -45)
    
    f.tokensDisplay = f:CreateFontString(nil, "OVERLAY", "GameFontNormalLarge")
    f.tokensDisplay:SetPoint("TOPLEFT", 200, -45)
    
    -- Tab buttons
    f.tabs = {}
    local tabNames = {"Classes", "Races", "Ultimates", "Sabotages"}
    for i, name in ipairs(tabNames) do
        local tab = CreateFrame("Button", nil, f, "UIPanelButtonTemplate")
        tab:SetSize(130, 25)
        tab:SetPoint("TOPLEFT", 25 + (i-1) * 140, -70)
        tab:SetText(name)
        tab.tabIndex = i
        tab:SetScript("OnClick", function(self)
            addon.shopTab = self.tabIndex
            addon:UpdateShopFrame()
        end)
        f.tabs[i] = tab
    end
    
    -- Content area
    f.content = CreateFrame("Frame", nil, f)
    f.content:SetPoint("TOPLEFT", 20, -105)
    f.content:SetPoint("BOTTOMRIGHT", -20, 50)
    
    -- Item rows (up to 8)
    f.itemRows = {}
    for i = 1, 8 do
        local row = CreateFrame("Frame", nil, f.content, "BackdropTemplate")
        row:SetSize(550, 48)
        row:SetPoint("TOP", 0, -2 - (i-1) * 50)
        row:SetBackdrop({
            bgFile = "Interface\\ChatFrame\\ChatFrameBackground",
            edgeFile = "Interface\\Tooltips\\UI-Tooltip-Border",
            tile = true, tileSize = 16, edgeSize = 10,
            insets = {left=2, right=2, top=2, bottom=2}
        })
        row:SetBackdropColor(0.1, 0.08, 0.05, 0.9)
        row:SetBackdropBorderColor(0.5, 0.4, 0.2, 1)
        
        row.icon = row:CreateTexture(nil, "ARTWORK")
        row.icon:SetSize(40, 40)
        row.icon:SetPoint("LEFT", 8, 0)
        row.icon:SetTexCoord(0.08, 0.92, 0.08, 0.92)
        
        row.name = row:CreateFontString(nil, "OVERLAY", "GameFontNormal")
        row.name:SetPoint("TOPLEFT", row.icon, "TOPRIGHT", 10, -2)
        
        row.desc = row:CreateFontString(nil, "OVERLAY", "GameFontNormalSmall")
        row.desc:SetPoint("TOPLEFT", row.name, "BOTTOMLEFT", 0, -4)
        row.desc:SetWidth(350)
        row.desc:SetJustifyH("LEFT")
        
        row.buyBtn = CreateFrame("Button", nil, row, "UIPanelButtonTemplate")
        row.buyBtn:SetSize(100, 28)
        row.buyBtn:SetPoint("RIGHT", -10, 0)
        
        f.itemRows[i] = row
    end
    
    addon.shopFrame = f
    addon.shopTab = 1
end

function addon:UpdateShopFrame()
    if not addon.shopFrame then return end
    local f = addon.shopFrame
    
    -- Update currency
    local coins = addon:GetCurrency("coins")
    local tokens = addon:GetCurrency("pvpTokens")
    f.coinsDisplay:SetText("|cffffd700Coins:|r " .. addon:FormatNumber(coins))
    f.tokensDisplay:SetText("|cffff4444PvP Tokens:|r " .. addon:FormatNumber(tokens))
    
    -- Highlight active tab
    for i, tab in ipairs(f.tabs) do
        if i == addon.shopTab then
            tab:SetNormalFontObject("GameFontHighlight")
        else
            tab:SetNormalFontObject("GameFontNormal")
        end
    end
    
    -- Hide all rows first
    for _, row in ipairs(f.itemRows) do
        row:Hide()
    end
    
    -- Get items for current tab
    local items = {}
    if addon.shopTab == 1 then  -- Classes
        for _, classKey in ipairs(addon.PREMIUM_CLASSES) do
            local classData = addon.CLASSES[classKey]
            if classData then
                table.insert(items, {
                    id = classKey,
                    name = classData.name,
                    icon = classData.icon,
                    desc = classData.description,
                    cost = classData.cost or 5000,
                    currency = "coins",
                    owned = addon:OwnsItem(classKey, "class"),
                    type = "class"
                })
            end
        end
    elseif addon.shopTab == 2 then  -- Races
        for _, raceKey in ipairs(addon.RACE_ORDER or {}) do
            local raceData = addon.RACES and addon.RACES[raceKey]
            if raceData and raceData.cost > 0 then
                table.insert(items, {
                    id = raceKey,
                    name = raceData.name,
                    icon = raceData.icon,
                    desc = raceData.ability.name .. ": " .. raceData.ability.description,
                    cost = raceData.cost,
                    currency = "coins",
                    owned = addon.IsRaceUnlocked and addon:IsRaceUnlocked(raceKey) or false,
                    type = "race"
                })
            end
        end
    elseif addon.shopTab == 3 then  -- Ultimates (filtered by selected class)
        local selectedClass = addon.selectedClass or "WARRIOR"
        for _, item in ipairs(addon.SHOP_ITEMS.ultimates or {}) do
            -- Show if it's for this class or for ALL classes
            if item.forClass == selectedClass or item.forClass == "ALL" then
                table.insert(items, {
                    id = item.id,
                    name = item.name .. " |cff888888(" .. (item.forClass == "ALL" and "All" or addon.CLASSES[item.forClass].name) .. ")|r",
                    icon = item.icon,
                    desc = item.description,
                    cost = item.cost,
                    currency = item.currency,
                    owned = addon:OwnsItem(item.id, "ultimate"),
                    type = "ultimate"
                })
            end
        end
    elseif addon.shopTab == 4 then  -- Sabotages (filtered by selected class)
        local selectedClass = addon.selectedClass or "WARRIOR"
        for _, item in ipairs(addon.SHOP_ITEMS.sabotage or {}) do
            -- Show if it's for this class or for ALL classes
            if item.forClass == selectedClass or item.forClass == "ALL" then
                table.insert(items, {
                    id = item.id,
                    name = item.name .. " |cff888888(" .. (item.forClass == "ALL" and "All" or addon.CLASSES[item.forClass].name) .. ")|r",
                    icon = item.icon,
                    desc = item.description,
                    cost = item.cost,
                    currency = item.currency,
                    owned = addon:OwnsItem(item.id, "sabotage"),
                    type = "sabotage"
                })
            end
        end
    end
    
    -- Display items
    for i, item in ipairs(items) do
        if i > 8 then break end
        local row = f.itemRows[i]
        row.icon:SetTexture(item.icon)
        row.name:SetText(item.name)
        row.desc:SetText("|cff888888" .. item.desc .. "|r")
        
        if item.owned then
            row.buyBtn:SetText("|cff00ff00Owned|r")
            row.buyBtn:Disable()
            row:SetBackdropColor(0.05, 0.15, 0.05, 0.9)
        else
            local currencyColor = item.currency == "coins" and "|cffffd700" or "|cffff4444"
            row.buyBtn:SetText(currencyColor .. addon:FormatNumber(item.cost) .. "|r")
            row.buyBtn:Enable()
            row:SetBackdropColor(0.1, 0.08, 0.05, 0.9)
            
            local canAfford = addon:GetCurrency(item.currency) >= item.cost
            if canAfford then
                row.buyBtn:SetScript("OnClick", function()
                    addon:PurchaseShopItem(item)
                    addon:UpdateShopFrame()
                    addon:UpdateMenuDisplay()
                end)
            else
                row.buyBtn:Disable()
            end
        end
        
        row:Show()
    end
end

function addon:PurchaseShopItem(item)
    if not addon:SpendCurrency(item.currency, item.cost) then
        print("|cffff0000[Tetris]|r Not enough currency!")
        return
    end
    
    if item.type == "class" then
        addon.shopData.ownedClasses = addon.shopData.ownedClasses or {}
        table.insert(addon.shopData.ownedClasses, item.id)
    elseif item.type == "race" then
        addon.db.unlockedRaces = addon.db.unlockedRaces or {}
        addon.db.unlockedRaces[item.id] = true
    elseif item.type == "ultimate" then
        addon.shopData.ownedUltimates = addon.shopData.ownedUltimates or {}
        table.insert(addon.shopData.ownedUltimates, item.id)
    elseif item.type == "sabotage" then
        addon.shopData.ownedSabotage = addon.shopData.ownedSabotage or {}
        table.insert(addon.shopData.ownedSabotage, item.id)
    end
    
    addon:SaveShopData()
    print("|cff00ff00[Tetris]|r Purchased " .. item.name .. "!")
end

-- =====================
-- TUTORIAL SLIDESHOW
-- =====================

local TUTORIAL_SLIDES = {
    {
        title = "Welcome to WoW Tetris!",
        content = [[|cffffd700Welcome, Champion!|r

WoW Tetris combines classic Tetris gameplay with World of Warcraft RPG elements!

|cff00ff00Key Features:|r
• Choose your Race and Class
• Unlock powerful Ultimate abilities
• Battle other players in PvP
• Complete quests for rewards
• Level up and earn coins

|cffffd700Controls:|r
|cffffffffArrow Keys|r - Move & Rotate
|cffffffffSpace|r - Hard Drop (instant)
|cffffffffC|r - Hold Piece
|cffffffffR|r - Ultimate Ability
|cffffffffB|r - Racial Ability
|cffffffffP / Escape|r - Pause

|cff00ffffLet's get started!|r]]
    },
    {
        title = "Step 1: Choose Your Race",
        content = [[|cffffd700Races|r give you a special |cff00ff00Racial Ability|r!

|cffffd700FREE STARTING RACES:|r

|cff00ff00PvP Races|r (sabotage opponents):
• |cffffffffHuman|r - Enemy loses 10% score
• |cffffffffOrc|r - Add garbage row + instant drop

|cff00ccffPvE Races|r (boost yourself):
• |cffffffffWorgen|r - +50% score for 20 seconds
• |cffffffffTroll|r - Ultimate charges 3x faster

|cffffd700How Racial Abilities Work:|r
• Press |cff00ff00[B]|r to activate
• Has a cooldown (usually 45-60 seconds)
• PvP racials attack your opponent
• PvE racials help you score more

|cffff6600Tip:|r Choose PvP races for battles, PvE races for high scores!]]
    },
    {
        title = "Step 2: Choose Your Class",
        content = [[|cffffd700Classes|r determine your |cff00ff00Ultimate Abilities|r!

|cffffd700FREE CLASSES:|r
Warrior, Paladin, Hunter, Rogue, Priest,
Death Knight, Shaman, Mage, Warlock, Druid

|cffffd700PREMIUM CLASSES (Shop):|r
Monk, Demon Hunter, Evoker

|cff00ff00Each class has unique Ultimates:|r
• |cffffffffWarrior|r - Bladestorm clears rows
• |cffffffffMage|r - Time Warp slows drops
• |cffffffffPriest|r - Guardian Spirit prevents death
• |cffffffffHunter|r - Aimed Shot destroys blocks

|cffffd700Leveling Your Class:|r
• Score = XP earned
• 3,000 XP = 1 Level Up
• Level up to unlock new abilities!
• Each class levels separately]]
    },
    {
        title = "Step 3: Ultimate Abilities",
        content = [[|cffffd700Ultimates|r are powerful abilities that charge as you play!

|cff00ff00How to Use:|r
1. Play and earn score to charge your Ultimate
2. The charge bar fills up on the right panel
3. When |cffffd700READY|r appears, press |cff00ff00[R]|r to activate!

|cffffd700Unlock More Ultimates:|r
• Level 1 - First Ultimate
• Level 15 - Second Ultimate  
• Level 30 - Third Ultimate
• Level 50 - Fourth Ultimate
• Level 100 - Fifth Ultimate

|cff00ff00Example Ultimates:|r
• |cffffffffClear Rows|r - Instantly clear lines
• |cffffffffSlow Time|r - Drops fall slower
• |cffffffffTransform|r - Change current piece
• |cffffffffDouble Score|r - 2x points temporarily

|cffff6600Tip:|r Save your Ultimate for emergencies!]]
    },
    {
        title = "Step 4: PvP Sabotages",
        content = [[|cffffd700Sabotages|r are PvP-only abilities to attack opponents!

|cff00ff00How PvP Works:|r
• Click "Find Battle" on the main menu
• Match with guild/party members
• First to |cffffd70025,000 points|r wins!
• Or survive longest (opponent's board fills)

|cffffd700Sabotage Abilities:|r
• Each class has |cff00ff003 sabotages|r
• Unlocked at levels |cffffd7001, 25, and 50|r
• 15 second cooldown between uses

|cff00ff00Example Sabotages:|r
• |cffff0000Garbage Rows|r - Add junk to enemy
• |cffff0000Instant Drop|r - Force their piece down
• |cffff0000Blackout|r - Hide their board
• |cffff0000Reverse Controls|r - Flip left/right

|cffffd700PvP Rewards:|r
• Win: +50 PvP Tokens, +25 Rating
• Loss: +25 PvP Tokens, -20 Rating]]
    },
    {
        title = "Step 5: Quests & Rewards",
        content = [[|cffffd700Daily Quests|r give bonus Coins and XP!

|cff00ff00Quest Types:|r
• |cffffffffDaily Quests|r - General objectives
• |cffffffffBonus Quests|r - Class-specific
• |cffffffffPvP Quests|r - Battle challenges

|cffffd700How to Complete:|r
• Quests track automatically as you play
• When complete, |cff00ff00CLICK TO CLAIM|r appears
• Claim rewards from the left panel IN-GAME!
• No need to return to main menu

|cffffd700Rewards:|r
• |cffffd700Coins|r - Buy items in the Shop
• |cff00ff00XP|r - Level up your class
• |cffff00ffPvP Tokens|r - From PvP quests

|cff00ff00Time Bonuses:|r
• +20% score every 15 seconds survived
• +20% score every 30 seconds (speed bonus)
• Game speeds up every 30 seconds!]]
    },
    {
        title = "Step 6: The Shop",
        content = [[|cffffd700The Shop|r lets you unlock new content!

|cff00ff00Currencies:|r
• |cffffd700Coins|r - Earned from leveling up
• |cffff00ffPvP Tokens|r - Earned from PvP battles

|cffffd700What You Can Buy:|r

|cffffffffRaces|r (1000-2500 coins)
• Night Elf, Dwarf, Gnome, Undead...
• Each has a unique racial ability

|cffffffffPremium Classes|r (2000-3000 coins)
• Monk, Demon Hunter, Evoker
• Unique ultimates and sabotages

|cffffffffExtra Abilities|r (PvP Tokens)
• Additional Ultimates for any class
• Extra Sabotages for PvP

|cffff6600Affix Bonus:|r
Play with Affixes active to earn
|cff00ff00+125% bonus coins|r per affix when leveling!

|cffffd700Good luck, Champion!|r]]
    },
}

function addon:ShowTutorial(isFirstTime)
    if addon.tutorialFrame then
        addon.tutorialFrame:Show()
        addon:SetTutorialSlide(1)
        return
    end
    
    local f = CreateFrame("Frame", "WoWTetrisTutorial", UIParent, "BackdropTemplate")
    f:SetSize(500, 450)
    f:SetPoint("CENTER")
    f:SetBackdrop({
        bgFile = "Interface\\DialogFrame\\UI-DialogBox-Background-Dark",
        edgeFile = "Interface\\DialogFrame\\UI-DialogBox-Gold-Border",
        tile = true, tileSize = 32, edgeSize = 32,
        insets = {left=8, right=8, top=8, bottom=8}
    })
    f:SetFrameStrata("DIALOG")
    f:SetFrameLevel(100)
    f:EnableMouse(true)
    f:SetMovable(true)
    f:RegisterForDrag("LeftButton")
    f:SetScript("OnDragStart", f.StartMoving)
    f:SetScript("OnDragStop", f.StopMovingOrSizing)
    
    -- Close button
    local closeBtn = CreateFrame("Button", nil, f, "UIPanelCloseButton")
    closeBtn:SetPoint("TOPRIGHT", -5, -5)
    closeBtn:SetScript("OnClick", function() 
        f:Hide() 
        -- Mark tutorial as seen
        addon.db.tutorialSeen = true
    end)
    
    -- Title
    f.title = f:CreateFontString(nil, "OVERLAY", "GameFontNormalHuge")
    f.title:SetPoint("TOP", 0, -20)
    f.title:SetText("|cff00ffffTutorial|r")
    
    -- Tab buttons at top
    f.tabs = {}
    local tabWidth = 65
    local tabStartX = -((#TUTORIAL_SLIDES * tabWidth) / 2) + (tabWidth / 2)
    for i = 1, #TUTORIAL_SLIDES do
        local tab = CreateFrame("Button", nil, f, "BackdropTemplate")
        tab:SetSize(60, 25)
        tab:SetPoint("TOP", tabStartX + (i-1) * tabWidth, -45)
        tab:SetBackdrop({bgFile = "Interface\\ChatFrame\\ChatFrameBackground", edgeFile = "Interface\\Tooltips\\UI-Tooltip-Border", tile = true, tileSize = 16, edgeSize = 12, insets = {left=2, right=2, top=2, bottom=2}})
        tab:SetBackdropColor(0.1, 0.1, 0.1, 1)
        tab:SetBackdropBorderColor(0.4, 0.4, 0.4, 1)
        
        tab.text = tab:CreateFontString(nil, "OVERLAY", "GameFontNormalSmall")
        tab.text:SetPoint("CENTER")
        tab.text:SetText(i)
        
        tab:SetScript("OnClick", function()
            addon:SetTutorialSlide(i)
        end)
        
        tab:SetScript("OnEnter", function(self)
            GameTooltip:SetOwner(self, "ANCHOR_TOP")
            GameTooltip:SetText(TUTORIAL_SLIDES[i].title)
            GameTooltip:Show()
        end)
        tab:SetScript("OnLeave", function() GameTooltip:Hide() end)
        
        f.tabs[i] = tab
    end
    
    -- Content area
    f.content = f:CreateFontString(nil, "OVERLAY", "GameFontNormal")
    f.content:SetPoint("TOPLEFT", 25, -80)
    f.content:SetPoint("BOTTOMRIGHT", -25, 60)
    f.content:SetJustifyH("LEFT")
    f.content:SetJustifyV("TOP")
    f.content:SetSpacing(2)
    
    -- Slide indicator
    f.slideIndicator = f:CreateFontString(nil, "OVERLAY", "GameFontNormalSmall")
    f.slideIndicator:SetPoint("BOTTOM", 0, 40)
    
    -- Navigation buttons
    local prevBtn = CreateFrame("Button", nil, f, "UIPanelButtonTemplate")
    prevBtn:SetSize(80, 25)
    prevBtn:SetPoint("BOTTOMLEFT", 20, 15)
    prevBtn:SetText("< Back")
    prevBtn:SetScript("OnClick", function()
        if f.currentSlide > 1 then
            addon:SetTutorialSlide(f.currentSlide - 1)
        end
    end)
    f.prevBtn = prevBtn
    
    local nextBtn = CreateFrame("Button", nil, f, "UIPanelButtonTemplate")
    nextBtn:SetSize(80, 25)
    nextBtn:SetPoint("BOTTOMRIGHT", -20, 15)
    nextBtn:SetText("Next >")
    nextBtn:SetScript("OnClick", function()
        if f.currentSlide < #TUTORIAL_SLIDES then
            addon:SetTutorialSlide(f.currentSlide + 1)
        else
            f:Hide()
            addon.db.tutorialSeen = true
        end
    end)
    f.nextBtn = nextBtn
    
    -- Skip button (only shows on first time)
    local skipBtn = CreateFrame("Button", nil, f, "UIPanelButtonTemplate")
    skipBtn:SetSize(80, 25)
    skipBtn:SetPoint("BOTTOM", 0, 15)
    skipBtn:SetText("Skip All")
    skipBtn:SetScript("OnClick", function()
        f:Hide()
        addon.db.tutorialSeen = true
    end)
    f.skipBtn = skipBtn
    if not isFirstTime then
        skipBtn:Hide()
    end
    
    f.currentSlide = 1
    addon.tutorialFrame = f
    
    addon:SetTutorialSlide(1)
    f:Show()
end

function addon:SetTutorialSlide(slideNum)
    local f = addon.tutorialFrame
    if not f then return end
    
    f.currentSlide = slideNum
    local slide = TUTORIAL_SLIDES[slideNum]
    
    f.title:SetText("|cff00ffff" .. slide.title .. "|r")
    f.content:SetText(slide.content)
    f.slideIndicator:SetText("|cff888888Slide " .. slideNum .. " of " .. #TUTORIAL_SLIDES .. "|r")
    
    -- Update tab highlights
    for i, tab in ipairs(f.tabs) do
        if i == slideNum then
            tab:SetBackdropColor(0.2, 0.5, 0.2, 1)
            tab:SetBackdropBorderColor(0, 1, 0, 1)
            tab.text:SetText("|cff00ff00" .. i .. "|r")
        elseif i < slideNum then
            tab:SetBackdropColor(0.15, 0.15, 0.2, 1)
            tab:SetBackdropBorderColor(0.3, 0.6, 0.3, 1)
            tab.text:SetText("|cff88ff88" .. i .. "|r")
        else
            tab:SetBackdropColor(0.1, 0.1, 0.1, 1)
            tab:SetBackdropBorderColor(0.4, 0.4, 0.4, 1)
            tab.text:SetText(i)
        end
    end
    
    -- Update navigation buttons
    if slideNum == 1 then
        f.prevBtn:Disable()
    else
        f.prevBtn:Enable()
    end
    
    if slideNum == #TUTORIAL_SLIDES then
        f.nextBtn:SetText("Finish!")
    else
        f.nextBtn:SetText("Next >")
    end
end

-- Check and show tutorial on first load
function addon:CheckFirstTimeTutorial()
    if not addon.db.tutorialSeen then
        addon:ShowTutorial(true)
    end
end

-- =====================
-- OPTIONS FRAME
-- =====================

local KEYBIND_LABELS = {
    moveLeft = "Move Left",
    moveRight = "Move Right",
    softDrop = "Soft Drop",
    hardDrop = "Hard Drop",
    rotateClockwise = "Rotate CW",
    rotateCounterClockwise = "Rotate CCW",
    hold = "Hold Piece",
    pause = "Pause",
    ultimate = "Ultimate",
    racialAbility = "Racial",
    pvpAbility = "PvP Sabotage",
}

local KEYBIND_ORDER = {
    "moveLeft", "moveRight", "softDrop", "hardDrop",
    "rotateClockwise", "rotateCounterClockwise", "hold",
    "pause", "ultimate", "racialAbility", "pvpAbility"
}

function addon:ShowOptionsFrame()
    if addon.optionsFrame then
        addon:UpdateOptionsFrame()
        addon.optionsFrame:Show()
        return
    end
    
    local f = CreateFrame("Frame", "WoWTetrisOptions", UIParent, "BackdropTemplate")
    f:SetSize(400, 450)
    f:SetPoint("CENTER")
    f:SetBackdrop({
        bgFile = "Interface\\DialogFrame\\UI-DialogBox-Background-Dark",
        edgeFile = "Interface\\DialogFrame\\UI-DialogBox-Gold-Border",
        tile = true, tileSize = 32, edgeSize = 32,
        insets = {left=8, right=8, top=8, bottom=8}
    })
    f:SetFrameStrata("DIALOG")
    f:SetFrameLevel(100)
    f:EnableMouse(true)
    f:SetMovable(true)
    f:RegisterForDrag("LeftButton")
    f:SetScript("OnDragStart", f.StartMoving)
    f:SetScript("OnDragStop", f.StopMovingOrSizing)
    
    -- Close button
    local closeBtn = CreateFrame("Button", nil, f, "UIPanelCloseButton")
    closeBtn:SetPoint("TOPRIGHT", -5, -5)
    closeBtn:SetScript("OnClick", function() f:Hide() end)
    
    -- Title
    local title = f:CreateFontString(nil, "OVERLAY", "GameFontNormalHuge")
    title:SetPoint("TOP", 0, -20)
    title:SetText("|cff888888Options|r")
    
    -- Keybinds section title
    local keybindsTitle = f:CreateFontString(nil, "OVERLAY", "GameFontNormalLarge")
    keybindsTitle:SetPoint("TOPLEFT", 25, -55)
    keybindsTitle:SetText("|cffffd700Keybinds|r")
    
    local hint = f:CreateFontString(nil, "OVERLAY", "GameFontNormalSmall")
    hint:SetPoint("TOPLEFT", keybindsTitle, "BOTTOMLEFT", 0, -2)
    hint:SetText("|cff888888Click a button, then press a key to rebind|r")
    
    -- Keybind rows
    f.keybindButtons = {}
    local startY = -95
    local rowHeight = 28
    
    for i, bindKey in ipairs(KEYBIND_ORDER) do
        local label = f:CreateFontString(nil, "OVERLAY", "GameFontNormal")
        label:SetPoint("TOPLEFT", 30, startY - (i-1) * rowHeight)
        label:SetWidth(140)
        label:SetJustifyH("LEFT")
        label:SetText(KEYBIND_LABELS[bindKey])
        
        local btn = CreateFrame("Button", nil, f, "BackdropTemplate")
        btn:SetSize(120, 22)
        btn:SetPoint("LEFT", label, "RIGHT", 10, 0)
        btn:SetBackdrop({
            bgFile = "Interface\\ChatFrame\\ChatFrameBackground",
            edgeFile = "Interface\\Tooltips\\UI-Tooltip-Border",
            tile = true, tileSize = 16, edgeSize = 12,
            insets = {left=2, right=2, top=2, bottom=2}
        })
        btn:SetBackdropColor(0.1, 0.1, 0.1, 1)
        btn:SetBackdropBorderColor(0.4, 0.4, 0.4, 1)
        
        btn.text = btn:CreateFontString(nil, "OVERLAY", "GameFontHighlight")
        btn.text:SetPoint("CENTER")
        btn.text:SetText(addon.db.keybinds[bindKey] or "NONE")
        
        btn.bindKey = bindKey
        btn.isBinding = false
        
        btn:SetScript("OnClick", function(self)
            -- Start listening for key
            if addon.currentBindingButton then
                addon.currentBindingButton:SetBackdropBorderColor(0.4, 0.4, 0.4, 1)
                addon.currentBindingButton.text:SetText(addon.db.keybinds[addon.currentBindingButton.bindKey] or "NONE")
                addon.currentBindingButton.isBinding = false
            end
            
            self.isBinding = true
            self:SetBackdropBorderColor(0, 1, 0, 1)
            self.text:SetText("|cff00ff00Press a key...|r")
            addon.currentBindingButton = self
            f:EnableKeyboard(true)
        end)
        
        f.keybindButtons[bindKey] = btn
    end
    
    -- Key capture
    f:SetScript("OnKeyDown", function(self, key)
        if not addon.currentBindingButton then return end
        
        -- Escape cancels binding
        if key == "ESCAPE" then
            addon.currentBindingButton:SetBackdropBorderColor(0.4, 0.4, 0.4, 1)
            addon.currentBindingButton.text:SetText(addon.db.keybinds[addon.currentBindingButton.bindKey] or "NONE")
            addon.currentBindingButton.isBinding = false
            addon.currentBindingButton = nil
            self:EnableKeyboard(false)
            return
        end
        
        -- Set the new keybind
        local bindKey = addon.currentBindingButton.bindKey
        addon.db.keybinds[bindKey] = key
        addon.currentBindingButton.text:SetText(key)
        addon.currentBindingButton:SetBackdropBorderColor(0.4, 0.4, 0.4, 1)
        addon.currentBindingButton.isBinding = false
        addon.currentBindingButton = nil
        self:EnableKeyboard(false)
        
        -- Reinitialize keybinds
        if addon.InitializeKeybinds then
            addon:InitializeKeybinds()
        end
        
        print("|cff00ff00[Tetris]|r " .. KEYBIND_LABELS[bindKey] .. " bound to: " .. key)
    end)
    
    -- Reset to defaults button
    local resetBtn = CreateFrame("Button", nil, f, "UIPanelButtonTemplate")
    resetBtn:SetSize(150, 25)
    resetBtn:SetPoint("BOTTOM", 0, 20)
    resetBtn:SetText("Reset to Defaults")
    resetBtn:SetScript("OnClick", function()
        addon.db.keybinds = {
            moveLeft = "LEFT",
            moveRight = "RIGHT",
            softDrop = "DOWN",
            hardDrop = "SPACE",
            rotateClockwise = "UP",
            rotateCounterClockwise = "LCTRL",
            hold = "C",
            pause = "P",
            ultimate = "R",
            pvpAbility = "V",
            racialAbility = "B",
        }
        addon:UpdateOptionsFrame()
        if addon.InitializeKeybinds then
            addon:InitializeKeybinds()
        end
        print("|cff00ff00[Tetris]|r Keybinds reset to defaults!")
    end)
    
    addon.optionsFrame = f
    addon:UpdateOptionsFrame()
    f:Show()
end

function addon:UpdateOptionsFrame()
    if not addon.optionsFrame or not addon.optionsFrame.keybindButtons then return end
    
    for bindKey, btn in pairs(addon.optionsFrame.keybindButtons) do
        btn.text:SetText(addon.db.keybinds[bindKey] or "NONE")
    end
end
