-- ============================================================
-- Komo Hold'Em — Lobby logic
-- Table discovery + hosting. Host re-announces every 15s so party
-- members who open the launcher late (or just joined the group)
-- still see the table. /kh close tears it down.
-- ============================================================
local _, KH = ...
KH.Lobby = {}
local Lobby = KH.Lobby

Lobby.known = {}   -- discovered tables: [id] = announce data
Lobby.mine  = nil  -- table I host

function Lobby:Init()
    local MSG   = KH.Comms.MSG
    local Comms = KH.Comms

    Comms:RegisterHandler(MSG.TABLE_ANNOUNCE, function(sender, _, f)
        local id, name, stakes, amount, seats, taken, inprog, handNo = unpack(f)
        if not id or not name or not seats or KH:IsMe(sender) then return end
        Lobby.known[id] = {
            id = id, host = sender, name = name, stakes = stakes,
            amount = tonumber(amount) or 0,
            seats  = tonumber(seats) or 6,
            taken  = tonumber(taken) or 1,
            inProgress = inprog == "1",
            handNo = tonumber(handNo),
            seenAt = GetTime(),
        }
        if KH.Launcher then KH.Launcher:RefreshTableList() end
    end)

    Comms:RegisterHandler(MSG.TABLE_CLOSE, function(sender, _, f)
        if f[1] and Lobby.known[f[1]] then
            Lobby.known[f[1]] = nil
            if KH.Launcher then KH.Launcher:RefreshTableList() end
        end
    end)

    -- stale tables: prune anything not re-announced within 45s
    C_Timer.NewTicker(45, function()
        local now = GetTime()
        local dirty = false
        for id, t in pairs(Lobby.known) do
            if t.seenAt and now - t.seenAt > 45 then
                Lobby.known[id] = nil
                dirty = true
            end
        end
        if dirty and KH.Launcher then KH.Launcher:RefreshTableList() end
    end)
end

-- ------------------------------------------------------------
-- hosting
-- ------------------------------------------------------------
function Lobby:Announce()
    if not self.mine then return end
    local t, cfg = self.mine, self.mine.config
    local taken = 0
    for _ in pairs(t.players) do taken = taken + 1 end
    KH.Comms:Broadcast(KH.Comms.MSG.TABLE_ANNOUNCE,
        t.id, cfg.name, cfg.stakes, cfg.amount, cfg.seats, taken,
        t.state ~= KH.Game.STATE.LOBBY and 1 or 0, t.handNo or 0)
end

function Lobby:HostTable(config)
    if self.mine then
        KH:Print("You're already hosting \"" .. self.mine.config.name .. "\". /kh close to close it.")
        return
    end
    self.mine = KH.Game:NewTable(config)
    self.mine.players[KH.playerFull] = {
        seat = 1, stack = config.amount, ready = true, connected = true,
    }
    self.mine.seatOrder = { KH.playerFull }

    if not KH.Comms:Broadcast(KH.Comms.MSG.TABLE_ANNOUNCE,
        self.mine.id, config.name, config.stakes, config.amount, config.seats, 1, 0) then
        KH:Print("|cfff08a80You're not in a party or raid|r — nobody can see this table yet. Group up and it will announce automatically.")
    else
        KH:Print("Table \"" .. config.name .. "\" is up. Announcing to your group.")
    end
    if config.stakes == "gold" then KH.Sounds:Play("GOLD_NOTICE") end
    KH.Host:BroadcastRoster()

    -- keep announcing for late openers
    self.announcer = C_Timer.NewTicker(15, function() Lobby:Announce() end)
end

function Lobby:HostDefaultTable()
    self:HostTable({
        name   = UnitName("player") .. "'s Table",
        stakes = "chips",
        amount = 2500,
        seats  = 6,
        timer  = 30,
    })
end

function Lobby:CloseTable()
    if not self.mine then
        KH:Print("You aren't hosting a table.")
        return
    end
    local t = self.mine
    -- if a game ran, everyone settles from final stacks before closing
    if t.state ~= KH.Game.STATE.LOBBY and t.handNo and t.handNo > 0 then
        KH.Comms:Broadcast(KH.Comms.MSG.SETTLE, t.id, t.handNo)
    end
    KH.Comms:Broadcast(KH.Comms.MSG.TABLE_CLOSE, t.id)
    if self.announcer then self.announcer:Cancel() self.announcer = nil end
    KH:Print("Table \"" .. t.config.name .. "\" closed.")
    self.mine = nil
    if not (t.handNo and t.handNo > 0) then
        KH.Client:Reset()
    end
end
