export interface Detection {
  class_id: number;
  class_name: string;
  confidence: number;
  bbox_xyxy: number[];
}

export interface DetectionImage {
  file: string;
  annotated_file: string;
  width: number;
  height: number;
  detections: Detection[];
}

export interface DetectionRun {
  detection_count: number;
  processed_images: number;
  elapsed_seconds: number;
  device: string;
  model: string;
  confidence: number;
  input_dir: string;
  notes: string[];
}

export interface TrajectoryEvent {
  event_id: string;
  event_type: string;
  track_ids: string[];
  start_time: string;
  end_time: string;
  duration_seconds: number;
}

export interface TrajectoryRun {
  case_count: number;
  track_count: number;
  event_count: number;
  dropped_duplicate_observations: number;
  elapsed_seconds: number;
  device: string;
  input: string;
  thresholds_by_case: Record<string, Record<string, number>>;
}

export interface TrajectorySummary {
  track_id: string;
  entity_type: string;
  point_count: string;
  distance_m: string;
  average_speed_mps: string;
  behavior_labels: string;
}

export const artifactUrl = (path: string) => `/${path.replace(/\\/g, "/").split("/").map(encodeURIComponent).join("/")}`;

async function getJson<T>(path: string): Promise<T> {
  const response = await fetch(artifactUrl(path), { cache: "no-store" });
  if (!response.ok) throw new Error(`无法读取 ${path} (${response.status})`);
  return response.json() as Promise<T>;
}

async function getText(path: string): Promise<string> {
  const response = await fetch(artifactUrl(path), { cache: "no-store" });
  if (!response.ok) throw new Error(`无法读取 ${path} (${response.status})`);
  return response.text();
}

function parseCsv(text: string): TrajectorySummary[] {
  const lines = text.trim().split(/\r?\n/);
  const headers = lines.shift()?.replace(/^\uFEFF/, "").split(",") ?? [];
  return lines.filter(Boolean).map((line) => {
    const values = line.split(",");
    return Object.fromEntries(headers.map((header, index) => [header, values[index] ?? ""])) as unknown as TrajectorySummary;
  });
}

export async function loadDetectionArtifacts() {
  const [run, payload] = await Promise.all([
    getJson<DetectionRun>("shared/outputs/01-object-detection/run_metadata.json"),
    getJson<{ images: DetectionImage[] }>("shared/outputs/01-object-detection/detections.json")
  ]);
  return { run, images: payload.images };
}

export async function loadTrajectoryArtifacts() {
  const [run, difficultEvents, difficultSummary, normalSummary] = await Promise.all([
    getJson<TrajectoryRun>("shared/outputs/15-trajectory-analysis/run_metadata.json"),
    getJson<{ events: TrajectoryEvent[] }>("shared/outputs/15-trajectory-analysis/difficult/events.json"),
    getText("shared/outputs/15-trajectory-analysis/difficult/trajectory_summary.csv"),
    getText("shared/outputs/15-trajectory-analysis/normal/trajectory_summary.csv")
  ]);
  return {
    run,
    cases: {
      difficult: { events: difficultEvents.events, summary: parseCsv(difficultSummary) },
      normal: { events: [], summary: parseCsv(normalSummary) }
    }
  };
}
