local ADDON_NAME, ns = ...

-- =========================================================
-- Plate-o-Matic (pom.lua)
-- Main entry file
-- =========================================================

local DB_VERSION = 3

-- =========================================================
-- Skins
-- =========================================================
ns.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 },
}

-- =========================================================
-- Defaults (SavedVariables)
-- =========================================================
ns.DEFAULTS = {
    dbVersion = DB_VERSION,

    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 },
        threatMedium   = { r=1.0, g=1.0, b=0.0 },
        threatLow      = { r=0.5, g=0.5, b=0.5 },

        threatTankSafe = { r=0.2, g=0.8, b=0.2 },
        threatOffTank  = { r=0.6, g=0.2, b=1.0 },

        groupAggro     = { r=0.2, g=0.7, b=1.0, a=1.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,
    flashDuration = 0,

    showThreatPerc = true,
    showQuestIcon  = true,
    showQuestProg  = true,

    colorBarByThreat     = true,

    -- OLD global option REMOVED
    -- keepBaseColorsAlways = false,

    -- NEW: Solo-only override (DEFAULT OFF)
    useBaseColorsSolo = false,

    tankModeEnabled = true,
    checkOffTank    = true,

    groupAggroColorEnabled = false,

    nameAnchor = "LEFT",
    globalScale = 1.0,

    buffSize   = 20,
    debuffSize = 20,

    targetBorderColor = { r=1.0, g=0.82, b=0.0, a=1.0 },
}

-- =========================================================
-- Locals
-- =========================================================
local U      = ns.util
local Mixins = ns.mixins
local Config = ns.config

-- =========================================================
-- Apply styling to one plate
-- =========================================================
local function Apply(frame)
    if not frame or frame:IsForbidden() then return end
    if not U.IsNameplateUnit(frame.unit) then return end

    if not frame.POM_Mixin then
        frame.POM_Mixin = Mixins:New(frame, ns.SKINS)
    end

    U.KillBlizzard(frame, PlateOMaticDB)

    frame.POM_Mixin:UpdateVisuals()
    frame.POM_Mixin:UpdateQuest()
    frame.POM_Mixin:UpdateName()
    frame.POM_Mixin:UpdateHealth()

    if U.IsSafeUnit(frame.unit) then
        frame.POM_Mixin:UpdateState()
    end
end

-- =========================================================
-- DB init
-- =========================================================
local function InitDB()
    PlateOMaticDB = PlateOMaticDB or {}
    U.CopyDefaults(ns.DEFAULTS, PlateOMaticDB)
    _G.PlateOMaticDB = PlateOMaticDB

    if PlateOMaticDB.useBaseColorsSolo == nil then
        PlateOMaticDB.useBaseColorsSolo = false
    end

    PlateOMaticDB.dbVersion = DB_VERSION
end

-- =========================================================
-- Menu
-- =========================================================
local function CreateMenu()
    if ns._menu then
        ns._menu:SetShown(not ns._menu:IsShown())
        return
    end

    local f = CreateFrame("Frame", "POM_MenuFrame", UIParent, "BasicFrameTemplateWithInset")
    f:SetSize(1020, 760)
    f:SetPoint("CENTER")
    f:SetMovable(true)
    f:EnableMouse(true)
    f:RegisterForDrag("LeftButton")
    f:SetScript("OnDragStart", f.StartMoving)
    f:SetScript("OnDragStop", f.StopMovingOrSizing)

    if f.TitleText then
        f.TitleText:SetText("Plate-o-Matic")
    end

    local function applyAll()
        U.RefreshAllPlates(Apply)
        if ns.preview and ns.preview.frame and ns.preview.frame.Refresh then
            ns.preview.frame:Refresh()
        end
    end

    Config:Build(f, ns.SKINS, applyAll)

    ns._menu = f
    f:Show()
end

-- =========================================================
-- Hooks
-- =========================================================
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 U.IsNameplateUnit(frame.unit) then
        U.KillBlizzard(frame, PlateOMaticDB)
    end
end)

hooksecurefunc("CompactUnitFrame_UpdateSelectionHighlight", function(frame)
    if frame and not frame:IsForbidden() and U.IsNameplateUnit(frame.unit) then
        if frame.selectionHighlight then
            U.LockAlpha(frame.selectionHighlight)
        end
    end
end)

hooksecurefunc("CompactUnitFrame_UpdateAuras", function(frame)
    if not frame or frame:IsForbidden() or not U.IsNameplateUnit(frame.unit) then return end

    local bScale = (PlateOMaticDB.buffSize or 20) / 18
    local dScale = (PlateOMaticDB.debuffSize or 20) / 18

    if frame.BuffFrame then frame.BuffFrame:SetScale(bScale) end
    if frame.DebuffFrame then frame.DebuffFrame:SetScale(dScale) end
end)

-- =========================================================
-- Events
-- =========================================================
local ev = CreateFrame("Frame")
ev:RegisterEvent("PLAYER_LOGIN")
ev:RegisterEvent("NAME_PLATE_UNIT_ADDED")
ev:RegisterEvent("PLAYER_TARGET_CHANGED")
ev:RegisterEvent("GROUP_ROSTER_UPDATE")
ev:RegisterEvent("PLAYER_ROLES_ASSIGNED")
ev:RegisterEvent("PLAYER_ENTERING_WORLD")

ev:SetScript("OnEvent", function(_, event, unit)
    if event == "PLAYER_LOGIN" then
        InitDB()
        if ns and ns.UpdateTankCache then
            ns:UpdateTankCache()
        end
        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

    else
        if ns and ns.UpdateTankCache then
            ns:UpdateTankCache()
        end
        U.RefreshAllPlates(Apply)
    end
end)

-- =========================================================
-- Slash command
-- =========================================================
SLASH_PLATEOMATIC1 = "/pom"
SlashCmdList["PLATEOMATIC"] = function(msg)
    if msg == "reset" then
        PlateOMaticDB = nil
        _G.PlateOMaticDB = nil
        C_UI.Reload()
        return
    end
    CreateMenu()
end
