import type { ModelType, PredictionClass } from "../context/AnalysisContext"; export interface ConfidenceScores { Healthy: number; MCI: number; AD: number; } export interface FoldPrediction { fold: number; prediction: PredictionClass; confidence: number; confidence_scores: ConfidenceScores; } export interface AnalyzeResponse { id: string; file_name: string; model: Exclude; prediction: PredictionClass; confidence: number; confidence_scores: ConfidenceScores; processed_at: string; spectrogram_image: string | null; scalogram_montage_image: string | null; spectrogram_channels: (string | null)[]; scalogram_channels: (string | null)[]; channel_0_image: string | null; channel_1_image: string | null; mock: boolean; fold_predictions: FoldPrediction[]; fold_vote_counts: Partial>; ensemble_folds: number; ensemble_mode: string; } export interface TrialAnalysisResult { id: string; file_name: string; trial_no: number | null; prediction: PredictionClass; confidence: number; confidence_scores: ConfidenceScores; spectrogram_image: string | null; scalogram_montage_image: string | null; spectrogram_channels: (string | null)[]; scalogram_channels: (string | null)[]; mock: boolean; fold_predictions: FoldPrediction[]; fold_vote_counts: Partial>; ensemble_folds: number; ensemble_mode: string; } export interface PatientAnalyzeResponse { id: string; patient_id: string; model: Exclude; prediction: PredictionClass; confidence: number; confidence_scores: ConfidenceScores; vote_counts: Partial>; trial_count: number; agreement_ratio: number; processed_at: string; trial_results: TrialAnalysisResult[]; mock: boolean; } const API_BASE = import.meta.env.VITE_API_URL ?? ""; export class AnalysisApiError extends Error { constructor( message: string, public status?: number, ) { super(message); this.name = "AnalysisApiError"; } } export async function analyzeEeg(file: File, model: Exclude): Promise { const formData = new FormData(); formData.append("file", file); formData.append("model", model); const response = await fetch(`${API_BASE}/api/analyze`, { method: "POST", body: formData, }); if (!response.ok) { let detail = "Analysis request failed."; try { const body = await response.json(); if (typeof body.detail === "string") { detail = body.detail; } else if (Array.isArray(body.detail)) { detail = body.detail.map((d: { msg?: string }) => d.msg).filter(Boolean).join(", ") || detail; } } catch { if (response.status === 500) { detail = "Server error — ensure the backend is running and USE_MOCK_INFERENCE=true in backend/.env"; } } throw new AnalysisApiError(detail, response.status); } return response.json(); } export async function analyzePatientEeg( files: File[], model: Exclude, ): Promise { const formData = new FormData(); files.forEach((file) => formData.append("files", file)); formData.append("model", model); const response = await fetch(`${API_BASE}/api/analyze/patient`, { method: "POST", body: formData, }); if (!response.ok) { let detail = "Patient analysis request failed."; try { const body = await response.json(); if (typeof body.detail === "string") { detail = body.detail; } else if (Array.isArray(body.detail)) { detail = body.detail.map((d: { msg?: string }) => d.msg).filter(Boolean).join(", ") || detail; } } catch { if (response.status === 404) { detail = "Patient endpoint not found — restart the backend (npm run dev:backend)."; } else if (response.status === 500) { detail = "Server error — restart the backend and try again."; } } throw new AnalysisApiError(detail, response.status); } return response.json(); } export async function checkApiHealth(): Promise { try { const response = await fetch(`${API_BASE}/api/health`); return response.ok; } catch { return false; } } export interface ModelStatusItem { name: Exclude; loaded: boolean; weights_found: boolean; weights_path: string; } export interface ModelsStatusResponse { models: ModelStatusItem[]; use_mock_inference: boolean; fusion_detail: Record | null; } export async function fetchModelsStatus(): Promise { try { const response = await fetch(`${API_BASE}/api/models/status`); if (!response.ok) return null; return response.json(); } catch { return null; } }