/**
 * i18n via i18next (i18n-spec §5, §7–8; M4 – beslut D-023, D-031).
 *
 * SPRÅKPOLICY (D-031):
 * 1. Första start utan sparat val → enhetens språk om det stöds
 *    (spanjoren som laddar ner appen får spanska direkt).
 * 2. Stöds inte enhetens språk → engelska (internationell fallback),
 *    svenska är alltid sista fallback för saknade nycklar.
 * 3. Manuellt val i profilen vinner ALLTID över enhetens språk och synkas
 *    till backend (mejl, notiser och innehåll följer samma val) –
 *    spanjoren i Sverige kan köra spanska, svensken i Spanien svenska.
 *
 * Nytt språk = en JSON-fil + rad i SUPPORTED_LANGUAGES + seed-rader för
 * enheter/ingredienser. Paritet vaktas av test (alla filer, samma nycklar).
 */
import i18next from "i18next";
import { create } from "zustand";
import { BRAND } from "./brand";
import sv from "../locales/sv/common.json";
import en from "../locales/en/common.json";
import es from "../locales/es/common.json";
import it from "../locales/it/common.json";
import de from "../locales/de/common.json";
import fr from "../locales/fr/common.json";
import da from "../locales/da/common.json";
import nb from "../locales/nb/common.json";
import fi from "../locales/fi/common.json";
import nl from "../locales/nl/common.json";
import pl from "../locales/pl/common.json";
import pt from "../locales/pt/common.json";

export type TranslationKey = string;

/** Stödda språk – renderar språkväljaren och styr detekteringen. */
export const SUPPORTED_LANGUAGES = [
  { code: "sv", tag: "sv-SE", labelKey: "profile.language.sv" },
  { code: "en", tag: "en-US", labelKey: "profile.language.en" },
  { code: "es", tag: "es-ES", labelKey: "profile.language.es" },
  { code: "it", tag: "it-IT", labelKey: "profile.language.it" },
  { code: "de", tag: "de-DE", labelKey: "profile.language.de" },
  { code: "fr", tag: "fr-FR", labelKey: "profile.language.fr" },
  { code: "da", tag: "da-DK", labelKey: "profile.language.da" },
  { code: "nb", tag: "nb-NO", labelKey: "profile.language.nb" },
  { code: "fi", tag: "fi-FI", labelKey: "profile.language.fi" },
  { code: "nl", tag: "nl-NL", labelKey: "profile.language.nl" },
  { code: "pl", tag: "pl-PL", labelKey: "profile.language.pl" },
  { code: "pt", tag: "pt-PT", labelKey: "profile.language.pt" },
] as const;

const SUPPORTED_CODES = new Set<string>(SUPPORTED_LANGUAGES.map((l) => l.code));

void i18next.init({
  lng: "sv",
  fallbackLng: "sv",
  resources: {
    sv: { common: sv },
    en: { common: en },
    es: { common: es },
    it: { common: it },
    de: { common: de },
    fr: { common: fr },
    da: { common: da },
    nb: { common: nb },
    fi: { common: fi },
    nl: { common: nl },
    pl: { common: pl },
    pt: { common: pt },
  },
  defaultNS: "common",
  // Platta nycklar – "home.title" är EN nyckel, inte nästling.
  keySeparator: false,
  nsSeparator: false,
  interpolation: {
    prefix: "{",
    suffix: "}",
    escapeValue: false,
    defaultVariables: { brand: BRAND.name },
  },
  returnNull: false,
  initAsync: false, // synkron init – resurserna är bundlade
});

interface I18nState {
  version: number;
  languageTag: string;
  bump: (languageTag: string) => void;
}
const useI18nStore = create<I18nState>((set) => ({
  version: 0,
  languageTag: "sv-SE",
  bump: (languageTag) => set((s) => ({ version: s.version + 1, languageTag })),
}));

/** Rotlayouten läser denna och re-monterar trädet vid språkbyte. */
export function useI18nVersion(): number {
  return useI18nStore((s) => s.version);
}

/** Byt språk utifrån BCP 47-tagg ("es-MX" -> resurser "es", Intl "es-MX"). */
export function setLocale(languageTag: string): void {
  const primary = languageTag.split("-")[0] ?? "sv";
  const lng = SUPPORTED_CODES.has(primary) ? primary : "sv";
  void i18next.changeLanguage(lng);
  useI18nStore.getState().bump(lng === primary ? languageTag : "sv-SE");
}

/** Full BCP 47-tagg för Intl-formattering (pengar, datum, tal). */
export function getLanguageTag(): string {
  return useI18nStore.getState().languageTag;
}

/**
 * Enhetens språk vid FÖRSTA start (D-031 steg 1–2): stött språk vinner,
 * annars engelska. expo-localization saknas i testmiljö → null och sv-default.
 */
export function detectDeviceLanguageTag(): string | null {
  try {
    // eslint-disable-next-line @typescript-eslint/no-require-imports
    const Localization = require("expo-localization") as {
      getLocales(): { languageTag: string; languageCode: string | null }[];
    };
    const locales = Localization.getLocales();
    for (const locale of locales) {
      const code =
        locale.languageCode === "no" || locale.languageCode === "nn"
          ? "nb" // norska varianter -> bokmål
          : locale.languageCode;
      if (code && SUPPORTED_CODES.has(code)) {
        return code === locale.languageCode ? locale.languageTag : "nb-NO";
      }
    }
    return locales.length > 0 ? "en-US" : null;
  } catch {
    return null;
  }
}

/**
 * Översätt. Plural: skicka `count` (i18next väljer _one/_other via
 * Intl.PluralRules). Alla {var} interpoleras; {brand} finns alltid.
 */
export function t(key: TranslationKey, params?: Record<string, string | number>): string {
  return i18next.t(key, params);
}
