import { normalizeHydroStation, normalizeSynopStation, normalizeWarning, } from "@/lib/weather-utils"; import type { HydroStation, MeteoStationPosition, RawHydroStation, RawMeteoStation, RawSynopStation, RawWarning, SynopStation, WeatherWarning, WarningKind, } from "@/types/imgw"; async function getJson(path: string, signal?: AbortSignal): Promise { const response = await fetch(`/api/imgw/${path}`, { signal }); if (!response.ok) { const details = await response.text().catch(() => ""); throw new Error(details || `IMGW API zwróciło status ${response.status}.`); } return response.json() as Promise; } export async function fetchSynopStations(signal?: AbortSignal): Promise { const rows = await getJson("synop", signal); return rows.map(normalizeSynopStation).filter((station): station is SynopStation => station !== null); } export async function fetchSynopStation(id: string, signal?: AbortSignal): Promise { const row = await getJson(`synop/id/${encodeURIComponent(id)}`, signal); const station = normalizeSynopStation(row); if (!station) throw new Error("IMGW zwróciło niekompletne dane stacji."); return station; } export async function fetchHydroStations(signal?: AbortSignal): Promise { const rows = await getJson("hydro", signal); return rows.map(normalizeHydroStation).filter((station): station is HydroStation => station !== null); } export async function fetchMeteoStationPositions(signal?: AbortSignal): Promise { const rows = await getJson("meteo", signal); return rows.flatMap((row) => { const latitude = Number(row.lat); const longitude = Number(row.lon); if (!row.nazwa_stacji?.trim() || !Number.isFinite(latitude) || !Number.isFinite(longitude)) return []; return [{ name: row.nazwa_stacji, latitude, longitude }]; }); } async function fetchWarningsByKind(kind: WarningKind, signal?: AbortSignal): Promise { const rows = await getJson(kind === "meteo" ? "warningsmeteo" : "warningshydro", signal); return Array.isArray(rows) ? rows.map((warning, index) => normalizeWarning(warning, kind, index)) : []; } export async function fetchWarnings(signal?: AbortSignal): Promise { const results = await Promise.allSettled([ fetchWarningsByKind("meteo", signal), fetchWarningsByKind("hydro", signal), ]); const warnings = results.flatMap((result) => result.status === "fulfilled" ? result.value : []); if (results.every((result) => result.status === "rejected")) { throw new Error("Nie udało się pobrać ostrzeżeń IMGW."); } return warnings.sort((a, b) => (b.publishedAt ?? "").localeCompare(a.publishedAt ?? "")); }