import { useState, useEffect } from "react";
import { useNavigate, useParams } from "@modern-js/runtime/router";
import { Outlet } from "@modern-js/runtime/router";
import { addLocale, locale as setPrimeLocale } from "primereact/api";
import {
  normalizeLocaleParam,
  localeToLanguage,
  type LocaleCode,
} from "@/i18n/resolver";
import { createI18nInstance } from "@/i18n/config";
import { I18nProvider } from "@/i18n/provider";
import { useApiClient } from "@/shared/api/provider";
import { registerPrimeLocales, primeLocaleNameFor } from "@/i18n/primeLocales";
import { ErrorPage } from "@/ui/errors/ErrorPage.js";
import type i18next from "i18next";

// Register all PrimeReact locales once at module load. The active
// locale is selected per-render via setPrimeLocale() so that switching
// between /ru-ru and /en-en swaps Calendar/AutoComplete labels too.
registerPrimeLocales(addLocale);

/**
 * Locale-scoped layout. Validates the `lang` URL segment (BCP-47:
 * `ru-ru`, `en-en`, …; legacy short codes like `ru` are auto-promoted
 * to their canonical BCP-47 cousin), creates an i18n instance for
 * the matching language file, and updates the shared ApiClient's
 * locale so backend responses come back in the right language.
 */
export default function LangLayout(): JSX.Element {
  const params = useParams<{ lang: string }>();
  const navigate = useNavigate();
  const rawLang = params.lang ?? "";
  const locale: LocaleCode | null = normalizeLocaleParam(rawLang);
  const language = locale ? localeToLanguage(locale) : null;
  const apiClient = useApiClient();

  const [i18n, setI18n] = useState<typeof i18next | null>(null);

  // Auto-promote a bare short code in the URL (`/ru/...`) to its
  // canonical BCP-47 form (`/ru-ru/...`) — Angular's URL contract.
  useEffect(() => {
    if (!locale) return;
    if (rawLang.toLowerCase() !== locale) {
      const newPath = `/${locale}${window.location.pathname.slice(`/${rawLang}`.length)}${window.location.search}${window.location.hash}`;
      navigate(newPath, { replace: true });
    }
  }, [locale, rawLang, navigate]);

  useEffect(() => {
    if (!locale || !language) return;
    let cancelled = false;
    apiClient.locale = language;
    setPrimeLocale(primeLocaleNameFor(language));
    void createI18nInstance({ locale: language }).then((instance) => {
      if (!cancelled) {
        setI18n(instance);
      }
    });
    return () => {
      cancelled = true;
    };
  }, [locale, language, apiClient]);

  // Unknown locale → branded 404 instead of the framework's default
  // "404" text; matches the `/error/404` route rendering.
  if (!locale) {
    return <ErrorPage code="404" />;
  }

  if (!i18n) {
    return <div>Loading translations...</div>;
  }

  return (
    <I18nProvider i18n={i18n}>
      <Outlet />
    </I18nProvider>
  );
}
