import { api } from '@/lib/api/api-client' import type { AnnouncementItem, AnnouncementState, BetSelection, ConnectionState, DashboardState, GameBootstrapSnapshot, GameCell, HistoryEntry, RoundSnapshot, TrendEntry, } from '../shared' import { createMockGameBootstrapSnapshot } from '../shared' import type { AnnouncementStateDto, BetSelectionDto, ChipDto, ConnectionStateDto, DashboardStateDto, GameAnnouncementsDto, GameBootstrapDto, GameCellDto, GameRoundFeedDto, HistoryEntryDto, RoundSnapshotDto, TrendEntryDto, } from './types' export const GAME_API_ENDPOINTS = { announcements: 'game/announcements', bootstrap: 'game/bootstrap', roundFeed: 'game/round-feed', } as const function normalizeGameCell(dto: GameCellDto) { return dto satisfies GameCell } function normalizeChip(dto: ChipDto) { return { amount: dto.amount, color: dto.color, id: dto.id, isDefault: dto.is_default, label: dto.label, } } function normalizeBetSelection(dto: BetSelectionDto) { return { amount: dto.amount, cellId: dto.cell_id, chipId: dto.chip_id, id: dto.id, placedAt: dto.placed_at, source: dto.source, } satisfies BetSelection } function normalizeRoundSnapshot(dto: RoundSnapshotDto) { return { bettingClosesAt: dto.betting_closes_at, id: dto.id, phase: dto.phase, revealingAt: dto.revealing_at, settledAt: dto.settled_at, startedAt: dto.started_at, winningCellId: dto.winning_cell_id, } satisfies RoundSnapshot } function normalizeHistoryEntry(dto: HistoryEntryDto) { return { payoutMultiplier: dto.payout_multiplier, roundId: dto.round_id, settledAt: dto.settled_at, totalPoolAmount: dto.total_pool_amount, winningCellId: dto.winning_cell_id, } satisfies HistoryEntry } function normalizeTrendEntry(dto: TrendEntryDto) { return { cellId: dto.cell_id, currentStreak: dto.current_streak, direction: dto.direction, hitCount: dto.hit_count, lastHitRoundId: dto.last_hit_round_id, missCount: dto.miss_count, } satisfies TrendEntry } function normalizeAnnouncementState(dto: AnnouncementStateDto) { return { activeAnnouncementId: dto.active_announcement_id, items: dto.items.map( (item) => ({ createdAt: item.created_at, expiresAt: item.expires_at, id: item.id, isPinned: item.is_pinned, isRead: item.is_read, message: item.message, title: item.title, tone: item.tone, }) satisfies AnnouncementItem, ), lastUpdatedAt: dto.last_updated_at, } satisfies AnnouncementState } function normalizeDashboardState(dto: DashboardStateDto) { return { countdownMs: dto.countdown_ms, featuredCellId: dto.featured_cell_id, onlinePlayers: dto.online_players, tableLimitMax: dto.table_limit_max, tableLimitMin: dto.table_limit_min, totalPoolAmount: dto.total_pool_amount, updatedAt: dto.updated_at, } satisfies DashboardState } function normalizeConnectionState(dto: ConnectionStateDto) { return { connectedAt: dto.connected_at, lastError: dto.last_error, lastMessageAt: dto.last_message_at, latencyMs: dto.latency_ms, reconnectAttempt: dto.reconnect_attempt, status: dto.status, transport: dto.transport, } satisfies ConnectionState } export function normalizeGameBootstrap(dto: GameBootstrapDto) { return { announcements: normalizeAnnouncementState(dto.announcements), cells: dto.cells.map(normalizeGameCell), chips: dto.chips.map(normalizeChip), connection: normalizeConnectionState(dto.connection), dashboard: normalizeDashboardState(dto.dashboard), history: dto.history.map(normalizeHistoryEntry), round: normalizeRoundSnapshot(dto.round), selections: dto.selections.map(normalizeBetSelection), trends: dto.trends.map(normalizeTrendEntry), } satisfies GameBootstrapSnapshot } export function normalizeGameRoundFeed(dto: GameRoundFeedDto) { return { history: dto.history.map(normalizeHistoryEntry), round: normalizeRoundSnapshot(dto.round), selections: dto.selections.map(normalizeBetSelection), trends: dto.trends.map(normalizeTrendEntry), } satisfies Pick< GameBootstrapSnapshot, 'history' | 'round' | 'selections' | 'trends' > } export async function getGameBootstrap() { const response = await api.get(GAME_API_ENDPOINTS.bootstrap) return normalizeGameBootstrap(response.data) } export async function getGameRoundFeed() { const response = await api.get(GAME_API_ENDPOINTS.roundFeed) return normalizeGameRoundFeed(response.data) } export async function getGameAnnouncements() { const response = await api.get( GAME_API_ENDPOINTS.announcements, ) return normalizeAnnouncementState(response.data.announcements) } export async function getMockGameBootstrap(latencyMs = 120) { await new Promise((resolve) => { setTimeout(resolve, latencyMs) }) return createMockGameBootstrapSnapshot() }