-- factoryos.apps.power — energy overview fed by core.telemetry.
return {
  id = "power", name = "POWER",
  desc = "Energy storage & flow",

  create = function(ctx)
    local W     = require("factoryos.ui.widgets")
    local sched = require("factoryos.core.sched")
    local util  = require("factoryos.util")
    local node, wm = ctx.node, ctx.wm
    local C = W.colors

    local bar   = W.ProgressBar({ x = 2, y = 3, w = 46, value = 0 })
    local store = W.Label({ x = 2, y = 5, w = 46, text = "stored: --" })
    local rate  = W.Label({ x = 2, y = 6, w = 46, text = "net: --" })
    local units = W.Table({ x = 2, y = 8, w = 54, h = 8,
      cols = { 22, 14, 14 }, rows = { { "UNIT", "STORED", "CAPACITY" } } })

    local function apply(metrics)
      local m = {}
      for _, mm in ipairs(metrics or {}) do m[mm.n] = mm end
      local pct = m["power.pct"]
      bar.value = pct and (pct.v / 100) or 0
      bar.color = (pct and pct.v or 0) < 15 and C.danger or C.ok
      local s, cap = m["power.stored"], m["power.capacity"]
      store.text = string.format("stored: %s / %s   quality: %s",
        s and util.eng(s.v, s.u) or "n/a",
        cap and util.eng(cap.v, cap.u) or "n/a",
        s and s.q or "unavailable")
      local nr = m["power.net_rate"]
      rate.text = string.format("net: %s   units: %s   source: %s",
        nr and (util.eng(nr.v, nr.u .. "/t")) or "n/a",
        m["power.units"] and tostring(m["power.units"].v) or "n/a",
        m["power.node"] and tostring(m["power.node"].v) or "--")
      if m["power.units_table"] and type(m["power.units_table"].v) == "table" then
        local rows = { { "UNIT", "STORED", "CAPACITY" } }
        for _, u in ipairs(m["power.units_table"].v) do
          rows[#rows + 1] = { u.name, util.eng(u.stored, "FE"), util.eng(u.cap, "FE") }
        end
        units.rows = rows
      end
    end

    local function poll()
      local ok, res = node:call("core.telemetry", "query")
      if not ok then return end
      local pw = {}
      for _, m in ipairs(res.metrics or {}) do
        if m.n and m.n:sub(1, 6) == "power." then pw[#pw + 1] = m end
      end
      apply(pw)
    end

    node:on("telemetry.updated", function() poll(); wm:draw() end)
    node:spawn(function()
      while true do sched.sleep(5); poll(); wm:draw() end
    end, "power.poll")

    poll()
    return {
      title = "POWER GRID", x = 4, y = 2, w = 58, h = 18,
      widgets = {
        W.Label({ x = 2, y = 2, w = 40, text = "STORAGE", color = C.dim }),
        bar, store, rate,
        W.Sep({ x = 2, y = 7, w = 54 }),
        units,
      },
    }
  end,
}
