-- HousingDecorGuide/Core/HDG_CrateContextMenu.lua
-- Shared "Add to crate" context menu. Lists every crate grouped by its
-- parent room (and floor) and adds the given decor on click. Re-used by
-- the Preview tab today; will be re-used by Acquisition / Styles later.

local _, privateDB = ...
local IDs = privateDB and privateDB.HDG_ProjectsIDs

local M = {}

local function _store()
    local HDG = _G.HousingDecorGuide
    return HDG and HDG.Store
end

local function _crateName(coll)
    return (coll and coll.name and coll.name ~= "") and coll.name or "(unnamed crate)"
end

local function _roomLabel(roomID)
    if type(roomID) ~= "string" then return "Unknown room" end
    local parsed = IDs and IDs.parsePath(roomID) or nil
    if parsed and parsed.kind == "room" then
        return string.format("F%d · Room %s", parsed.floor or 0, parsed.roomShortID or "?")
    end
    return roomID
end

-- Build a stable order for menu rendering: rooms sorted by (floor, shortID).
local function _crateGroups()
    local store = _store()
    if not (store and store.Collection_ListByType) then return {} end
    local crates = store:Collection_ListByType("crate") or {}

    local byRoom = {}  -- roomID → { collIDs }
    for collID, coll in pairs(crates) do
        local rid = coll.parent or "__orphan"
        byRoom[rid] = byRoom[rid] or {}
        table.insert(byRoom[rid], { collID = collID, coll = coll })
    end

    local rooms = {}
    for rid in pairs(byRoom) do rooms[#rooms + 1] = rid end
    table.sort(rooms, function(a, b)
        local pa = IDs and IDs.parsePath(a) or {}
        local pb = IDs and IDs.parsePath(b) or {}
        if (pa.floor or 0) ~= (pb.floor or 0) then
            return (pa.floor or 0) < (pb.floor or 0)
        end
        return tostring(pa.roomShortID or a) < tostring(pb.roomShortID or b)
    end)

    local groups = {}
    for _, rid in ipairs(rooms) do
        local entries = byRoom[rid]
        table.sort(entries, function(a, b)
            return (a.coll.createdAt or 0) < (b.coll.createdAt or 0)
        end)
        groups[#groups + 1] = { roomID = rid, entries = entries }
    end
    return groups
end

local function _addAndToast(crateID, itemID, itemName)
    local store = _store()
    if not (store and store.Crate_AddDecor) then return end
    local ok = store:Crate_AddDecor(crateID, itemID)
    if ok and DEFAULT_CHAT_FRAME then
        local coll = store:Collection_Get(crateID)
        local crate = _crateName(coll)
        DEFAULT_CHAT_FRAME:AddMessage(string.format(
            "|cFFfcd34d[HDG]|r Added |cFF14b8a6%s|r to crate |cFFfcd34d%s|r",
            tostring(itemName or ("#" .. itemID)), crate))
    end
end

function M.Show(owner, itemID, itemName)
    if not owner or not itemID then return end
    if not (MenuUtil and MenuUtil.CreateContextMenu) then return end

    local groups = _crateGroups()

    MenuUtil.CreateContextMenu(owner, function(_, root)
        root:CreateTitle("Add to crate")

        if #groups == 0 then
            local btn = root:CreateButton("(no crates yet)", function() end)
            if btn and btn.SetEnabled then btn:SetEnabled(false) end
            root:CreateButton("Open Projects |A:common-icon-forwardarrow:12:12|a Architect", function()
                if _G.HDG_UI and _G.HDG_UI.SwitchTab then _G.HDG_UI.SwitchTab("projects") end
            end)
            return
        end

        for _, group in ipairs(groups) do
            local sub = root:CreateButton(_roomLabel(group.roomID))
            for _, entry in ipairs(group.entries) do
                sub:CreateButton(_crateName(entry.coll), function()
                    _addAndToast(entry.collID, itemID, itemName)
                end)
            end
        end
    end)
end

if privateDB then privateDB.HDG_CrateContextMenu = M end
return M
