local _, _ns = ...
local AC = _G.ArenaCore
if not AC then return end

-- =============================================================================
-- Core/HonorCapReminder.lua - Alerts when honor points reach a threshold
-- ported from Shade addon because capping honor is sad
-- =============================================================================

local HCR = {}
AC.HonorCapReminder = HCR

local alertFrame = nil
local eventFrame = nil
local HONOR_CURRENCY_ID = 1792
local sessionDismissed = false

------------------------------------------------------------------------
-- config helpers
------------------------------------------------------------------------
local function GetDB()
    if not AC.DB or not AC.DB.profile then
        return { enabled = true, threshold = 12000, posX = 0, posY = 0 }
    end
    AC.DB.profile.honorCapReminder = AC.DB.profile.honorCapReminder or {}
    local db = AC.DB.profile.honorCapReminder
    if db.enabled == nil then db.enabled = true end
    if db.threshold == nil then db.threshold = 12000 end
    if db.posX == nil then db.posX = 0 end
    if db.posY == nil then db.posY = 0 end
    return db
end

------------------------------------------------------------------------
-- gradient text helper (A24CFF -> FFB522)
------------------------------------------------------------------------
local function CreateGradientText(parent, text, fontSize)
    local gradient = {
        {r = 0.635, g = 0.298, b = 1.000},  -- A24CFF
        {r = 0.690, g = 0.357, b = 0.875},  -- B05BDF
        {r = 0.745, g = 0.416, b = 0.753},  -- BE6AC0
        {r = 0.800, g = 0.475, b = 0.627},  -- CC79A0
        {r = 0.855, g = 0.533, b = 0.506},  -- DA8881
        {r = 0.910, g = 0.592, b = 0.380},  -- E89761
        {r = 0.965, g = 0.651, b = 0.259},  -- F6A642
        {r = 1.000, g = 0.710, b = 0.133},  -- FFB522
    }

    local container = CreateFrame("Frame", nil, parent)
    local chars = {}
    local totalChars = #text

    for i = 1, totalChars do
        local char = text:sub(i, i)
        local fs = container:CreateFontString(nil, "OVERLAY")
        fs:SetFont(AC.FONT_PATH or "Fonts\\FRIZQT__.ttf", fontSize, "OUTLINE")
        fs:SetText(char)

        local progress = (i - 1) / math.max(1, totalChars - 1)
        local colorIndex = math.floor(progress * (#gradient - 1)) + 1
        local nextIndex = math.min(colorIndex + 1, #gradient)
        local localProgress = (progress * (#gradient - 1)) - (colorIndex - 1)

        local c1 = gradient[colorIndex]
        local c2 = gradient[nextIndex]
        local r = c1.r + (c2.r - c1.r) * localProgress
        local g = c1.g + (c2.g - c1.g) * localProgress
        local b = c1.b + (c2.b - c1.b) * localProgress

        fs:SetTextColor(r, g, b, 1)

        if i == 1 then
            fs:SetPoint("LEFT", container, "LEFT", 0, 0)
        else
            fs:SetPoint("LEFT", chars[i-1], "RIGHT", 0, 0)
        end

        chars[i] = fs
    end

    local actualWidth = 0
    for i = 1, #chars do
        actualWidth = actualWidth + chars[i]:GetStringWidth()
    end
    container:SetSize(actualWidth, fontSize + 4)

    return container
end

------------------------------------------------------------------------
-- alert frame creation
------------------------------------------------------------------------
local function CreateAlertFrame()
    if alertFrame then return alertFrame end

    local db = GetDB()

    local frame = CreateFrame("Frame", "ArenaCoreHonorCapAlert", UIParent, "BackdropTemplate")
    frame:SetSize(400, 120)
    frame:SetFrameStrata("HIGH")
    frame:SetFrameLevel(1000)

    frame:SetBackdrop({
        bgFile = "Interface\\Tooltips\\UI-Tooltip-Background",
        edgeFile = "Interface\\Tooltips\\UI-Tooltip-Border",
        tile = true, tileSize = 16, edgeSize = 16,
        insets = { left = 4, right = 4, top = 4, bottom = 4 }
    })
    frame:SetBackdropColor(0.05, 0.05, 0.05, 0.95)
    frame:SetBackdropBorderColor(0.6, 0.2, 0.8, 1)

    if db.posX == 0 and db.posY == 0 then
        frame:SetPoint("CENTER", UIParent, "CENTER", 0, 0)
    else
        frame:SetPoint("CENTER", UIParent, "BOTTOMLEFT", db.posX, db.posY)
    end

    -- emerald green title
    local title = frame:CreateFontString(nil, "OVERLAY")
    title:SetFont(AC.FONT_PATH or "Fonts\\FRIZQT__.ttf", 18, "OUTLINE")
    title:SetText("Honor Cap Reminder")
    title:SetTextColor(0.1, 0.9, 0.3, 1)
    title:SetPoint("CENTER", frame, "TOP", 0, -20)

    -- subtitle
    local subtitle = frame:CreateFontString(nil, "OVERLAY")
    subtitle:SetFont(AC.FONT_PATH or "Fonts\\FRIZQT__.ttf", 14, "OUTLINE")
    subtitle:SetText("Go spend the points!")
    subtitle:SetTextColor(0.9, 0.9, 0.9, 1)
    subtitle:SetPoint("TOP", title, "BOTTOM", 0, -8)

    -- dismiss button
    local dismissBtn = CreateFrame("Button", nil, frame, "BackdropTemplate")
    dismissBtn:SetSize(180, 24)
    dismissBtn:SetPoint("TOP", subtitle, "BOTTOM", 0, -12)
    dismissBtn:SetBackdrop({
        bgFile = "Interface\\Tooltips\\UI-Tooltip-Background",
        edgeFile = "Interface\\Tooltips\\UI-Tooltip-Border",
        tile = true, tileSize = 16, edgeSize = 1,
        insets = { left = 1, right = 1, top = 1, bottom = 1 }
    })
    dismissBtn:SetBackdropColor(0.1, 0.1, 0.1, 0.9)
    dismissBtn:SetBackdropBorderColor(0.3, 0.3, 0.3, 1)

    local btnText = dismissBtn:CreateFontString(nil, "OVERLAY")
    btnText:SetFont(AC.FONT_PATH or "Fonts\\FRIZQT__.ttf", 11)
    btnText:SetText("Disable alert for this session")
    btnText:SetTextColor(0.9, 0.9, 0.9, 1)
    btnText:SetPoint("CENTER", 0, 0)

    dismissBtn:SetScript("OnEnter", function(self)
        self:SetBackdropColor(0.4, 0.15, 0.5, 0.9)
        self:SetBackdropBorderColor(0.8, 0.4, 0.9, 1)
        btnText:SetTextColor(1, 1, 1, 1)
    end)

    dismissBtn:SetScript("OnLeave", function(self)
        self:SetBackdropColor(0.1, 0.1, 0.1, 0.9)
        self:SetBackdropBorderColor(0.3, 0.3, 0.3, 1)
        btnText:SetTextColor(0.9, 0.9, 0.9, 1)
    end)

    dismissBtn:SetScript("OnClick", function()
        sessionDismissed = true
        frame:Hide()
    end)

    -- pulse animation
    local pulseAG = frame:CreateAnimationGroup()
    local pulseAlpha = pulseAG:CreateAnimation("Alpha")
    pulseAlpha:SetFromAlpha(1.0)
    pulseAlpha:SetToAlpha(0.6)
    pulseAlpha:SetDuration(0.8)
    pulseAlpha:SetSmoothing("IN_OUT")

    local pulseAlpha2 = pulseAG:CreateAnimation("Alpha")
    pulseAlpha2:SetFromAlpha(0.6)
    pulseAlpha2:SetToAlpha(1.0)
    pulseAlpha2:SetDuration(0.8)
    pulseAlpha2:SetSmoothing("IN_OUT")
    pulseAlpha2:SetOrder(2)

    pulseAG:SetLooping("REPEAT")
    frame.pulseAG = pulseAG

    -- dragging
    frame:SetMovable(true)
    frame:EnableMouse(true)
    frame:RegisterForDrag("LeftButton")

    frame:SetScript("OnDragStart", function(self)
        self:StartMoving()
        if self.pulseAG then self.pulseAG:Stop() end
    end)

    frame:SetScript("OnDragStop", function(self)
        self:StopMovingOrSizing()
        local x, y = self:GetCenter()
        if x and y then
            local db = GetDB()
            db.posX = x
            db.posY = y
        end
        if self.pulseAG then self.pulseAG:Play() end
    end)

    frame:Hide()
    alertFrame = frame
    return frame
end

------------------------------------------------------------------------
-- honor tracking
------------------------------------------------------------------------
local function GetCurrentHonor()
    local currencyInfo = C_CurrencyInfo.GetCurrencyInfo(HONOR_CURRENCY_ID)
    if currencyInfo and currencyInfo.quantity and type(currencyInfo.quantity) == "number" then
        return currencyInfo.quantity
    end
    return 0
end

------------------------------------------------------------------------
-- core alert logic
------------------------------------------------------------------------
local function CheckAlert()
    local db = GetDB()
    if not db.enabled then
        if alertFrame then
            if alertFrame.pulseAG then alertFrame.pulseAG:Stop() end
            alertFrame:Hide()
        end
        return
    end

    if sessionDismissed then
        if alertFrame then
            if alertFrame.pulseAG then alertFrame.pulseAG:Stop() end
            alertFrame:Hide()
        end
        return
    end

    local honor = GetCurrentHonor()
    local threshold = tonumber(db.threshold) or 12000
    if threshold < 0 then threshold = 12000 end

    if honor >= threshold then
        if not alertFrame then CreateAlertFrame() end
        if not alertFrame:IsShown() then
            alertFrame:Show()
            if alertFrame.pulseAG then
                alertFrame.pulseAG:Play()
            end
        end
    else
        if alertFrame and alertFrame:IsShown() then
            if alertFrame.pulseAG then alertFrame.pulseAG:Stop() end
            alertFrame:Hide()
        end
    end
end

------------------------------------------------------------------------
-- event handling
------------------------------------------------------------------------
local function OnEvent(self, event, ...)
    if event == "PLAYER_LOGIN" then
        sessionDismissed = false
        CheckAlert()

    elseif event == "PLAYER_ENTERING_WORLD" then
        CheckAlert()

    elseif event == "CURRENCY_DISPLAY_UPDATE" then
        local currencyType = ...
        if currencyType == HONOR_CURRENCY_ID then
            CheckAlert()
        end
    end
end

local function RegisterEvents()
    if not eventFrame then
        eventFrame = CreateFrame("Frame")
        eventFrame:SetScript("OnEvent", OnEvent)
    end

    eventFrame:RegisterEvent("PLAYER_LOGIN")
    eventFrame:RegisterEvent("PLAYER_ENTERING_WORLD")
    eventFrame:RegisterEvent("CURRENCY_DISPLAY_UPDATE")
end

local function UnregisterEvents()
    if eventFrame then
        eventFrame:UnregisterAllEvents()
    end
end

------------------------------------------------------------------------
-- public API
------------------------------------------------------------------------
function HCR:Initialize()
    local db = GetDB()
    if not db.enabled then return end

    sessionDismissed = false
    RegisterEvents()
    CheckAlert()
end

function HCR:Toggle()
    local db = GetDB()
    if not db.enabled then
        UnregisterEvents()
        if alertFrame then
            if alertFrame.pulseAG then alertFrame.pulseAG:Stop() end
            alertFrame:Hide()
        end
    else
        RegisterEvents()
        CheckAlert()
    end
end

function HCR:UpdateThreshold()
    CheckAlert()
end

function HCR:ResetPosition()
    local db = GetDB()
    db.posX = 0
    db.posY = 0
    if alertFrame then
        alertFrame:ClearAllPoints()
        alertFrame:SetPoint("CENTER", UIParent, "CENTER", 0, 0)
    end
end
