import React, { createContext, useCallback, useContext, useMemo, useState } from 'react';

import {
  EDITOR_LOCALE_STORAGE_KEY,
  inferEditorLocaleFromSystem,
  normalizeEditorLocale,
  translateEditorMessage,
  type EditorLocale,
} from './editorMessages';

type EditorI18nContextValue = {
  locale: EditorLocale;
  setLocale: (next: EditorLocale) => void;
  t: (key: string, vars?: Record<string, string | number>) => string;
};

const EditorI18nContext = createContext<EditorI18nContextValue | null>(null);

function readInitialLocale(): EditorLocale {
  try {
    return normalizeEditorLocale(localStorage.getItem(EDITOR_LOCALE_STORAGE_KEY));
  } catch {
    return inferEditorLocaleFromSystem();
  }
}

export function EditorI18nProvider({ children }: { children: React.ReactNode }) {
  const [locale, setLocaleState] = useState<EditorLocale>(readInitialLocale);

  const setLocale = useCallback((next: EditorLocale) => {
    setLocaleState(next);
    try {
      localStorage.setItem(EDITOR_LOCALE_STORAGE_KEY, next);
    } catch {
      // ignore
    }
  }, []);

  const t = useCallback(
    (key: string, vars?: Record<string, string | number>) => translateEditorMessage(locale, key, vars),
    [locale],
  );

  const value = useMemo<EditorI18nContextValue>(() => ({ locale, setLocale, t }), [locale, setLocale, t]);

  return <EditorI18nContext.Provider value={value}>{children}</EditorI18nContext.Provider>;
}

export function useEditorI18n(): EditorI18nContextValue {
  const ctx = useContext(EditorI18nContext);
  if (!ctx) {
    throw new Error('useEditorI18n must be used within EditorI18nProvider');
  }
  return ctx;
}
