-- =============================================================
--  Plate-o-Matic (Quest Progress Fix Edition)
--  - FIX: Quest-tekst (x/y eller %) vises nå konsekvent
--  - Scanner alle tooltip-linjer for tall, ikke bare spesifikke typer
--  - Alle tidligere funksjoner (Threat, Arrows, Visuals) er med
-- =============================================================

local ADDON_NAME = "Plate-o-Matic"
local addonTable = {}

-- =============================================================
-- 1. SKINS & CONFIG
-- =============================================================

local SKINS = {
    { name = "Base (Orange)",      texture = "Interface\\AddOns\\pom\\skins\\base.tga", ignoreColor = true },
    { name = "Yellow",             texture = "Interface\\AddOns\\pom\\skins\\yellow.tga", ignoreColor = true },
    { name = "Cool Blue",          texture = "Interface\\AddOns\\pom\\skins\\coolblue.tga", ignoreColor = true },
    { name = "Gray",               texture = "Interface\\AddOns\\pom\\skins\\gray.tga", ignoreColor = true },
    { name = "Statusbar 1",        texture = "Interface\\AddOns\\pom\\skins\\statusbar1.tga", ignoreColor = true },
    { name = "MiniBoss",           texture = "Interface\\AddOns\\pom\\skins\\miniboss1.tga", ignoreColor = true },
    { name = "Status: Hostile",    texture = "Interface\\AddOns\\pom\\skins\\robui_statusbar_hostile_256x32.tga", ignoreColor = true },
    { name = "Status: Friendly",   texture = "Interface\\AddOns\\pom\\skins\\robui_statusbar_friendly_256x32.tga", ignoreColor = true },
    { name = "Status: Neutral",    texture = "Interface\\AddOns\\pom\\skins\\robui_statusbar_neutral_256x32.tga", ignoreColor = true },
    { name = "Class: Warrior",     texture = "Interface\\AddOns\\pom\\skins\\robui_statusbar_warrior_256x32.tga", ignoreColor = true },
    { name = "Class: Paladin",     texture = "Interface\\AddOns\\pom\\skins\\robui_statusbar_paladin_256x32.tga", ignoreColor = true },
    { name = "Class: Hunter",      texture = "Interface\\AddOns\\pom\\skins\\robui_statusbar_hunter_256x32.tga", ignoreColor = true },
    { name = "Class: Rogue",       texture = "Interface\\AddOns\\pom\\skins\\robui_statusbar_rogue_256x32.tga", ignoreColor = true },
    { name = "Class: Priest",      texture = "Interface\\AddOns\\pom\\skins\\robui_statusbar_priest_256x32.tga", ignoreColor = true },
    { name = "Class: Death Knight",texture = "Interface\\AddOns\\pom\\skins\\robui_statusbar_deathknight_256x32.tga", ignoreColor = true },
    { name = "Class: Shaman",      texture = "Interface\\AddOns\\pom\\skins\\robui_statusbar_shaman_256x32.tga", ignoreColor = true },
    { name = "Class: Mage",        texture = "Interface\\AddOns\\pom\\skins\\robui_statusbar_mage_256x32.tga", ignoreColor = true },
    { name = "Class: Warlock",     texture = "Interface\\AddOns\\pom\\skins\\robui_statusbar_warlock_256x32.tga", ignoreColor = true },
    { name = "Class: Monk",        texture = "Interface\\AddOns\\pom\\skins\\robui_statusbar_monk_256x32.tga", ignoreColor = true },
    { name = "Class: Druid",       texture = "Interface\\AddOns\\pom\\skins\\robui_statusbar_druid_256x32.tga", ignoreColor = true },
    { name = "Class: Demon Hunter",texture = "Interface\\AddOns\\pom\\skins\\robui_statusbar_demonhunter_256x32.tga", ignoreColor = true },
    { name = "Class: Evoker",      texture = "Interface\\AddOns\\pom\\skins\\robui_statusbar_evoker_256x32.tga", ignoreColor = true },
    { name = "Flat (Plater)",      texture = "Interface\\Buttons\\WHITE8x8",          ignoreColor = false },
    { name = "Smooth",             texture = "Interface\\TargetingFrame\\UI-StatusBar", ignoreColor = false },
    { name = "Blizzard Raid",      texture = "Interface\\RaidFrame\\Raid-Bar-Hp-Fill",  ignoreColor = false },
}

local DEFAULTS = {
    colors = {
        normal    = { r=0.8, g=0.8, b=0.8 },
        plusOne   = { r=1.0, g=0.5, b=0.0 },
        highlevel = { r=0.8, g=0.0, b=1.0 },
        caster    = { r=1.0, g=0.4, b=0.8 },
        melee     = { r=0.0, g=0.6, b=1.0 },
        threatHigh= { r=1.0, g=0.0, b=0.0 }, 
    },
    skins = {
        normal    = 23, 
        plusOne   = 23,
        highlevel = 23,
        caster    = 23,
        melee     = 23,
    },
    heights = {
        normal    = 16,
        plusOne   = 18,
        highlevel = 20,
        caster    = 18,
        melee     = 18,
    },
    fontPath    = "Fonts\\FRIZQT__.TTF",
    fontSize    = 10,
    fontOutline = "OUTLINE",
    hideClassIcon = true,
    
    alwaysTargetGlow = true,  
    targetScale      = 1.15,
    showTargetArrow  = true,
    arrowPointingOut = false, 
    flashAggro       = true,
    showThreatPerc   = true,
    showQuestIcon    = true,
    showQuestProg    = true, 
    nameAnchor       = "LEFT", 
}

local function IsSafeUnit(unit)
    return unit and UnitCanAttack("player", unit)
end

local function GetGradientColor(perc, r1, g1, b1, r2, g2, b2)
    if perc > 1 then perc = 1 end
    if perc < 0 then perc = 0 end
    local r = r1 + (r2 - r1) * perc
    local g = g1 + (g2 - g1) * perc
    local b = b1 + (b2 - b1) * perc
    return r, g, b
end

-- =============================================================
-- 2. MIXIN SYSTEM
-- =============================================================

addonTable.Mixin = {}

function addonTable.Mixin:Init(frame)
    self.frame = frame
    self.healthBar = frame.healthBar or (frame.HealthBarsContainer and frame.HealthBarsContainer.healthBar)
    if not self.healthBar then return end

    -- 1. BAKGRUNN
    if not self.healthBar.pomBG then
        local bg = self.healthBar:CreateTexture(nil, "BACKGROUND")
        bg:SetAllPoints(self.healthBar)
        bg:SetTexture("Interface\\Buttons\\WHITE8x8")
        bg:SetVertexColor(0.25, 0.25, 0.25, 0.85) 
        self.healthBar.pomBG = bg
    end

    -- 2. BORDERS
    if not self.healthBar.pomBorders then
        self.healthBar.pomBorders = {}
        for i=1, 4 do
            local t = self.healthBar:CreateTexture(nil, "OVERLAY") 
            t:SetColorTexture(0, 0, 0, 1) 
            table.insert(self.healthBar.pomBorders, t)
        end
    end
    
    -- 3. TEKST RAMME
    if not self.healthBar.pomTextFrame then
        local tf = CreateFrame("Frame", nil, self.healthBar)
        tf:SetAllPoints(self.healthBar)
        tf:SetFrameLevel(self.healthBar:GetFrameLevel() + 20) 
        self.healthBar.pomTextFrame = tf
        
        -- Navn
        local fsName = tf:CreateFontString(nil, "OVERLAY")
        fsName:SetFont(DEFAULTS.fontPath, DEFAULTS.fontSize, DEFAULTS.fontOutline)
        fsName:SetPoint("LEFT", tf, "LEFT", 4, 0)
        fsName:SetPoint("RIGHT", tf, "RIGHT", -40, 0) 
        fsName:SetJustifyH("LEFT")
        fsName:SetWordWrap(false)
        self.healthBar.pomName = fsName

        -- Helse
        local fsHealth = tf:CreateFontString(nil, "OVERLAY")
        fsHealth:SetFont(DEFAULTS.fontPath, DEFAULTS.fontSize, DEFAULTS.fontOutline)
        fsHealth:SetPoint("RIGHT", tf, "RIGHT", -4, 0)
        fsHealth:SetJustifyH("RIGHT")
        self.healthBar.pomHealth = fsHealth
    end

    -- Threat Percent (Under)
    if not self.healthBar.pomThreatText then
        local ft = self.healthBar.pomTextFrame:CreateFontString(nil, "OVERLAY")
        ft:SetFont(DEFAULTS.fontPath, DEFAULTS.fontSize - 1, "OUTLINE")
        ft:SetPoint("TOP", self.healthBar, "BOTTOM", 0, -2)
        self.healthBar.pomThreatText = ft
    end

    -- === QUEST ICON & TEXT ===
    if not self.healthBar.pomQuestIcon then
        local qi = self.healthBar:CreateTexture(nil, "OVERLAY")
        qi:SetTexture("Interface\\TargetingFrame\\PortraitQuestBadge") 
        qi:SetSize(20, 20)
        qi:SetPoint("RIGHT", self.healthBar, "LEFT", -5, 5) 
        qi:Hide()
        self.healthBar.pomQuestIcon = qi
        
        -- Quest Progress Text (Gull tekst under ikonet)
        local qt = self.healthBar.pomTextFrame:CreateFontString(nil, "OVERLAY")
        qt:SetFont(DEFAULTS.fontPath, DEFAULTS.fontSize - 2, "OUTLINE")
        qt:SetPoint("TOP", qi, "BOTTOM", 0, 2)
        qt:SetTextColor(1, 0.82, 0) 
        self.healthBar.pomQuestText = qt
    end

    -- 4. TARGET MARKERS
    if not self.healthBar.pomArrows then
        self.healthBar.pomArrows = {}
        
        local arrowL = self.frame:CreateTexture(nil, "OVERLAY")
        arrowL:SetTexture("Interface\\Buttons\\UI-MicroStream-Yellow") 
        arrowL:SetSize(24, 24)
        arrowL:Hide()
        self.healthBar.pomArrows.left = arrowL

        local arrowR = self.frame:CreateTexture(nil, "OVERLAY")
        arrowR:SetTexture("Interface\\Buttons\\UI-MicroStream-Yellow") 
        arrowR:SetSize(24, 24)
        arrowR:SetTexCoord(1, 0, 0, 1) 
        arrowR:Hide()
        self.healthBar.pomArrows.right = arrowR
    end

    -- 5. FLASH
    if not self.healthBar.pomWarningGlow then
        local glow = self.healthBar:CreateTexture(nil, "OVERLAY", nil, 6)
        glow:SetAllPoints(self.healthBar)
        glow:SetTexture("Interface\\Buttons\\WHITE8x8")
        glow:SetVertexColor(1, 1, 0, 0.6) 
        glow:SetBlendMode("ADD")
        glow:Hide()
        self.healthBar.pomWarningGlow = glow

        local ag = glow:CreateAnimationGroup()
        ag:SetLooping("BOUNCE")
        local a1 = ag:CreateAnimation("Alpha")
        a1:SetFromAlpha(0); a1:SetToAlpha(1); a1:SetDuration(0.4); a1:SetSmoothing("IN_OUT")
        self.healthBar.pomWarningAnim = ag
    end

    self.initialized = true
end

function addonTable.Mixin:UpdateVisuals()
    if not self.healthBar then return end
    local db = PlateOMaticDB

    local tf = self.healthBar.pomTextFrame
    local fsName = self.healthBar.pomName
    if tf and fsName then
        fsName:ClearAllPoints()
        local pos = db.nameAnchor or "LEFT"
        
        if pos == "TOP" then
            fsName:SetPoint("BOTTOM", tf, "TOP", 0, 2)
            fsName:SetJustifyH("CENTER")
            fsName:SetPoint("LEFT", tf, "LEFT", -50, 0)
            fsName:SetPoint("RIGHT", tf, "RIGHT", 50, 0)
        elseif pos == "LEFT" then
            fsName:SetPoint("LEFT", tf, "LEFT", 4, 0)
            fsName:SetPoint("RIGHT", tf, "RIGHT", -40, 0)
            fsName:SetJustifyH("LEFT")
        elseif pos == "CENTER" then
            fsName:SetPoint("CENTER", tf, "CENTER", 0, 1)
            fsName:SetPoint("LEFT", tf, "LEFT", 4, 0)
            fsName:SetPoint("RIGHT", tf, "RIGHT", -40, 0)
            fsName:SetJustifyH("CENTER")
        end
    end

    if self.healthBar.pomName then
        self.healthBar.pomName:Show()
        self.healthBar.pomName:SetFont(db.fontPath, db.fontSize, db.fontOutline)
        self.healthBar.pomName:SetTextColor(1, 1, 1)
    end

    if self.healthBar.pomHealth then
        self.healthBar.pomHealth:Show()
        self.healthBar.pomHealth:SetFont(db.fontPath, db.fontSize, db.fontOutline)
        self.healthBar.pomHealth:SetTextColor(1, 1, 1)
    end

    if self.healthBar.pomThreatText then
        self.healthBar.pomThreatText:SetFont(db.fontPath, db.fontSize - 1, db.fontOutline)
    end
    
    if self.healthBar.pomQuestText then
        self.healthBar.pomQuestText:SetFont(db.fontPath, db.fontSize - 2, db.fontOutline)
    end
end

-- === QUEST INFO LOGIC (WIDE SCAN) ===
function addonTable.Mixin:UpdateQuest()
    if not self.healthBar.pomQuestIcon then return end
    
    local showIcon = PlateOMaticDB.showQuestIcon
    local showProg = PlateOMaticDB.showQuestProg
    
    if not showIcon then 
        self.healthBar.pomQuestIcon:Hide()
        if self.healthBar.pomQuestText then self.healthBar.pomQuestText:Hide() end
        return 
    end

    local unit = self.frame.unit
    local isQuest = false
    local progressText = ""
    
    if C_TooltipInfo and C_TooltipInfo.GetUnit then
        local data = C_TooltipInfo.GetUnit(unit)
        if data then
            for _, line in ipairs(data.lines) do
                -- Type 17 = Quest Title, 18 = Quest Objective
                -- Vi markerer isQuest = true hvis vi ser en av disse
                if line.type == 17 or line.type == 18 then isQuest = true end
                
                -- Vi sjekker ALLE linjer for "x/y" eller "%", uavhengig av linjetype
                -- Dette er sikrere fordi Blizzard iblant putter fremgang i "leftText" på en vanlig linje
                if showProg and line.leftText then
                    -- 1. Sjekk for "5/10" format
                    local current, total = string.match(line.leftText, "(%d+)/(%d+)")
                    if current and total then
                        progressText = current .. "/" .. total
                    else
                        -- 2. Sjekk for "54%" format
                        local perc = string.match(line.leftText, "(%d+%%)")
                        if perc then
                            progressText = perc
                        end
                    end
                end
            end
        end
    end

    if isQuest then
        self.healthBar.pomQuestIcon:Show()
        if showProg and progressText ~= "" then
            self.healthBar.pomQuestText:SetText(progressText)
            self.healthBar.pomQuestText:Show()
        else
            self.healthBar.pomQuestText:Hide()
        end
    else
        self.healthBar.pomQuestIcon:Hide()
        self.healthBar.pomQuestText:Hide()
    end
end

function addonTable.Mixin:UpdateName()
    if not self.healthBar or not self.healthBar.pomName then return end
    local name = UnitName(self.frame.unit)
    self.healthBar.pomName:SetText(name or "")
end

function addonTable.Mixin:UpdateHealth()
    if not self.healthBar or not self.healthBar.pomHealth then return end
    local unit = self.frame.unit
    
    if not IsSafeUnit(unit) then
        self.healthBar.pomHealth:SetText("")
        return
    end

    if UnitIsDeadOrGhost(unit) then
        self.healthBar.pomHealth:SetText("0%")
        return
    end

    local percentValue = 0
    if UnitHealthPercent then 
        local scaling = (CurveConstants and CurveConstants.ScaleTo100) or 1
        percentValue = UnitHealthPercent(unit, true, scaling)
    else
        percentValue = UnitHealth(unit, true) / UnitHealthMax(unit) * 100
    end
    self.healthBar.pomHealth:SetText(string.format("%d%%", percentValue))
end

function addonTable.Mixin:UpdateState()
    if not self.healthBar then return end
    local db = PlateOMaticDB
    local unit = self.frame.unit

    -- === TARGET LOGIKK ===
    local isTarget = UnitIsUnit("target", unit)
    
    if isTarget then
        self.frame:SetScale(db.targetScale or 1.15)
        if db.showTargetArrow and self.healthBar.pomArrows then 
            local arrL = self.healthBar.pomArrows.left
            local arrR = self.healthBar.pomArrows.right
            arrL:ClearAllPoints(); arrR:ClearAllPoints()

            if db.arrowPointingOut then
                arrL:SetPoint("RIGHT", self.healthBar, "LEFT", -4, 0); arrL:SetRotation(1.57) 
                arrR:SetPoint("LEFT", self.healthBar, "RIGHT", 4, 0); arrR:SetRotation(-1.57)
            else
                arrL:SetPoint("RIGHT", self.healthBar, "LEFT", -4, 0); arrL:SetRotation(-1.57) 
                arrR:SetPoint("LEFT", self.healthBar, "RIGHT", 4, 0); arrR:SetRotation(1.57) 
            end
            arrL:Show(); arrR:Show()
        end
    else
        self.frame:SetScale(1)
        if self.healthBar.pomArrows then 
            self.healthBar.pomArrows.left:Hide(); self.healthBar.pomArrows.right:Hide()
        end
    end

    -- === SKIN ===
    local lvl = UnitLevel(unit)
    local pl = UnitLevel("player")
    local cls = UnitClassification(unit)
    local typeKey = "normal"

    if lvl == -1 or (lvl and pl and lvl >= pl + 2) then typeKey = "highlevel"
    elseif lvl and pl and lvl > pl then typeKey = "plusOne"
    elseif cls == "elite" then
        if UnitPowerType(unit) == 0 then typeKey = "caster" else typeKey = "melee" end
    end

    local skinID = db.skins[typeKey] or 23 
    local currentSkin = SKINS[skinID] or SKINS[23]

    self.healthBar:SetStatusBarTexture(currentSkin.texture)
    self.healthBar:SetHeight(db.heights[typeKey])

    -- === THREAT SCALING ===
    local isTanking, status, threatPct = UnitDetailedThreatSituation("player", unit)
    local finalR, finalG, finalB = db.colors[typeKey].r, db.colors[typeKey].g, db.colors[typeKey].b
    
    if currentSkin.ignoreColor then finalR, finalG, finalB = 1, 1, 1 end

    local role = GetSpecializationRole(GetSpecialization() or 1)
    
    if threatPct then
        if role == "TANK" then
            if threatPct < 100 then
                local dangerPct = threatPct / 100
                finalR, finalG, finalB = GetGradientColor(dangerPct, 1, 0, 1, finalR, finalG, finalB)
            end
        else
            if threatPct >= 100 then
                finalR, finalG, finalB = db.colors.threatHigh.r, db.colors.threatHigh.g, db.colors.threatHigh.b
            elseif threatPct >= 70 then
                local warnPct = (threatPct - 70) / 29 
                finalR, finalG, finalB = GetGradientColor(warnPct, 1, 1, 0, 1, 0.5, 0)
            end
        end
    end

    self.healthBar:SetStatusBarColor(finalR, finalG, finalB)

    -- === THREAT TEXT ===
    if db.showThreatPerc and self.healthBar.pomThreatText then
        if threatPct and threatPct > 0 then
            self.healthBar.pomThreatText:SetText(string.format("%.0f%%", threatPct))
            self.healthBar.pomThreatText:Show()
            if threatPct >= 100 then self.healthBar.pomThreatText:SetTextColor(1, 0.2, 0.2)
            elseif threatPct >= 70 then self.healthBar.pomThreatText:SetTextColor(1, 1, 0)
            else self.healthBar.pomThreatText:SetTextColor(0.6, 0.6, 0.6) end
        else
            self.healthBar.pomThreatText:SetText(""); self.healthBar.pomThreatText:Hide()
        end
    elseif self.healthBar.pomThreatText then
        self.healthBar.pomThreatText:Hide()
    end

    -- === FLASH ===
    if db.flashAggro and self.healthBar.pomWarningGlow then
        local shouldFlash = false
        if role == "TANK" then
            local inCombat = UnitAffectingCombat(unit)
            if inCombat and (not status or status < 3) then shouldFlash = true end
        else
            if status and status >= 1 then shouldFlash = true end
        end

        if shouldFlash then
            self.healthBar.pomWarningGlow:Show()
            if not self.healthBar.pomWarningAnim:IsPlaying() then self.healthBar.pomWarningAnim:Play() end
        else
            self.healthBar.pomWarningGlow:Hide(); self.healthBar.pomWarningAnim:Stop()
        end
    end

    -- === BORDER ===
    if self.healthBar.pomBorders then
        local size = 2 
        local top, bottom, left, right = unpack(self.healthBar.pomBorders)
        top:ClearAllPoints(); top:SetPoint("BOTTOMLEFT", self.healthBar, "TOPLEFT", -size, 0); top:SetPoint("BOTTOMRIGHT", self.healthBar, "TOPRIGHT", size, 0); top:SetHeight(size)
        bottom:ClearAllPoints(); bottom:SetPoint("TOPLEFT", self.healthBar, "BOTTOMLEFT", -size, 0); bottom:SetPoint("TOPRIGHT", self.healthBar, "BOTTOMRIGHT", size, 0); bottom:SetHeight(size)
        left:ClearAllPoints(); left:SetPoint("TOPRIGHT", self.healthBar, "TOPLEFT", 0, size); left:SetPoint("BOTTOMRIGHT", self.healthBar, "BOTTOMLEFT", 0, -size); left:SetWidth(size)
        right:ClearAllPoints(); right:SetPoint("TOPLEFT", self.healthBar, "TOPRIGHT", 0, size); right:SetPoint("BOTTOMLEFT", self.healthBar, "BOTTOMRIGHT", 0, -size); right:SetWidth(size)
    end
end

-- =============================================================
-- 4. HOOKS
-- =============================================================

local function LockAlpha(texture)
    if not texture then return end
    texture:SetAlpha(0); texture:Hide()
    if not texture.pomLocked then
        hooksecurefunc(texture, "SetAlpha", function(self, alpha) if alpha and alpha > 0 then self:SetAlpha(0) end end)
        texture.pomLocked = true
    end
end

local function KillBlizzard(frame)
    if not frame then return end
    local hb = frame.healthBar or (frame.HealthBarsContainer and frame.HealthBarsContainer.healthBar)
    if hb and hb.border then LockAlpha(hb.border) end
    if frame.HealthBarsContainer and frame.HealthBarsContainer.border then LockAlpha(frame.HealthBarsContainer.border) end
    if frame.selectionHighlight then LockAlpha(frame.selectionHighlight) end
    if frame.CastBarBorder then LockAlpha(frame.CastBarBorder) end
    if frame.CastBarShield then LockAlpha(frame.CastBarShield) end
    if frame.name then frame.name:Hide() end
    if frame.level then frame.level:Hide() end 
    if hb and hb.text then hb.text:Hide() end
    if PlateOMaticDB.hideClassIcon and frame.classificationIndicator then frame.classificationIndicator:Hide() end
end

local function Apply(frame)
    if not frame or frame:IsForbidden() then return end
    if not frame.unit or not string.find(frame.unit, "nameplate") then return end
    if not frame.POM_Mixin then
        frame.POM_Mixin = {}
        for k,v in pairs(addonTable.Mixin) do frame.POM_Mixin[k] = v end
        frame.POM_Mixin:Init(frame)
    end
    KillBlizzard(frame)
    frame.POM_Mixin:UpdateVisuals()
    frame.POM_Mixin:UpdateQuest()
    frame.POM_Mixin:UpdateName()
    frame.POM_Mixin:UpdateHealth()
    if IsSafeUnit(frame.unit) then frame.POM_Mixin:UpdateState() end
end

hooksecurefunc("CompactUnitFrame_UpdateAll", Apply)
hooksecurefunc("CompactUnitFrame_UpdateHealth", Apply)
hooksecurefunc("CompactUnitFrame_UpdateName", Apply)
hooksecurefunc("CompactUnitFrame_UpdateStatusText", Apply)
hooksecurefunc("CompactUnitFrame_UpdateHealthBorder", function(frame) if frame and not frame:IsForbidden() and frame.unit and string.find(frame.unit, "nameplate") then KillBlizzard(frame) end end)
hooksecurefunc("CompactUnitFrame_UpdateSelectionHighlight", function(frame) if frame and not frame:IsForbidden() and frame.unit and string.find(frame.unit, "nameplate") then if frame.selectionHighlight then LockAlpha(frame.selectionHighlight) end end end)
local eventFrame = CreateFrame("Frame"); eventFrame:RegisterEvent("PLAYER_TARGET_CHANGED"); eventFrame:SetScript("OnEvent", function() for _, plate in pairs(C_NamePlate.GetNamePlates()) do if plate.UnitFrame then Apply(plate.UnitFrame) end end end)

-- =============================================================
-- 5. SETTINGS FRAME
-- =============================================================

local function ToggleSkinList(parent, typeKey, updateTextFunc)
    if addonTable.SkinListFrame then
        if addonTable.SkinListFrame.activeKey == typeKey and addonTable.SkinListFrame:IsShown() then
            addonTable.SkinListFrame:Hide()
            return
        end
    end
    if not addonTable.SkinListFrame then
        local f = CreateFrame("Frame", nil, UIParent, "BackdropTemplate")
        f:SetSize(250, #SKINS * 25 + 10)
        f:SetFrameStrata("DIALOG")
        local bg = f:CreateTexture(nil, "BACKGROUND"); bg:SetAllPoints(); bg:SetColorTexture(0, 0, 0, 0.95)
        local border = f:CreateTexture(nil, "BORDER"); border:SetPoint("TOPLEFT", -1, 1); border:SetPoint("BOTTOMRIGHT", 1, -1); border:SetColorTexture(0.5, 0.5, 0.5, 1)
        addonTable.SkinListFrame = f; addonTable.SkinListFrame.buttons = {}
    end
    local f = addonTable.SkinListFrame
    f:ClearAllPoints(); f:SetPoint("TOPLEFT", parent, "TOPRIGHT", 5, 0); f.activeKey = typeKey; f:Show()
    for i, skin in ipairs(SKINS) do
        local btn = f.buttons[i]
        if not btn then
            btn = CreateFrame("Button", nil, f)
            btn:SetSize(240, 24); btn:SetPoint("TOP", f, "TOP", 0, -5 - ((i-1)*25))
            local txt = btn:CreateFontString(nil, "OVERLAY", "GameFontNormal"); txt:SetPoint("LEFT", 5, 0); btn.text = txt
            local hl = btn:CreateTexture(nil, "HIGHLIGHT"); hl:SetAllPoints(); hl:SetColorTexture(1, 1, 1, 0.2)
            f.buttons[i] = btn
        end
        btn.text:SetText(skin.name)
        if skin.ignoreColor then btn.text:SetTextColor(1, 0.8, 0) else btn.text:SetTextColor(1, 1, 1) end
        btn:SetScript("OnClick", function()
            PlateOMaticDB.skins[f.activeKey] = i; print("Set " .. f.activeKey .. " to use skin: " .. skin.name); updateTextFunc(); f:Hide()
            for _, plate in pairs(C_NamePlate.GetNamePlates()) do if plate.UnitFrame then Apply(plate.UnitFrame) end end
        end)
    end
end

local function CreateSettingsRow(parent, label, typeKey, yOffset)
    local row = CreateFrame("Frame", nil, parent); row:SetSize(380, 30); row:SetPoint("TOPLEFT", parent, "TOPLEFT", 10, yOffset)
    local text = row:CreateFontString(nil, "OVERLAY", "GameFontHighlight"); text:SetPoint("LEFT", 0, 0); text:SetText(label)
    local colBtn = CreateFrame("Button", nil, row); colBtn:SetSize(20, 20); colBtn:SetPoint("RIGHT", row, "RIGHT", -120, 0)
    local colBg = colBtn:CreateTexture(nil, "BACKGROUND"); colBg:SetAllPoints(); colBg:SetColorTexture(0.2,0.2,0.2,1)
    local colSwatch = colBtn:CreateTexture(nil, "OVERLAY"); colSwatch:SetPoint("TOPLEFT",1,-1); colSwatch:SetPoint("BOTTOMRIGHT",-1,1)
    colBtn.Update = function() local c = PlateOMaticDB.colors[typeKey] or PlateOMaticDB.colors.threatHigh; colSwatch:SetColorTexture(c.r, c.g, c.b) end; colBtn.Update()
    colBtn:SetScript("OnClick", function() local c = PlateOMaticDB.colors[typeKey]; if not c then return end; ColorPickerFrame:SetupColorPickerAndShow({ r = c.r, g = c.g, b = c.b, swatchFunc = function() local r, g, b = ColorPickerFrame:GetColorRGB(); c.r, c.g, c.b = r, g, b; colSwatch:SetColorTexture(r, g, b) end }) end)
    local skinBtn = CreateFrame("Button", nil, row, "UIPanelButtonTemplate"); skinBtn:SetSize(110, 20); skinBtn:SetPoint("RIGHT", row, "RIGHT", 0, 0)
    skinBtn.UpdateText = function() local skinID = PlateOMaticDB.skins[typeKey] or 23; local s = SKINS[skinID] or SKINS[23]; skinBtn:SetText(s.name) end; skinBtn.UpdateText()
    skinBtn:SetScript("OnClick", function() ToggleSkinList(skinBtn, typeKey, skinBtn.UpdateText) end)
end

local function CreateStandaloneMenu()
    if addonTable.MenuFrame then return end
    local f = CreateFrame("Frame", "POM_MenuFrame", UIParent, "BasicFrameTemplateWithInset")
    f:SetSize(400, 650); f:SetPoint("CENTER")
    f:SetMovable(true); f:EnableMouse(true); f:RegisterForDrag("LeftButton")
    f:SetScript("OnDragStart", f.StartMoving); f:SetScript("OnDragStop", f.StopMovingOrSizing); f:Hide()
    if f.TitleText then f.TitleText:SetText("Plate-o-Matic Settings") end
    
    local t1 = f:CreateFontString(nil, "OVERLAY", "GameFontNormalSmall"); t1:SetPoint("TOPLEFT", 15, -35); t1:SetText("Unit Type")
    local t2 = f:CreateFontString(nil, "OVERLAY", "GameFontNormalSmall"); t2:SetPoint("TOPRIGHT", -135, -35); t2:SetText("Color")
    local t3 = f:CreateFontString(nil, "OVERLAY", "GameFontNormalSmall"); t3:SetPoint("TOPRIGHT", -40, -35); t3:SetText("Skin")

    local startY = -60; local gap = -35
    CreateSettingsRow(f, "Normal", "normal", startY)
    CreateSettingsRow(f, "High Lvl (+2)", "highlevel", startY + gap*1)
    CreateSettingsRow(f, "Player Lvl +1", "plusOne", startY + gap*2)
    CreateSettingsRow(f, "Elite Caster", "caster", startY + gap*3)
    CreateSettingsRow(f, "Elite Melee", "melee", startY + gap*4)
    
    local threatRow = CreateFrame("Frame", nil, f); threatRow:SetSize(380, 30); threatRow:SetPoint("TOPLEFT", f, "TOPLEFT", 10, startY + gap*5)
    local tt = threatRow:CreateFontString(nil, "OVERLAY", "GameFontHighlight"); tt:SetPoint("LEFT"); tt:SetText("Aggro (High Threat)")
    local tb = CreateFrame("Button", nil, threatRow); tb:SetSize(20,20); tb:SetPoint("RIGHT", threatRow, "RIGHT", -120, 0)
    local tbg = tb:CreateTexture(nil,"BACKGROUND"); tbg:SetAllPoints(); tbg:SetColorTexture(0.2,0.2,0.2,1)
    local tsw = tb:CreateTexture(nil,"OVERLAY"); tsw:SetPoint("TOPLEFT",1,-1); tsw:SetPoint("BOTTOMRIGHT",-1,1)
    tb.Update = function() local c = PlateOMaticDB.colors.threatHigh; tsw:SetColorTexture(c.r,c.g,c.b) end; tb.Update()
    tb:SetScript("OnClick", function() local c = PlateOMaticDB.colors.threatHigh; ColorPickerFrame:SetupColorPickerAndShow({r=c.r,g=c.g,b=c.b,swatchFunc=function() local r,g,b=ColorPickerFrame:GetColorRGB(); c.r,c.g,c.b=r,g,b; tsw:SetColorTexture(r,g,b) end}) end)

    local cbY = startY + gap*6 - 20
    local cb = CreateFrame("CheckButton", nil, f, "UICheckButtonTemplate"); cb:SetPoint("TOPLEFT", f, "TOPLEFT", 15, cbY); cb.text:SetText("Hide Elite Icon"); cb:SetChecked(PlateOMaticDB.hideClassIcon)
    cb:SetScript("OnClick", function(self) PlateOMaticDB.hideClassIcon = self:GetChecked(); for _, plate in pairs(C_NamePlate.GetNamePlates()) do if plate.UnitFrame then Apply(plate.UnitFrame) end end end)

    local cb2 = CreateFrame("CheckButton", nil, f, "UICheckButtonTemplate"); cb2:SetPoint("TOPLEFT", f, "TOPLEFT", 15, cbY - 30); cb2.text:SetText("Thick Black Border (Always)"); cb2:SetChecked(PlateOMaticDB.alwaysTargetGlow)
    cb2:SetScript("OnClick", function(self) PlateOMaticDB.alwaysTargetGlow = self:GetChecked(); for _, plate in pairs(C_NamePlate.GetNamePlates()) do if plate.UnitFrame then Apply(plate.UnitFrame) end end end)

    local cb3 = CreateFrame("CheckButton", nil, f, "UICheckButtonTemplate"); cb3:SetPoint("TOPLEFT", f, "TOPLEFT", 15, cbY - 60); cb3.text:SetText("Flash Yellow (Threat Warning)"); cb3:SetChecked(PlateOMaticDB.flashAggro)
    cb3:SetScript("OnClick", function(self) PlateOMaticDB.flashAggro = self:GetChecked() end)

    local cb4 = CreateFrame("CheckButton", nil, f, "UICheckButtonTemplate"); cb4:SetPoint("TOPLEFT", f, "TOPLEFT", 15, cbY - 90); cb4.text:SetText("Show Target Arrows"); cb4:SetChecked(PlateOMaticDB.showTargetArrow)
    cb4:SetScript("OnClick", function(self) PlateOMaticDB.showTargetArrow = self:GetChecked(); for _, plate in pairs(C_NamePlate.GetNamePlates()) do if plate.UnitFrame then Apply(plate.UnitFrame) end end end)

    local cb5 = CreateFrame("CheckButton", nil, f, "UICheckButtonTemplate"); cb5:SetPoint("TOPLEFT", f, "TOPLEFT", 15, cbY - 120); cb5.text:SetText("Show Threat %"); cb5:SetChecked(PlateOMaticDB.showThreatPerc)
    cb5:SetScript("OnClick", function(self) PlateOMaticDB.showThreatPerc = self:GetChecked(); for _, plate in pairs(C_NamePlate.GetNamePlates()) do if plate.UnitFrame then Apply(plate.UnitFrame) end end end)

    local cb6 = CreateFrame("CheckButton", nil, f, "UICheckButtonTemplate"); cb6:SetPoint("TOPLEFT", f, "TOPLEFT", 15, cbY - 150); cb6.text:SetText("Invert Arrows (Point Outward)"); cb6:SetChecked(PlateOMaticDB.arrowPointingOut)
    cb6:SetScript("OnClick", function(self) PlateOMaticDB.arrowPointingOut = self:GetChecked(); for _, plate in pairs(C_NamePlate.GetNamePlates()) do if plate.UnitFrame then Apply(plate.UnitFrame) end end end)

    local cb7 = CreateFrame("CheckButton", nil, f, "UICheckButtonTemplate"); cb7:SetPoint("TOPLEFT", f, "TOPLEFT", 15, cbY - 180); cb7.text:SetText("Show Quest Icon"); cb7.text:SetTextColor(1, 0.8, 0); cb7:SetChecked(PlateOMaticDB.showQuestIcon)
    cb7:SetScript("OnClick", function(self) PlateOMaticDB.showQuestIcon = self:GetChecked(); for _, plate in pairs(C_NamePlate.GetNamePlates()) do if plate.UnitFrame then Apply(plate.UnitFrame) end end end)

    local cb8 = CreateFrame("CheckButton", nil, f, "UICheckButtonTemplate"); cb8:SetPoint("TOPLEFT", f, "TOPLEFT", 200, cbY - 180); cb8.text:SetText("Show Quest Progress"); cb8.text:SetTextColor(1, 0.8, 0); cb8:SetChecked(PlateOMaticDB.showQuestProg)
    cb8:SetScript("OnClick", function(self) PlateOMaticDB.showQuestProg = self:GetChecked(); for _, plate in pairs(C_NamePlate.GetNamePlates()) do if plate.UnitFrame then Apply(plate.UnitFrame) end end end)

    local posBtn = CreateFrame("Button", nil, f, "UIPanelButtonTemplate")
    posBtn:SetSize(160, 24); posBtn:SetPoint("TOPLEFT", f, "TOPLEFT", 15, cbY - 220)
    posBtn:SetText("Name Pos: " .. (PlateOMaticDB.nameAnchor or "LEFT"))
    posBtn:SetScript("OnClick", function()
        local p = PlateOMaticDB.nameAnchor
        if p == "TOP" then PlateOMaticDB.nameAnchor = "LEFT"
        elseif p == "LEFT" then PlateOMaticDB.nameAnchor = "CENTER"
        elseif p == "CENTER" then PlateOMaticDB.nameAnchor = "TOP" 
        else PlateOMaticDB.nameAnchor = "LEFT" end
        posBtn:SetText("Name Pos: " .. PlateOMaticDB.nameAnchor)
        for _, plate in pairs(C_NamePlate.GetNamePlates()) do if plate.UnitFrame then Apply(plate.UnitFrame) end end
    end)

    local slider = CreateFrame("Slider", "POM_ScaleSlider", f, "OptionsSliderTemplate")
    slider:SetPoint("TOPLEFT", f, "TOPLEFT", 20, cbY - 270); slider:SetWidth(200)
    slider:SetMinMaxValues(1.0, 1.5); slider:SetValue(PlateOMaticDB.targetScale or 1.15); slider:SetValueStep(0.05); slider:SetObeyStepOnDrag(true)
    _G[slider:GetName() .. "Low"]:SetText("1.0"); _G[slider:GetName() .. "High"]:SetText("1.5"); _G[slider:GetName() .. "Text"]:SetText("Target Scale: " .. (PlateOMaticDB.targetScale or 1.15))
    slider:SetScript("OnValueChanged", function(self, value)
        value = math.floor(value * 100 + 0.5) / 100; PlateOMaticDB.targetScale = value
        _G[slider:GetName() .. "Text"]:SetText("Target Scale: " .. value)
        for _, plate in pairs(C_NamePlate.GetNamePlates()) do if plate.UnitFrame then Apply(plate.UnitFrame) end end
    end)

    local resetBtn = CreateFrame("Button", nil, f, "UIPanelButtonTemplate")
    resetBtn:SetSize(120, 24); resetBtn:SetPoint("TOP", slider, "BOTTOM", 0, -20)
    resetBtn:SetText("Reset Settings")
    resetBtn:SetScript("OnClick", function() PlateOMaticDB = nil; C_UI.Reload() end)

    addonTable.MenuFrame = f
end

-- =============================================================
-- 6. INIT
-- =============================================================

local login = CreateFrame("Frame"); login:RegisterEvent("PLAYER_LOGIN"); login:RegisterEvent("NAME_PLATE_UNIT_ADDED")
login:SetScript("OnEvent", function(self, event, unit)
    if event == "PLAYER_LOGIN" then
        if C_CVar then C_CVar.SetCVar("nameplateShowAll", "1"); C_CVar.SetCVar("nameplateShowEnemies", "1") end
        PlateOMaticDB = PlateOMaticDB or DEFAULTS
        if not PlateOMaticDB.skins then PlateOMaticDB.skins = DEFAULTS.skins end
        if PlateOMaticDB.targetScale == nil then PlateOMaticDB.targetScale = 1.15 end
        if PlateOMaticDB.alwaysTargetGlow == nil then PlateOMaticDB.alwaysTargetGlow = true end
        if PlateOMaticDB.showTargetArrow == nil then PlateOMaticDB.showTargetArrow = true end
        if PlateOMaticDB.flashAggro == nil then PlateOMaticDB.flashAggro = true end
        if PlateOMaticDB.showThreatPerc == nil then PlateOMaticDB.showThreatPerc = true end
        if PlateOMaticDB.showQuestIcon == nil then PlateOMaticDB.showQuestIcon = true end
        if PlateOMaticDB.showQuestProg == nil then PlateOMaticDB.showQuestProg = true end
        if PlateOMaticDB.nameAnchor == nil then PlateOMaticDB.nameAnchor = "LEFT" end
        CreateStandaloneMenu()
        print("|cFF00FF00Plate-o-Matic:|r Loaded.")
    elseif event == "NAME_PLATE_UNIT_ADDED" then
        local plate = C_NamePlate.GetNamePlateForUnit(unit)
        if plate and plate.UnitFrame then Apply(plate.UnitFrame) end
    end
end)

SLASH_PLATEOMATIC1 = "/pom"
SlashCmdList["PLATEOMATIC"] = function(msg)
    if msg == "reset" then PlateOMaticDB = DEFAULTS; print("Resetting..."); C_UI.Reload() else if addonTable.MenuFrame then if addonTable.MenuFrame:IsShown() then addonTable.MenuFrame:Hide() else addonTable.MenuFrame:Show() end end end
end