import { DEFAULT_CHIP_AMOUNTS } from '@/constants' import { DEFAULT_ACTIVE_CHIP_ID, DEFAULT_ANNOUNCEMENT_TTL_MS, DEFAULT_GAME_CHIP_COLORS, GAME_GRID_COLUMNS, GAME_MAX_SELECTION_CELLS, GAME_TOTAL_CELLS, } from './constants' import { deriveTrendEntries, getRoundCountdownMs } from './selectors' import type { AnnouncementState, BetSelection, Chip, ConnectionState, DashboardState, GameBootstrapSnapshot, GameCell, HistoryEntry, RoundSnapshot, } from './types' const MOCK_GAME_BASE_TIME = '2026-04-23T12:00:00.000Z' const MOCK_HISTORY_RESULTS = [8, 12, 12, 4, 31, 9, 17, 22, 17, 5, 28, 13] function offsetIso(baseIso: string, offsetMs: number) { return new Date(Date.parse(baseIso) + offsetMs).toISOString() } export function createGameCells() { return Array.from({ length: GAME_TOTAL_CELLS }, (_, index) => { const id = index + 1 return { column: (index % GAME_GRID_COLUMNS) + 1, id, label: String(id).padStart(2, '0'), odds: 36, row: Math.floor(index / GAME_GRID_COLUMNS) + 1, } satisfies GameCell }) } export function createDefaultChips() { return DEFAULT_CHIP_AMOUNTS.map((chip, index) => ({ amount: chip.amount, color: DEFAULT_GAME_CHIP_COLORS[index], id: chip.id, isDefault: chip.id === DEFAULT_ACTIVE_CHIP_ID, label: chip.amount >= 100 ? `${chip.amount / 100}x` : String(chip.amount), })) satisfies Chip[] } export function createMockHistoryEntries(baseIso = MOCK_GAME_BASE_TIME) { return MOCK_HISTORY_RESULTS.map((winningCellId, index) => { const settledAt = offsetIso(baseIso, -(index + 1) * 30_000) return { payoutMultiplier: 36, roundId: `round-${6200 - index}`, settledAt, totalPoolAmount: 12_000 + index * 850, winningCellId, } satisfies HistoryEntry }) } export function createMockRoundSnapshot(baseIso = MOCK_GAME_BASE_TIME) { return { bettingClosesAt: offsetIso(baseIso, 18_000), id: 'round-6201', phase: 'betting', revealingAt: offsetIso(baseIso, 24_000), settledAt: offsetIso(baseIso, 30_000), startedAt: baseIso, winningCellId: null, } satisfies RoundSnapshot } export function createMockBetSelections() { return [] satisfies BetSelection[] } export function createMockAnnouncementState(baseIso = MOCK_GAME_BASE_TIME) { return { activeAnnouncementId: 'announcement-maintenance', items: [ { createdAt: offsetIso(baseIso, -20_000), expiresAt: offsetIso(baseIso, DEFAULT_ANNOUNCEMENT_TTL_MS), id: 'announcement-maintenance', isPinned: true, isRead: false, message: 'Realtime sync upgrades finish after the current cycle.', title: 'Table maintenance', tone: 'warning', }, { createdAt: offsetIso(baseIso, -55_000), expiresAt: null, id: 'announcement-promo', isRead: true, message: 'Warm-up round rebates are credited every 5 settled rounds.', title: 'Reward window live', tone: 'success', }, ], lastUpdatedAt: offsetIso(baseIso, -10_000), } satisfies AnnouncementState } export function createMockDashboardState( baseIso = MOCK_GAME_BASE_TIME, round = createMockRoundSnapshot(baseIso), history = createMockHistoryEntries(baseIso), ) { return { countdownMs: getRoundCountdownMs(round, baseIso), featuredCellId: history[0]?.winningCellId ?? null, onlinePlayers: 1_284, tableLimitMax: 5_000, tableLimitMin: 10, totalPoolAmount: 84_300, updatedAt: baseIso, } satisfies DashboardState } export function createMockConnectionState(baseIso = MOCK_GAME_BASE_TIME) { return { connectedAt: offsetIso(baseIso, -180_000), lastError: null, lastMessageAt: offsetIso(baseIso, -500), latencyMs: 48, reconnectAttempt: 0, status: 'connected', transport: 'websocket', } satisfies ConnectionState } export function createMockGameBootstrapSnapshot(baseIso = MOCK_GAME_BASE_TIME) { const cells = createGameCells() const chips = createDefaultChips() const history = createMockHistoryEntries(baseIso) const round = createMockRoundSnapshot(baseIso) return { announcements: createMockAnnouncementState(baseIso), cells, chips, connection: createMockConnectionState(baseIso), dashboard: createMockDashboardState(baseIso, round, history), history, maxSelectionCount: GAME_MAX_SELECTION_CELLS, round, selections: createMockBetSelections(), trends: deriveTrendEntries(history), } satisfies GameBootstrapSnapshot }