-- HousingDecorGuide/Modules/HDG_ProjectsStore.lua
-- Facade over HDG.Store.state.projects. Pure read helpers + thin write
-- wrappers that forward to HDG.Store:UpsertProjectHouse/Room/etc.
-- Schema is seeded by HDG.Store DEFAULT_STATE; persistence is handled
-- via HDG.Store's QueueSave + SaveToSavedVariables.

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

local M = {}

local function _projects()
    local s = _G.HousingDecorGuide and _G.HousingDecorGuide.Store
    if not s or not s.GetState then return nil end
    local state = s:GetState()
    return state and state.projects
end

local function _Store()
    return _G.HousingDecorGuide and _G.HousingDecorGuide.Store
end

-- ---- Houses (read + write facade) ----

function M.GetHouse(houseID)
    local p = _projects()
    return p and p.houses[houseID]
end

function M.GetAllHouses()
    local p = _projects()
    return p and p.houses or {}
end

function M.UpsertHouse(houseID, fields)
    if not IDs.parseHouseID(houseID) then return nil end
    local store = _Store()
    if not store or not store.UpsertProjectHouse then return nil end
    -- Provide a default name if none specified and this is a fresh entry
    fields = fields or {}
    if not fields.name then
        local existing = M.GetHouse(houseID)
        if not existing or not existing.name then
            local faction = IDs.parseHouseID(houseID)
            fields.name = "My " .. (faction:gsub("^%l", string.upper)) .. " House"
        end
    end
    return store:UpsertProjectHouse(houseID, fields)
end

-- ---- Rooms (read + write facade) ----

function M.GetRoom(roomID)
    local p = _projects()
    return p and p.rooms[roomID]
end

function M.UpsertRoom(roomID, fields)
    local parsed = IDs.parsePath(roomID)
    if not parsed or parsed.kind ~= "room" then return nil end
    local store = _Store()
    if not store or not store.UpsertProjectRoom then return nil end
    return store:UpsertProjectRoom(roomID, fields)
end

function M.DeleteRoom(roomID)
    local store = _Store()
    if store and store.DeleteProjectRoom then
        store:DeleteProjectRoom(roomID)
    end
end

-- Prefix scan: returns array of { id = roomID, room = roomRecord }
function M.GetRoomsByPrefix(prefix)
    local p = _projects()
    if not p then return {} end
    local out = {}
    for id, r in pairs(p.rooms) do
        if id:sub(1, #prefix) == prefix then
            out[#out + 1] = { id = id, room = r }
        end
    end
    return out
end

function M.GetRoomsForHouse(houseID)
    return M.GetRoomsByPrefix(houseID .. ":")
end

function M.GetRoomsForFloor(floorID)
    return M.GetRoomsByPrefix(floorID .. ":")
end

-- Derived: numFloors for a house = max f<n> across its rooms
function M.GetNumFloors(houseID)
    local rooms = M.GetRoomsForHouse(houseID)
    local maxF = 0
    for _, entry in ipairs(rooms) do
        local parsed = IDs.parsePath(entry.id)
        if parsed and parsed.floor and parsed.floor > maxF then
            maxF = parsed.floor
        end
    end
    return maxF
end

-- Mint a fresh roomID with collision-checked shortUUID
function M.MintRoomID(floorID, attempts)
    attempts = attempts or 32
    local p = _projects()
    if not p then return nil end
    for _ = 1, attempts do
        local short = IDs.shortUUID(4)
        local id = IDs.makeRoomID(floorID, short)
        if id and not p.rooms[id] then return id end
    end
    -- Fallback to longer UUID if 4-hex space is dense
    local short = IDs.shortUUID(8)
    return IDs.makeRoomID(floorID, short)
end

-- ---- UI state (read + write facade) ----

function M.GetUI()
    local p = _projects()
    return p and p.ui or {}
end

function M.SetUIField(field, value)
    local store = _Store()
    if store and store.SetProjectUI then
        store:SetProjectUI(field, value)
    end
end

privateDB.HDG_ProjectsStore = M
