import { TguApiError, type TguPlan, type TguPlanDecision, type TguPlanDecisionMessage, type TguPlatform } from "../model/tguTypes"; export type FlightLinePoint = { time: string; revolution: number; lat: number; long: number; latLeft: number; longLeft: number; latInnerLeft: number; longInnerLeft: number; latInnerRight: number; longInnerRight: number; latRight: number; longRight: number; revSign: "ASC" | "DESC"; }; export async function fetchFlightLine( noradId: string, fromMs: number, toMs: number ): Promise { const toLocalDT = (ms: number) => new Date(ms).toISOString().slice(0, 19); const query = new URLSearchParams({ time_start: toLocalDT(fromMs), time_stop: toLocalDT(toMs) }); return fetchJson( `/api/tgu-planning/spacecraft/${encodeURIComponent(noradId)}/flight-line?${query}` ); } export async function fetchPlatforms(): Promise { return fetchJson("/api/tgu-planning/platforms"); } export async function fetchPlans(historyDays: number, spacecraftId?: string): Promise { const query = new URLSearchParams({ historyDays: String(historyDays) }); const path = spacecraftId ? `/api/tgu-planning/spacecraft/${encodeURIComponent(spacecraftId)}/plans?${query}` : `/api/tgu-planning/plans?${query}`; return fetchJson(path); } export async function sendPlanDecision( planId: string, decision: TguPlanDecision, reason?: string ): Promise { const query = new URLSearchParams({ decision }); if (reason?.trim()) { query.set("reason", reason.trim()); } return fetchJson( `/api/tgu-planning/plans/${encodeURIComponent(planId)}/decision?${query}`, { method: "POST" }, true ); } async function fetchJson(url: string, init?: RequestInit, decisionRequest = false): Promise { let response: Response; try { response = await fetch(url, { headers: { Accept: "application/json" }, ...init }); } catch (error) { throw new TguApiError("Не удалось подключиться к backend API.", "network"); } const text = await response.text(); if (!response.ok) { throw new TguApiError(errorMessage(response.status, text, decisionRequest), "http", response.status); } if (!text.trim()) { return undefined as T; } return JSON.parse(text) as T; } function errorMessage(status: number, body: string, decisionRequest: boolean): string { if (decisionRequest && status === 404) { return "План не найден."; } if (decisionRequest && status === 409) { return "План не является активным планом, ожидающим решения, или для него нет active attempt."; } if (decisionRequest && status >= 500) { return "Ошибка сервиса при отправке решения."; } return extractErrorText(body) || "Ошибка backend API."; } function extractErrorText(body: string): string { const trimmed = body.trim(); if (!trimmed) return ""; try { const parsed = JSON.parse(trimmed) as Record; for (const field of ["reason", "message", "error", "detail"]) { const value = parsed[field]; if (typeof value === "string" && value.trim()) { return value; } } } catch { return trimmed; } return trimmed; }