-- HDG_HT_W_Velocity.lua
-- Acquisition pace + ETA to next title-tier threshold + 90-day forecast.
-- Pure read-side widget: consumes snap.velocity (computed by the Aggregator)
-- and snap.titleTier; no events, no caching. Hidden when no recent
-- craftingHistory data is available (snap.velocity is nil).

local _, privateDB = ...
privateDB.HDG_HT = privateDB.HDG_HT or {}
privateDB.HDG_HT.Widgets = privateDB.HDG_HT.Widgets or {}
local W = { id = "velocity", title = "Collection Velocity" }
privateDB.HDG_HT.Widgets.Velocity = W

local Theme = privateDB.HDG_HT.Theme

local function fmt(n)
    if BreakUpLargeNumbers then return BreakUpLargeNumbers(n) end
    return tostring(n)
end

-- Format a day count compactly: "in 3d", "in 12d", "~3 weeks", "~2 months"
local function formatETA(days)
    if not days or days <= 0 then return nil end
    if days <= 14 then return string.format("~%dd", days) end
    if days <= 60 then return string.format("~%d weeks", math.floor(days / 7 + 0.5)) end
    return string.format("~%d months", math.floor(days / 30 + 0.5))
end

function W.Create(parent, dims)
    local self = { dims = dims }

    -- Parent here is the cockpit's body region (chrome + title bar are
    -- drawn separately by the cockpit framework). Fill it.
    local frame = CreateFrame("Frame", nil, parent)
    frame:SetAllPoints(parent)
    self.frame = frame

    -- Big number: items per week. Anchored to TOPLEFT of body region with
    -- some inset; cockpit's own title bar sits above this region.
    local pace = frame:CreateFontString(nil, "OVERLAY", "GameFontHighlightLarge")
    pace:SetPoint("TOPLEFT", frame, "TOPLEFT", 10, -8)
    pace:SetText("--")
    self.paceLabel = pace

    local paceUnit = frame:CreateFontString(nil, "OVERLAY", "GameFontHighlightSmall")
    paceUnit:SetPoint("LEFT", pace, "RIGHT", 4, -2)
    paceUnit:SetText("items/week")
    self.paceUnitLabel = paceUnit

    -- Sub-line: items in last 30 days
    local recent = frame:CreateFontString(nil, "OVERLAY", "GameFontDisableSmall")
    recent:SetPoint("TOPLEFT", pace, "BOTTOMLEFT", 0, -6)
    recent:SetText("")
    self.recentLabel = recent

    -- ETA to next tier
    local eta = frame:CreateFontString(nil, "OVERLAY", "GameFontHighlightSmall")
    eta:SetPoint("TOPLEFT", recent, "BOTTOMLEFT", 0, -8)
    eta:SetText("")
    self.etaLabel = eta

    -- 90-day forecast
    local forecast = frame:CreateFontString(nil, "OVERLAY", "GameFontDisableSmall")
    forecast:SetPoint("TOPLEFT", eta, "BOTTOMLEFT", 0, -4)
    forecast:SetText("")
    self.forecastLabel = forecast

    function self:Refresh(snap)
        local v = snap and snap.velocity
        if not v then
            self.paceLabel:SetText("--")
            self.recentLabel:SetText("Insufficient history yet")
            self.etaLabel:SetText("")
            self.forecastLabel:SetText("")
            return
        end

        -- Pace number: round to nearest 0.1 for sub-week paces, integer otherwise
        local pw = v.perWeek or 0
        if pw < 10 then
            self.paceLabel:SetText(string.format("%.1f", pw))
        else
            self.paceLabel:SetText(string.format("%d", math.floor(pw + 0.5)))
        end

        self.recentLabel:SetText(string.format("%d items in last %dd",
            v.recentCount or 0, v.recentDays or 30))

        local etaStr = formatETA(v.daysToNextTier)
        if etaStr and v.nextTierName then
            local cAccent = (Theme and Theme.C_Accent and Theme.C_Accent()) or "|cFFffd34d"
            self.etaLabel:SetText(string.format("%s%s|r to %s", cAccent, etaStr, v.nextTierName))
        elseif v.daysToNextTier then
            self.etaLabel:SetText("")  -- no name resolved
        else
            -- Either at max rank, or no recent pace
            if (v.perDay or 0) > 0 then
                self.etaLabel:SetText("Max rank reached")
            else
                self.etaLabel:SetText("")
            end
        end

        if v.ninetyDayForecast and v.ninetyDayForecast > (snap.collectedAll or 0) then
            self.forecastLabel:SetText(string.format("90-day forecast: %s total",
                fmt(v.ninetyDayForecast)))
        else
            self.forecastLabel:SetText("")
        end
    end

    function self:Resize(w, h)
        if frame.SetSize then frame:SetSize(w, h) end
    end

    return self
end

return W
