/**
 * PrimeReact widget translations (Calendar/AutoComplete labels).
 *
 * PrimeReact ships an English default and lets apps register additional
 * locales via `addLocale(name, dictionary)` at module load. The active
 * locale is then selected per-render with `setPrimeLocale(name)`. We
 * register every supported language at boot so a locale switch in the
 * URL doesn't leave the date picker stuck on Russian.
 */

import type { Language } from "./resolver.js";

interface PrimeLocaleDict {
  dayNames: string[];
  dayNamesShort: string[];
  dayNamesMin: string[];
  monthNames: string[];
  monthNamesShort: string[];
  today: string;
  clear: string;
  chooseDate: string;
  prevDecade: string;
  nextDecade: string;
  prevYear: string;
  nextYear: string;
  prevMonth: string;
  nextMonth: string;
  chooseYear: string;
  chooseMonth: string;
  weekHeader: string;
  firstDayOfWeek: number;
  emptyMessage: string;
  emptyFilterMessage: string;
}

const RU: PrimeLocaleDict = {
  dayNames: ["воскресенье", "понедельник", "вторник", "среда", "четверг", "пятница", "суббота"],
  dayNamesShort: ["вс", "пн", "вт", "ср", "чт", "пт", "сб"],
  dayNamesMin: ["вс", "пн", "вт", "ср", "чт", "пт", "сб"],
  monthNames: ["январь", "февраль", "март", "апрель", "май", "июнь", "июль", "август", "сентябрь", "октябрь", "ноябрь", "декабрь"],
  monthNamesShort: ["янв", "фев", "мар", "апр", "май", "июн", "июл", "авг", "сен", "окт", "ноя", "дек"],
  today: "Сегодня",
  clear: "Очистить",
  chooseDate: "Выбрать дату",
  prevDecade: "Предыдущее десятилетие",
  nextDecade: "Следующее десятилетие",
  prevYear: "Предыдущий год",
  nextYear: "Следующий год",
  prevMonth: "Предыдущий месяц",
  nextMonth: "Следующий месяц",
  chooseYear: "Выбрать год",
  chooseMonth: "Выбрать месяц",
  weekHeader: "Нед",
  firstDayOfWeek: 1,
  emptyMessage: "Совпадений не найдено",
  emptyFilterMessage: "Совпадений не найдено",
};

const EN: PrimeLocaleDict = {
  dayNames: ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"],
  dayNamesShort: ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"],
  dayNamesMin: ["Su", "Mo", "Tu", "We", "Th", "Fr", "Sa"],
  monthNames: ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"],
  monthNamesShort: ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"],
  today: "Today",
  clear: "Clear",
  chooseDate: "Choose date",
  prevDecade: "Previous decade",
  nextDecade: "Next decade",
  prevYear: "Previous year",
  nextYear: "Next year",
  prevMonth: "Previous month",
  nextMonth: "Next month",
  chooseYear: "Choose year",
  chooseMonth: "Choose month",
  weekHeader: "Wk",
  firstDayOfWeek: 1,
  emptyMessage: "No results found",
  emptyFilterMessage: "No results found",
};

/**
 * Build a locale dict by deferring weekday/month names to Intl.
 * Less polish than a hand-curated dict but means the calendar is
 * never untranslated when we add a new language file.
 */
function buildIntlLocale(lang: Language): PrimeLocaleDict {
  const localeTag = `${lang}-${lang.toUpperCase()}`;
  const weekdayLong = new Intl.DateTimeFormat(localeTag, { weekday: "long" });
  const weekdayShort = new Intl.DateTimeFormat(localeTag, { weekday: "short" });
  const monthLong = new Intl.DateTimeFormat(localeTag, { month: "long" });
  const monthShort = new Intl.DateTimeFormat(localeTag, { month: "short" });

  // Build day arrays: 0=Sunday … 6=Saturday. Use a known Sunday.
  const daySeed = new Date(Date.UTC(2024, 0, 7)); // Sunday 2024-01-07
  const dayNames: string[] = [];
  const dayNamesShort: string[] = [];
  for (let i = 0; i < 7; i++) {
    const d = new Date(daySeed);
    d.setUTCDate(daySeed.getUTCDate() + i);
    dayNames.push(weekdayLong.format(d));
    dayNamesShort.push(weekdayShort.format(d));
  }

  const monthNames: string[] = [];
  const monthNamesShort: string[] = [];
  for (let m = 0; m < 12; m++) {
    const d = new Date(Date.UTC(2024, m, 1));
    monthNames.push(monthLong.format(d));
    monthNamesShort.push(monthShort.format(d));
  }

  return {
    dayNames,
    dayNamesShort,
    dayNamesMin: dayNamesShort.map((n) => n.slice(0, 2)),
    monthNames,
    monthNamesShort,
    today: EN.today,
    clear: EN.clear,
    chooseDate: EN.chooseDate,
    prevDecade: EN.prevDecade,
    nextDecade: EN.nextDecade,
    prevYear: EN.prevYear,
    nextYear: EN.nextYear,
    prevMonth: EN.prevMonth,
    nextMonth: EN.nextMonth,
    chooseYear: EN.chooseYear,
    chooseMonth: EN.chooseMonth,
    weekHeader: EN.weekHeader,
    firstDayOfWeek: 1,
    emptyMessage: EN.emptyMessage,
    emptyFilterMessage: EN.emptyFilterMessage,
  };
}

const REGISTERED: Partial<Record<Language, PrimeLocaleDict>> = {
  ru: RU,
  en: EN,
};

/**
 * The canonical PrimeReact-locale name we'll switch to for a given
 * app language. Any language not in REGISTERED falls back to a
 * just-in-time Intl-built dict (keyed by language code).
 */
export function primeLocaleNameFor(lang: Language): string {
  return lang;
}

/**
 * Register all supported PrimeReact locale dicts at boot.
 * `addLocale` is the PrimeReact API: `(name: string, dict) => void`.
 */
export function registerPrimeLocales(
  addLocale: (name: string, dict: PrimeLocaleDict) => void,
): void {
  const langs: Language[] = ["ru", "en", "es", "fr", "it", "ja", "ko", "zh", "de"];
  for (const lang of langs) {
    const dict = REGISTERED[lang] ?? buildIntlLocale(lang);
    addLocale(lang, dict);
  }
}
