-- Tournaments: scheduled events with an entry fee, a prize pool, and a
-- leaderboard.
--
-- The prize pool is a real ledger account, not a number in a row. Entry fees
-- move into it and prizes move out of it, so a tournament's money is subject to
-- the same double-entry invariants as everything else and cannot be
-- accidentally created or lost.

CREATE TYPE tournament_status AS ENUM
    ('scheduled', 'registering', 'running', 'settled', 'cancelled');

CREATE TABLE tournaments (
    id             BIGSERIAL PRIMARY KEY,
    name           TEXT NOT NULL,
    game           TEXT NOT NULL,
    status         tournament_status NOT NULL DEFAULT 'scheduled',
    entry_fee_msat BIGINT NOT NULL CHECK (entry_fee_msat >= 0),
    -- The ledger account holding this tournament's pool.
    pool_account_id BIGINT NOT NULL REFERENCES accounts(id),
    -- Prize split as basis points per finishing position, highest first.
    -- e.g. {5000,3000,2000} pays 50/30/20 to the top three.
    payout_bp      INTEGER[] NOT NULL,
    max_entrants   INTEGER,
    registers_at   TIMESTAMPTZ NOT NULL,
    starts_at      TIMESTAMPTZ NOT NULL,
    ends_at        TIMESTAMPTZ NOT NULL,
    settled_at     TIMESTAMPTZ,
    created_at     TIMESTAMPTZ NOT NULL DEFAULT now(),
    CONSTRAINT tournament_window CHECK (registers_at <= starts_at AND starts_at < ends_at)
);

CREATE INDEX tournaments_status_idx ON tournaments (status, starts_at);

CREATE TABLE tournament_entries (
    id            BIGSERIAL PRIMARY KEY,
    tournament_id BIGINT NOT NULL REFERENCES tournaments(id),
    account_id    BIGINT NOT NULL REFERENCES accounts(id),
    -- Score is net profit in millisatoshis across the tournament window.
    -- It may be negative; a losing player still has a standing.
    score_msat    BIGINT NOT NULL DEFAULT 0,
    rounds_played INTEGER NOT NULL DEFAULT 0,
    prize_msat    BIGINT NOT NULL DEFAULT 0 CHECK (prize_msat >= 0),
    entered_at    TIMESTAMPTZ NOT NULL DEFAULT now(),
    UNIQUE (tournament_id, account_id)
);

CREATE INDEX tournament_entries_board_idx
    ON tournament_entries (tournament_id, score_msat DESC);

-- Deliberately NOT append-only. An entry row is a seat reservation; a seat
-- claimed but not paid for must be releasable so the player can retry once
-- funded. The money side is a ledger posting and remains immutable.
