--[[ UI/MyBlueprints.lua - "My Blueprints" tab: the player's saved collection via
     RequestBlueprintCollection. Spike: COLLECTION_RECEIVED = { groups = {...} },
     also fired when Blizzard's Blueprints tab opens. Field names inside groups
     are VERIFY - probed defensively; unknown shapes render as a raw dump line
     so a PTR shape change never hard-crashes. Rows with a code are clickable
     -> ad-hoc inspect (UI.InspectCode). ]]

local _, ns = ...
local S = ns.Style
local W = ns.Widgets
ns.UI = ns.UI or {}
local UI = ns.UI
local MB = {}
ns.MyBlueprints = MB

local host, rows, status
local MAX_ROWS = 24
-- Enum verified from live collection payloads (PTR 2026-07-30):
-- 1=interior, 3=full layout/house, 4=exterior. 2/5 unconfirmed -> "?" until seen.
local TYPE_NAMES = { [1] = "Interior", [3] = "House", [4] = "Exterior" }

local function makeRow(parent, i)
  local b = CreateFrame("Button", nil, parent)
  b:SetHeight(18)
  b:SetPoint("TOPLEFT", S.pad, -40 - i * 19)
  b:SetPoint("RIGHT", -S.pad, 0)
  local t = W.Text(b, S.size.small)
  t:SetPoint("LEFT", 2, 0)
  t:SetPoint("RIGHT", -2, 0)
  t:SetWordWrap(false)
  b.text = t
  b:SetScript("OnEnter", function(self)
    if self.code then self.text:SetTextColor(S.gold[1], S.gold[2], S.gold[3]) end
  end)
  b:SetScript("OnLeave", function(self)
    self.text:SetTextColor(S.text[1], S.text[2], S.text[3])
  end)
  b:SetScript("OnClick", function(self)
    if self.code and UI.InspectCode then UI.InspectCode(self.code) end
  end)
  return b
end

local function ensureBuilt()
  if host then return end
  host = CreateFrame("Frame", nil, UI.gridHost)
  host:SetAllPoints()
  host:Hide()
  UI.myBlueprintsHost = host

  local head = W.Text(host, S.size.title, S.gold)
  head:SetPoint("TOPLEFT", S.pad, -S.pad)
  head:SetText("My Blueprints")

  local refresh = W.Button(host, "Refresh", function() MB.Refresh() end)
  refresh:SetPoint("TOPRIGHT", -S.pad, -S.pad + 2)

  status = W.Text(host, S.size.small, S.textDim)
  status:SetPoint("TOPLEFT", S.pad, -34)
  status:SetPoint("RIGHT", -S.pad, 0)

  rows = {}
  for i = 1, MAX_ROWS do rows[i] = makeRow(host, i) end
end

local function describeEntry(e)
  if type(e) ~= "table" then return tostring(e), nil end
  local name = e.name or e.blueprintName or e.title
  local code = e.shareCode or e.code
  local btype = TYPE_NAMES[e.blueprintType or e.type] or ""
  if name or code then
    local s = name or "(unnamed)"
    if btype ~= "" then s = s .. "  |cff888888[" .. btype .. "]|r" end
    if code then s = s .. "  |cff66bbff" .. code .. "|r" end
    return s, code
  end
  local parts = {}
  for k, v in pairs(e) do
    if type(v) ~= "table" then parts[#parts + 1] = tostring(k) .. "=" .. tostring(v) end
    if #parts >= 4 then break end
  end
  return "{" .. table.concat(parts, ", ") .. "}", nil
end

local function render(groups)
  ensureBuilt()
  local list = {}
  for _, group in ipairs(groups or {}) do
    local entries = group.entries or group.blueprints or group
    if type(entries) == "table" then
      for _, e in ipairs(entries) do
        local text, code = describeEntry(e)
        list[#list + 1] = { text = text, code = code }
      end
    end
  end
  if #list == 0 then
    status:SetText("No saved blueprints yet. Save one at your house: " ..
      "Housing Dashboard > Blueprints > '+'.")
  else
    status:SetText(#list .. " saved blueprint(s) - click one to inspect:")
  end
  for i = 1, MAX_ROWS do
    local item = list[i]
    rows[i].code = item and item.code or nil
    rows[i].text:SetText(item and item.text or "")
  end
end

function MB.Refresh()
  ensureBuilt()
  local BP = C_HousingBlueprint
  if not (BP and BP.RequestBlueprintCollection) then
    status:SetText("Blueprint collection API not available on this client (needs 12.1).")
    return
  end
  status:SetText("Loading your blueprints...")
  local ok = pcall(BP.RequestBlueprintCollection)
  if not ok then status:SetText("Request failed - try again at your house.") end
end

function MB.Show()
  ensureBuilt()
  host:Show()
  MB.Refresh()
end

function MB.Hide()
  if host then host:Hide() end
end

ns.events:Register("HOUSING_BLUEPRINT_COLLECTION_RECEIVED", function(_, payload)
  if type(payload) == "table" then render(payload.groups or payload) end
end)
