local _, ns = ...

local UIProgressBars = {}
ns.UIProgressBars = UIProgressBars

local UIData = ns.UIData or {}
local PREMIUM = UIData.PREMIUM or {}
local THEME = UIData.THEME or {}

local function clamp(value, minimum, maximum)
    if value < minimum then
        return minimum
    end

    if value > maximum then
        return maximum
    end

    return value
end

local function setTextureColor(texture, color, alpha)
    if not texture or type(color) ~= "table" then
        return
    end

    texture:SetVertexColor(color[1], color[2], color[3], alpha == nil and 1 or alpha)
end

local function createProgressBar(parent)
    local bar = CreateFrame("StatusBar", nil, parent)
    bar:SetMinMaxValues(0, 1)
    bar:SetValue(0)
    bar:SetStatusBarTexture(PREMIUM.barFill)
    bar:SetStatusBarColor(0.74, 0.63, 0.28, 0.95)

    bar.backdrop = bar:CreateTexture(nil, "BACKGROUND", nil, -1)
    bar.backdrop:SetPoint("TOPLEFT", -1, 1)
    bar.backdrop:SetPoint("BOTTOMRIGHT", 1, -1)
    bar.backdrop:SetTexture(PREMIUM.barBg)
    bar.backdrop:SetVertexColor(0.08, 0.07, 0.06, 0.22)

    bar.bg = bar:CreateTexture(nil, "BACKGROUND")
    bar.bg:SetAllPoints()
    bar.bg:SetTexture(PREMIUM.barBg)
    setTextureColor(bar.bg, { 1, 1, 1 }, 0.94)

    bar.fill = bar:GetStatusBarTexture()
    bar.fill:SetHorizTile(false)
    bar.fill:SetVertTile(false)

    bar.fillOverlay = bar:CreateTexture(nil, "ARTWORK")
    bar.fillOverlay:SetPoint("TOPLEFT", bar.fill, "TOPLEFT", 0, 0)
    bar.fillOverlay:SetPoint("BOTTOMRIGHT", bar.fill, "BOTTOMRIGHT", 0, 0)
    bar.fillOverlay:SetTexture(PREMIUM.barOverlay)
    bar.fillOverlay:SetBlendMode("ADD")
    setTextureColor(bar.fillOverlay, { 1, 1, 1 }, 0.22)

    bar.glow = bar:CreateTexture(nil, "ARTWORK")
    bar.glow:SetPoint("TOPLEFT", bar, "TOPLEFT", 0, 0)
    bar.glow:SetPoint("BOTTOMRIGHT", bar, "BOTTOMLEFT", 1, 0)
    bar.glow:SetTexture(PREMIUM.barOverlay)
    bar.glow:SetBlendMode("ADD")
    bar.glow:SetAlpha(0.06)
    bar.glow:Hide()

    bar.spark = bar:CreateTexture(nil, "OVERLAY")
    bar.spark:SetSize(16, 20)
    bar.spark:SetTexture(PREMIUM.barSpark)
    bar.spark:SetBlendMode("ADD")
    bar.spark:SetAlpha(0.18)

    bar.topEdge = bar:CreateTexture(nil, "BORDER")
    bar.topEdge:SetPoint("TOPLEFT", 7, 0)
    bar.topEdge:SetPoint("TOPRIGHT", -7, 0)
    bar.topEdge:SetHeight(1)
    bar.topEdge:SetTexture("Interface\\Buttons\\WHITE8X8")
    setTextureColor(bar.topEdge, THEME.parchment, 0.10)

    bar.bottomEdge = bar:CreateTexture(nil, "BORDER")
    bar.bottomEdge:SetPoint("BOTTOMLEFT", 7, 0)
    bar.bottomEdge:SetPoint("BOTTOMRIGHT", -7, 0)
    bar.bottomEdge:SetHeight(1)
    bar.bottomEdge:SetTexture("Interface\\Buttons\\WHITE8X8")
    bar.bottomEdge:SetColorTexture(THEME.shadow[1], THEME.shadow[2], THEME.shadow[3], 0.16)

    bar.markers = {}
    return bar
end

local function setProgressBar(bar, ratio, r, g, b)
    if not bar then
        return
    end

    local value = clamp(tonumber(ratio) or 0, 0, 1)
    bar:SetStatusBarColor(r or 0.62, g or 0.84, b or 0.66, 0.95)
    local visualValue = value >= 0.015 and value or 0
    bar:SetValue(visualValue)
    local barWidth = bar:GetWidth() or 1
    local width = math.floor(barWidth * visualValue)
    if bar.glow then
        bar.glow:ClearAllPoints()
        if width > 1 then
            bar.glow:SetPoint("TOPLEFT", bar, "TOPLEFT", 1, 0)
            bar.glow:SetPoint("BOTTOMRIGHT", bar, "BOTTOMLEFT", width, 0)
            bar.glow:SetVertexColor(r or 0.66, g or 0.92, b or 0.82, 0.05)
            bar.glow:Show()
        else
            bar.glow:Hide()
        end
    end
    if bar.fillOverlay then
        bar.fillOverlay:SetShown(visualValue > 0)
        bar.fillOverlay:SetVertexColor(1, 1, 1, visualValue > 0 and 0.035 or 0)
    end
    if bar.spark then
        local sparkOffset = math.max(0, math.min(barWidth - 1, width))
        bar.spark:ClearAllPoints()
        bar.spark:SetPoint("CENTER", bar, "LEFT", sparkOffset, 0)
        bar.spark:SetVertexColor(r or 0.66, g or 0.92, b or 0.82, 0.16)
        bar.spark:SetShown(visualValue > 0.04 and visualValue < 0.992)
    end
end

local function setProgressBreakpoints(bar, thresholds, maxThreshold)
    if not bar then
        return
    end

    maxThreshold = tonumber(maxThreshold) or 0
    thresholds = type(thresholds) == "table" and thresholds or {}

    for index, threshold in ipairs(thresholds) do
        local marker = bar.markers[index]
        if not marker then
            marker = bar:CreateTexture(nil, "OVERLAY")
            marker:SetSize(16, 16)
            marker:SetTexture(PREMIUM.barMarker)
            marker:SetBlendMode("BLEND")
            marker:SetVertexColor(0.96, 0.82, 0.48, 0.54)
            bar.markers[index] = marker
        end

        if maxThreshold > 0 and tonumber(threshold) and threshold < maxThreshold then
            local ratio = threshold / maxThreshold
            marker:ClearAllPoints()
            marker:SetPoint("CENTER", bar, "LEFT", math.floor(((bar:GetWidth() or 1) * ratio) + 0.5), 0)
            marker:Show()
        else
            marker:Hide()
        end
    end

    for index = #thresholds + 1, #bar.markers do
        bar.markers[index]:Hide()
    end
end

UIProgressBars.Create = createProgressBar
UIProgressBars.Set = setProgressBar
UIProgressBars.SetBreakpoints = setProgressBreakpoints
