--[[
    Commander 3.0 - TUI Gauge Widget

    A horizontal progress bar with optional label.
    Uses Unicode block characters for smooth fill (1/8th increments).

    Usage:
        local gauge = Gauge:new()
            :ratio(0.75)
            :label("75%")
            :barColor("88C0D0")
            :bgColor("3B4252")

        gauge:render(buf, rect)
]]

local ADDON_NAME, C3 = ...

local Widget = C3.TUI.Widget
local Symbols = C3.TUI.Symbols

-------------------------------------------------------------------------------
-- Gauge Widget
-------------------------------------------------------------------------------

local Gauge = C3.class()
C3.TUI.Widgets = C3.TUI.Widgets or {}
C3.TUI.Widgets.Gauge = Gauge

function Gauge:init()
    self._ratio = 0          -- 0.0 to 1.0
    self._label = nil        -- Optional label (nil = show percentage)
    self._block = nil        -- Optional containing block
    self._barColor = nil     -- Resolved at render time via TUI.Colors
    self._bgColor = nil      -- Resolved at render time via TUI.Colors
    self._labelColor = nil   -- Resolved at render time via TUI.Colors
    self._useUnicode = true  -- Use Unicode fractional blocks
    self._showLabel = true   -- Show centered label
end

---Set progress as percentage (0-100)
---@param percent number
---@return Gauge
function Gauge:percent(percent)
    self._ratio = math.max(0, math.min(100, percent)) / 100
    return self
end

---Set progress as ratio (0.0-1.0)
---@param ratio number
---@return Gauge
function Gauge:ratio(ratio)
    self._ratio = math.max(0, math.min(1, ratio))
    return self
end

---Set label (nil = show percentage)
---@param label string|nil
---@return Gauge
function Gauge:label(label)
    self._label = label
    return self
end

---Set containing block (optional)
---@param block table Block widget
---@return Gauge
function Gauge:block(block)
    self._block = block
    return self
end

---Set bar fill color
---@param color string Hex color
---@return Gauge
function Gauge:barColor(color)
    self._barColor = color
    return self
end

---Set background (empty) color
---@param color string Hex color
---@return Gauge
function Gauge:bgColor(color)
    self._bgColor = color
    return self
end

---Set label color
---@param color string Hex color
---@return Gauge
function Gauge:labelColor(color)
    self._labelColor = color
    return self
end

---Use Unicode fractional blocks for smooth fill
---@param use boolean
---@return Gauge
function Gauge:useUnicode(use)
    self._useUnicode = use
    return self
end

---Show/hide label
---@param show boolean
---@return Gauge
function Gauge:showLabel(show)
    self._showLabel = show
    return self
end

---Get fractional block character
---@param fraction number 0.0 to 1.0
---@return string
local function getFractionalBlock(fraction)
    if fraction >= 0.875 then return Symbols.BAR.sevenEighths
    elseif fraction >= 0.75 then return Symbols.BAR.threeQuarters
    elseif fraction >= 0.625 then return Symbols.BAR.fiveEighths
    elseif fraction >= 0.5 then return Symbols.BAR.half
    elseif fraction >= 0.375 then return Symbols.BAR.threeEighths
    elseif fraction >= 0.25 then return Symbols.BAR.quarter
    elseif fraction >= 0.125 then return Symbols.BAR.eighth
    else return " "
    end
end

---Render the gauge
---@param buf table TuiBuffer
---@param rect table Rect
function Gauge:render(buf, rect)
    local TuiColors = C3.TUI.Colors

    -- Resolve colors (use explicit or fall back to theme)
    local barColor = TuiColors.Resolve(self._barColor, TuiColors.barFill)
    local bgColor = TuiColors.Resolve(self._bgColor, TuiColors.barBg)
    local labelColor = TuiColors.Resolve(self._labelColor, TuiColors.barLabel)

    local gauge = self
    Widget.RenderWithBlock(self, buf, rect, function(innerRect)
        local width = innerRect.width
        local y = innerRect.y

        -- Calculate fill
        local filledWidth = gauge._ratio * width
        local fullBlocks = math.floor(filledWidth)
        local partialFraction = filledWidth - fullBlocks

        -- Draw the bar
        for x = 1, width do
            local col = innerRect.x + x - 1

            if x <= fullBlocks then
                -- Full block
                buf:SetCell(col, y, Symbols.BAR.full, barColor)
            elseif x == fullBlocks + 1 and partialFraction > 0 and gauge._useUnicode then
                -- Partial block (fractional fill)
                buf:SetCell(col, y, getFractionalBlock(partialFraction), barColor)
            else
                -- Empty (background)
                buf:SetCell(col, y, Symbols.BAR.empty, bgColor)
            end
        end

        -- Draw centered label
        if gauge._showLabel then
            local label = gauge._label
            if not label then
                label = string.format("%d%%", math.floor(gauge._ratio * 100))
            end

            local labelLen = Widget.TextWidth(label)
            if labelLen <= width then
                local labelX = innerRect.x + math.floor((width - labelLen) / 2)
                buf:SetString(labelX, y, label, labelColor)
            end
        end
    end)
end

-------------------------------------------------------------------------------
-- Convenience Constructors
-------------------------------------------------------------------------------

---Create a simple percentage gauge
---@param percent number 0-100
---@param color? string Bar color
---@return Gauge
function Gauge.Percent(percent, color)
    local gauge = Gauge:new():percent(percent)
    if color then gauge:barColor(color) end
    return gauge
end

---Create a health-bar style gauge (green → yellow → red)
---@param ratio number 0.0-1.0
---@return Gauge
function Gauge.Health(ratio)
    local TuiColors = C3.TUI.Colors
    local color = TuiColors.healthForRatio(ratio)
    return Gauge:new():ratio(ratio):barColor(color)
end

---Create a mana-bar style gauge (blue)
---@param ratio number 0.0-1.0
---@return Gauge
function Gauge.Mana(ratio)
    local TuiColors = C3.TUI.Colors
    return Gauge:new():ratio(ratio):barColor(TuiColors.mana)
end

return Gauge
