/**
 * Locale codes used in URLs vs the short language code used for i18n
 * file lookup, API path segment, and `Accept-Language` header.
 *
 * Mirrors Angular's `LocalizationService`: URL is BCP-47 (`/ru-ru/`,
 * `/en-en/`, `/zh-zh/`...), backend + translation files use the short
 * 2-letter language part only (`ru`, `en`, `zh`...). This split keeps
 * the customer's URL contract while reusing a single set of locale
 * resources.
 */

export type Language = "ru" | "en" | "es" | "fr" | "it" | "ja" | "ko" | "zh" | "de";

export type LocaleCode =
  | "ru-ru"
  | "en-en"
  | "es-es"
  | "fr-fr"
  | "it-it"
  | "ja-ja"
  | "ko-ko"
  | "zh-zh"
  | "de-de";

export const LANGUAGES: readonly Language[] = [
  "ru", "en", "es", "fr", "it", "ja", "ko", "zh", "de",
] as const;

export const LOCALE_CODES: readonly LocaleCode[] = [
  "ru-ru", "en-en", "es-es", "fr-fr", "it-it", "ja-ja", "ko-ko", "zh-zh", "de-de",
] as const;

export const DEFAULT_LOCALE_CODE: LocaleCode = "ru-ru";
export const DEFAULT_LANGUAGE: Language = "ru";

const languageSet: ReadonlySet<string> = new Set(LANGUAGES);
const localeCodeSet: ReadonlySet<string> = new Set(LOCALE_CODES);

// Angular's URL contract is `/{country}-{language}` where the two
// halves repeat the same 2-letter language code (see
// `ClientApp/src/app/shared/services/localization.service.ts` —
// `Country = baseHref[1..3]`, `Language = baseHref[4..6]`). We mirror
// that exact shape so the React MF remote shares Angular's URL surface.
const LANGUAGE_TO_LOCALE_CODE: Record<Language, LocaleCode> = {
  ru: "ru-ru",
  en: "en-en",
  es: "es-es",
  fr: "fr-fr",
  it: "it-it",
  ja: "ja-ja",
  ko: "ko-ko",
  zh: "zh-zh",
  de: "de-de",
};

export function isLanguage(x: string): x is Language {
  return languageSet.has(x);
}

export function isLocaleCode(x: string): x is LocaleCode {
  return localeCodeSet.has(x);
}

/**
 * Extract the language part from a BCP-47 locale code.
 * `localeToLanguage("en-en")` → `"en"`.
 */
export function localeToLanguage(code: LocaleCode): Language {
  return code.slice(0, 2) as Language;
}

/**
 * Promote a short language code to its canonical URL locale code.
 * `languageToLocale("en")` → `"en-en"`. Used when the URL needs the
 * BCP-47 form but only the short language is in hand.
 */
export function languageToLocale(lang: Language): LocaleCode {
  return LANGUAGE_TO_LOCALE_CODE[lang];
}

/**
 * Read the locale code from `:lang` URL params. Accepts both BCP-47
 * (`ru-ru`) and bare short codes (`ru`) — the short form is promoted
 * to its canonical BCP-47 cousin so legacy / direct API consumers
 * keep working during migration.
 */
export function normalizeLocaleParam(raw: string | undefined): LocaleCode | null {
  if (!raw) return null;
  const lowered = raw.toLowerCase();
  if (isLocaleCode(lowered)) return lowered;
  if (isLanguage(lowered)) return languageToLocale(lowered);
  return null;
}

export function resolveLocaleFromPath(pathname: string): LocaleCode | null {
  const segments = pathname.split("/").filter(Boolean);
  return normalizeLocaleParam(segments[0]);
}

export function stripLocaleFromPath(
  pathname: string,
): { locale: LocaleCode; rest: string } | null {
  const segments = pathname.split("/").filter(Boolean);
  const first = segments[0];
  const locale = normalizeLocaleParam(first);
  if (locale === null || first === undefined) return null;

  const rest = pathname.slice(`/${first}`.length);
  return {
    locale,
    rest: rest === "" || rest === "/" ? "/" : rest,
  };
}
