📄 src/lib/labels.ts
import { readable } from "svelte/store";
import type { BirdLabel } from "./types";

const supportedLanguages = [
  "af",
  "ar",
  "cs",
  "da",
  "de",
  "en_uk",
  "en_us",
  "es",
  "fi",
  "fr",
  "hu",
  "it",
  "ja",
  "ko",
  "nl",
  "no",
  "pl",
  "pt",
  "ro",
  "ru",
  "sk",
  "sl",
  "sv",
  "th",
  "tr",
  "uk",
  "zh",
] as const;

function resolveLocale(): Array<(typeof supportedLanguages)[number]> {
  if (typeof navigator === "undefined") return ["en_us"];
  const navigatorLanguages = navigator.languages.slice(1).map((l) =>
    l.replace("-", "_").toLowerCase()
  );
  const foundLanguages = navigatorLanguages.flatMap(
    (n) => supportedLanguages.find((s) => s.startsWith(n)) ?? [],
  );
  if (!foundLanguages.includes("en_us")) {
    foundLanguages.push("en_us");
  }
  return foundLanguages;
}

async function fetchLabels(
  locale: (typeof supportedLanguages)[number],
): Promise<BirdLabel[]> {
  const res = await fetch(`/models/birdnet/labels/${locale}.json`);
  if (!res.ok) throw new Error(`HTTP ${res.status}`);
  return res.json() as Promise<BirdLabel[]>;
}

export const labelsStore = readable<BirdLabel[]>([], (set) => {
  (async () => {
    const locales = resolveLocale();
    for (const locale of locales) {
      try {
        const labels = await fetchLabels(locale);
        set(labels);
        return;
      } catch (e) {
        console.warn(e);
      }
    }
  })();
});