import i18next, { type i18n as I18nInstance, type Resource } from 'i18next';
import { initReactI18next } from 'react-i18next';

import { resources } from './resources.js';
import { DEFAULT_LOCALE, type SupportedLocale } from './types.js';

export * from './detect.js';
export * from './error-map.js';
export * from './types.js';

export interface InitI18nOptions {
  initialLocale: SupportedLocale;
  // Called whenever the active language changes.
  onLanguageChanged?: (locale: SupportedLocale) => void;
}

// Idempotent init — safe to call from multiple entry points.
// Returns the configured i18next instance.
export function initI18n(options: InitI18nOptions): I18nInstance {
  if (!i18next.isInitialized) {
    void i18next.use(initReactI18next).init({
      resources: resources as unknown as Resource,
      lng: options.initialLocale,
      fallbackLng: DEFAULT_LOCALE,
      defaultNS: 'common',
      ns: ['common', 'auth', 'errors', 'app'],
      interpolation: { escapeValue: false },
      returnNull: false,
    });
  } else if (i18next.language !== options.initialLocale) {
    void i18next.changeLanguage(options.initialLocale);
  }

  if (options.onLanguageChanged) {
    i18next.off('languageChanged');
    i18next.on('languageChanged', (lng: string) => {
      if (isSupportedLocale(lng)) {
        options.onLanguageChanged?.(lng);
      }
    });
  }

  return i18next;
}

export function changeLocale(locale: SupportedLocale): Promise<unknown> {
  return i18next.changeLanguage(locale);
}

export { i18next };

// Local type guard (detect.ts exports this too; re-declared here to keep this
// file free of cyclic references).
function isSupportedLocale(value: string): value is SupportedLocale {
  return value === 'en' || value === 'de';
}
