import React, { createContext, useCallback, useContext, useEffect, useState } from "react";
import { translations, TranslationKey, UiLanguage } from "./translations";
import { api } from "../api";

type TranslationParams = Record<string, string | number>;

type Ctx = {
  language: UiLanguage;
  setLanguage: (l: UiLanguage) => void;
  hydrateLanguage: (language?: string | null) => void;
  t: (key: TranslationKey, params?: TranslationParams) => string;
};

const I18nContext = createContext<Ctx | null>(null);

function interpolate(template: string, params?: TranslationParams) {
  if (!params) return template;
  return template.replace(/\{(\w+)\}/g, (_, key) => String(params[key] ?? `{${key}}`));
}

export function I18nProvider({ children }: { children: React.ReactNode }) {
  const [language, setLanguageState] = useState<UiLanguage>(() => {
    const raw = window.localStorage.getItem("uiLanguage");
    return raw === "nb" || raw === "nb-NO" || raw === "no" ? "nb" : "en";
  });

  const applyLanguage = useCallback((l: UiLanguage) => {
    setLanguageState(l);
    window.localStorage.setItem("uiLanguage", l);
    document.documentElement.lang = l === "nb" ? "nb-NO" : "en";
  }, []);

  const setLanguage = (l: UiLanguage) => {
    applyLanguage(l);
    void api.put("/auth/preferences/language", { language: l === "nb" ? "nb-NO" : "en" }).catch(() => undefined);
  };

  const hydrateLanguage = useCallback((value?: string | null) => {
    if (!value) return;
    applyLanguage(value === "nb" || value === "nb-NO" || value === "no" ? "nb" : "en");
  }, [applyLanguage]);

  useEffect(() => {
    document.documentElement.lang = language === "nb" ? "nb-NO" : "en";
    const onStorage = (event: StorageEvent) => {
      if (event.key !== "uiLanguage") return;
      applyLanguage(event.newValue === "nb" || event.newValue === "nb-NO" || event.newValue === "no" ? "nb" : "en");
    };
    window.addEventListener("storage", onStorage);
    return () => window.removeEventListener("storage", onStorage);
  }, [applyLanguage, language]);

  const t = (key: TranslationKey, params?: TranslationParams) => interpolate(translations[language][key] ?? translations.en[key], params);

  return <I18nContext.Provider value={{ language, setLanguage, hydrateLanguage, t }}>{children}</I18nContext.Provider>;
}

export function useI18n() {
  const ctx = useContext(I18nContext);
  if (!ctx) throw new Error("useI18n must be used within I18nProvider");
  return ctx;
}

export function useOptionalI18n() {
  return useContext(I18nContext);
}
