--[[
    Commander 3.0 - TUI Demo App

    A simple demo to test the TUI system.
    Launch with: tuidemo
]]

local ADDON_NAME, C3 = ...

-------------------------------------------------------------------------------
-- Demo App
-------------------------------------------------------------------------------

local DemoApp = C3.TUI.App:extend()

function DemoApp:init(terminal)
    self:super("init", terminal)

    self.name = "TUI Demo"
    self.tickInterval = 0.1  -- 10 FPS for gauge animation

    -- Menu state
    self.menuState = C3.TUI.ListState:new()
    self.menuItems = {
        { text = "Show Health Bar", action = "health" },
        { text = "Show Mana Bar", action = "mana" },
        { text = "Animate Progress", action = "animate" },
        { text = "Change Border Style", action = "border" },
        { text = "Exit Demo", action = "exit" },
    }

    -- Demo state
    self.healthPercent = 75
    self.manaPercent = 50
    self.animating = false
    self.animProgress = 0
    self.borderStyle = "rounded"
    self.borderStyles = { "rounded", "single", "double", "thick" }
    self.borderIndex = 1

    -- Status message
    self.statusMessage = "Use arrows to navigate, Enter to select"
end

function DemoApp:draw(buf)
    local area = buf:Area()

    -- Main layout: menu on left, content on right
    local layout = C3.Layout.new()
        :direction(C3.Layout.HORIZONTAL)
        :constraints({
            C3.Constraint.Length(28),
            C3.Constraint.Fill(1),
        })

    local chunks = layout:split(area)

    -- Draw menu
    self:_drawMenu(buf, chunks[1])

    -- Draw content panel
    self:_drawContent(buf, chunks[2])

    -- Release pooled rects
    C3.Rect.ReleaseAll(chunks)
end

function DemoApp:_drawMenu(buf, rect)
    local Block = C3.TUI.Widgets.Block
    local List = C3.TUI.Widgets.List
    local Symbols = C3.TUI.Symbols
    local TuiColors = C3.TUI.Colors

    local block = Block:new()
        :borders(Block.ALL)
        :borderType(self.borderStyle)
        :title("TUI Demo")
        :borderColor(TuiColors.border())
        :titleColor(TuiColors.border())

    -- List uses theme colors by default now, but we can still customize
    local list = List:new()
        :items(self.menuItems)
        :block(block)
        :highlightSymbol(Symbols.MARKERS.pointer .. " ")
        -- Colors will auto-resolve from TUI.Colors if not specified

    list:render(buf, rect, self.menuState)
end

function DemoApp:_drawContent(buf, rect)
    local Block = C3.TUI.Widgets.Block
    local Gauge = C3.TUI.Widgets.Gauge
    local TuiColors = C3.TUI.Colors

    -- Content block
    local block = Block:new()
        :borders(Block.ALL)
        :borderType(self.borderStyle)
        :title("Preview")
        :borderColor(TuiColors.borderDim())
        :titleColor(TuiColors.info())

    block:render(buf, rect)
    local inner = block:inner(rect)

    local y = inner.y

    -- Health bar
    buf:SetString(inner.x, y, "Health:", TuiColors.error())
    y = y + 1

    local healthRect = C3.Rect.Acquire(inner.x, y, math.min(30, inner.width), 1)
    Gauge.Health(self.healthPercent / 100):render(buf, healthRect)
    C3.Rect.Release(healthRect)
    y = y + 2

    -- Mana bar
    buf:SetString(inner.x, y, "Mana:", TuiColors.info())
    y = y + 1

    local manaRect = C3.Rect.Acquire(inner.x, y, math.min(30, inner.width), 1)
    Gauge.Mana(self.manaPercent / 100):render(buf, manaRect)
    C3.Rect.Release(manaRect)
    y = y + 2

    -- Animation bar (if active)
    if self.animating then
        buf:SetString(inner.x, y, "Animation:", TuiColors.warning())
        y = y + 1

        local animRect = C3.Rect.Acquire(inner.x, y, math.min(30, inner.width), 1)
        Gauge:new()
            :ratio(self.animProgress)
            :barColor(TuiColors.special())
            :label("Loading...")
            :render(buf, animRect)
        C3.Rect.Release(animRect)
        y = y + 2
    end

    -- Border style info
    y = y + 1
    buf:SetString(inner.x, y, "Border: " .. self.borderStyle, TuiColors.textDim())
    y = y + 2

    -- Status message at bottom
    local statusY = inner.y + inner.height - 1
    local statusText = C3.TUI.Widget.Truncate(self.statusMessage, inner.width)
    buf:SetString(inner.x, statusY, statusText, TuiColors.textDim())

    C3.Rect.Release(inner)
end

function DemoApp:tick()
    -- Animate progress bar if active
    if self.animating then
        self.animProgress = self.animProgress + 0.02
        if self.animProgress >= 1 then
            self.animProgress = 0
        end
        self:MarkDirty()
    end
end

function DemoApp:handleInput(action, key)
    if action == "up" then
        self.menuState:prev()
        self:_updateStatus()
        return true
    end

    if action == "down" then
        self.menuState:next(#self.menuItems)
        self:_updateStatus()
        return true
    end

    if action == "select" then
        local item = self.menuItems[self.menuState.selected]
        if item then
            self:_handleAction(item.action)
        end
        return true
    end

    if action == "cancel" or action == "quit" then
        self:Stop()
        return true
    end

    return false
end

function DemoApp:_handleAction(actionName)
    if actionName == "health" then
        -- Cycle health
        self.healthPercent = (self.healthPercent + 25) % 125
        if self.healthPercent == 0 then self.healthPercent = 25 end
        self.statusMessage = "Health: " .. self.healthPercent .. "%"

    elseif actionName == "mana" then
        -- Cycle mana
        self.manaPercent = (self.manaPercent + 25) % 125
        if self.manaPercent == 0 then self.manaPercent = 25 end
        self.statusMessage = "Mana: " .. self.manaPercent .. "%"

    elseif actionName == "animate" then
        -- Toggle animation
        self.animating = not self.animating
        self.animProgress = 0
        self.statusMessage = self.animating and "Animation started" or "Animation stopped"

    elseif actionName == "border" then
        -- Cycle border styles
        self.borderIndex = (self.borderIndex % #self.borderStyles) + 1
        self.borderStyle = self.borderStyles[self.borderIndex]
        self.statusMessage = "Border: " .. self.borderStyle

    elseif actionName == "exit" then
        self:Stop()
    end
end

function DemoApp:_updateStatus()
    local item = self.menuItems[self.menuState.selected]
    if item then
        self.statusMessage = "Selected: " .. item.text
    end
end

-------------------------------------------------------------------------------
-- Command Registration
-------------------------------------------------------------------------------

C3.Command:Define({
    name = "tuidemo",
    description = "Launch TUI demo application",
    category = "system",
    execute = function(ctx)
        -- Get terminal from session (how other commands access it)
        local terminal = ctx.session and ctx.session.terminal
        if not terminal then
            -- Fallback to primary terminal
            terminal = C3.Terminal or (C3.WindowRegistry and C3.WindowRegistry:GetPrimary())
        end

        if not terminal then
            return C3.Types.Create("Error", { message = "No terminal available" })
        end

        local app = DemoApp:new(terminal)
        app:Start()

        -- Return nil since app takes over UI
        return nil
    end
})

return DemoApp
