import type { DashboardSnapshot, VideoStatus } from '@/types' const envBaseUrl = import.meta.env.VITE_API_BASE_URL as string | undefined export const API_BASE = (envBaseUrl?.trim() || 'http://127.0.0.1:8001').replace(/\/$/, '') async function fetchJson(path: string): Promise { const response = await fetch(`${API_BASE}${path}`) if (!response.ok) { throw new Error(`请求失败: ${response.status} ${response.statusText}`) } return response.json() as Promise } export function fetchDashboardSnapshot() { return fetchJson('/api/dashboard/') } export function fetchVideoStatus() { return fetchJson('/api/video/status/') } export async function fetchClockCalibrationSample() { const response = await fetch(`${API_BASE}/api/clock/calibrate/`, { cache: 'no-store', }) if (!response.ok) { throw new Error(`clock calibration failed: ${response.status} ${response.statusText}`) } return response.json() as Promise<{ server_received_unix_ms: number server_sent_unix_ms: number }> } export function buildVideoFrameUrl(frameKey: number) { return `${API_BASE}/api/video/frame/?frame=${frameKey}&t=${Date.now()}` } export async function postVideoDisplayProbe(payload: Record) { const response = await fetch(`${API_BASE}/api/video/display-probe/`, { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify(payload), }) if (!response.ok) { throw new Error(`display probe post failed: ${response.status} ${response.statusText}`) } } export function buildControlWebSocketUrl() { const url = new URL(API_BASE, window.location.origin) const basePath = url.pathname.replace(/\/$/, '') url.protocol = url.protocol === 'https:' ? 'wss:' : 'ws:' url.pathname = `${basePath}/ws/control/` url.search = '' url.hash = '' return url.toString() }