import { expect, test } from "bun:test";
import {
  createPresenceEvent,
  createRealtimeMessage,
  createTypingEvent,
  parseRealtimeMessage,
  roomMemberSummary,
  roomQuery,
} from "../src/index.ts";

test("creates and parses typed realtime messages", () => {
  const message = createRealtimeMessage({
    id: "message-1",
    type: "message",
    room: "support/general",
    data: { text: "Hi" },
    sentAt: "2026-01-01T00:00:00.000Z",
  });
  expect(parseRealtimeMessage(JSON.stringify(message), { room: "support/general" })).toEqual(
    message,
  );
});

test("builds presence and typing events", () => {
  expect(createPresenceEvent("join", { userId: "u1" }).type).toBe("presence");
  expect(createTypingEvent("u1", true).data.typing).toBe(true);
});

test("summarizes room members and query parameters", () => {
  expect(
    roomMemberSummary([
      { userId: "1", status: "online" },
      { userId: "2", status: "away" },
    ]),
  ).toEqual({ total: 2, online: 1, away: 1, busy: 0 });
  expect(roomQuery({ user: "u1", page: 2, active: true })).toBe("user=u1&page=2&active=true");
});

test("rejects oversized, unsafe, mismatched, and unknown messages", () => {
  const message = createRealtimeMessage({
    id: "message-2",
    type: "message",
    room: "support",
    data: { text: "Hi" },
  });
  expect(() =>
    parseRealtimeMessage(JSON.stringify(message), { allowedTypes: ["presence"] }),
  ).toThrow("not allowed");
  expect(() => parseRealtimeMessage(JSON.stringify(message), { room: "other" })).toThrow(
    "does not match",
  );
  expect(() => parseRealtimeMessage(JSON.stringify(message), { maxBytes: 16 })).toThrow(
    "maximum size",
  );
  expect(() => roomQuery({ "bad key": "x" })).toThrow("query key");
});
