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

import {
  EDITOR_LOCALE_STORAGE_KEY,
  inferEditorLocaleFromSystem,
  normalizeEditorLocale,
  translateEditorMessage,
  type EditorLocale,
} from './editorMessages';
import { getDndApi } from '../../shared/dndApi';
import { ipcChannels } from '../../../shared/ipc/contracts';

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
    }
  }, []);

  useEffect(() => {
    const tag = locale === 'ru' ? 'ru-RU' : 'en-US';
    try {
      void getDndApi().invoke(ipcChannels.windows.syncChromeTitles, { localeTag: tag });
    } catch {
      // preload ещё не готов (редко при первом кадре)
    }
  }, [locale]);

  // Другие окна Electron (пульт, материалы) подхватывают смену языка из редактора.
  useEffect(() => {
    const onStorage = (e: StorageEvent) => {
      if (e.key !== EDITOR_LOCALE_STORAGE_KEY) return;
      setLocaleState(normalizeEditorLocale(e.newValue));
    };
    window.addEventListener('storage', onStorage);
    return () => window.removeEventListener('storage', onStorage);
  }, []);

  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;
}
