'use client';

import {
  createContext,
  useCallback,
  useContext,
  useEffect,
  useMemo,
  useState,
} from 'react';
import {
  fetchLocaleWithGeoFirst,
  fetchTranslations,
  type LocalizationContext as LocaleContext,
} from '@/lib/localization';

type Translations = Record<string, string>;

interface LocalizationState {
  locale: LocaleContext | null;
  translations: Translations | null;
  loading: boolean;
  error: boolean;
}

interface LocalizationContextValue extends LocalizationState {
  t: (key: string) => string;
  localeCode: string;
}

const defaultTranslations: Translations = {
  'app.title': 'GooSeek',
  'app.searchPlaceholder': 'Search...',
  'empty.subtitle': 'Research begins here.',
  'input.askAnything': 'Ask anything...',
  'input.askFollowUp': 'Ask a follow-up',
  'chat.send': 'Send',
  'chat.newChat': 'New Chat',
  'chat.suggestions': 'Suggestions',
  'discover.title': 'Discover',
  'discover.region': 'Region',
  'weather.title': 'Weather',
  'weather.feelsLike': 'Feels like',
  'common.loading': 'Loading...',
  'common.error': 'Error',
  'common.retry': 'Retry',
  'nav.home': 'Home',
  'nav.discover': 'Discover',
  'nav.library': 'Library',
  'chat.related': 'Follow-up questions',
  'chat.searchImages': 'Search images',
  'chat.searchVideos': 'Search videos',
  'chat.video': 'Video',
  'chat.uploadedFile': 'Uploaded File',
  'chat.viewMore': 'View {count} more',
  'chat.sources': 'Sources',
  'chat.researchProgress': 'Research Progress',
  'chat.step': 'step',
  'chat.steps': 'steps',
  'chat.answer': 'Answer',
  'chat.brainstorming': 'Brainstorming...',
  'chat.formingAnswer': 'Forming answer...',
  'chat.answerFailed': 'Could not form an answer from the sources found. Try rephrasing or shortening your query.',
  'chat.thinking': 'Thinking',
  'chat.searchingQueries': 'Searching {count} {plural}',
  'chat.foundResults': 'Found {count} {plural}',
  'chat.readingSources': 'Reading {count} {plural}',
  'chat.scanningDocs': 'Scanning your uploaded documents',
  'chat.readingDocs': 'Reading {count} {plural}',
  'chat.processing': 'Processing',
  'chat.query': 'query',
  'chat.queries': 'queries',
  'chat.result': 'result',
  'chat.results': 'results',
  'chat.source': 'source',
  'chat.document': 'document',
  'chat.documents': 'documents',
};

const LocalizationContext = createContext<LocalizationContextValue | null>(null);

export function LocalizationProvider({
  children,
}: {
  children: React.ReactNode;
}) {
  const [state, setState] = useState<LocalizationState>({
    locale: null,
    translations: null,
    loading: true,
    error: false,
  });

  useEffect(() => {
    let cancelled = false;
    async function load() {
      try {
        const loc = await fetchLocaleWithGeoFirst();
        if (cancelled) return;
        let trans: Record<string, string>;
        try {
          trans = await fetchTranslations(loc.locale);
        } catch {
          trans = (await import('./embeddedTranslations')).getEmbeddedTranslations(
            loc.locale,
          );
        }
        if (cancelled) return;
        setState({
          locale: loc,
          translations: trans,
          loading: false,
          error: false,
        });
        if (typeof document !== 'undefined') {
          document.documentElement.lang = loc.locale;
        }
      } catch {
        if (cancelled) return;
        setState({
          locale: null,
          translations: null,
          loading: false,
          error: true,
        });
      }
    }
    load();
    return () => {
      cancelled = true;
    };
  }, []);

  const t = useCallback(
    (key: string): string => {
      if (state.translations && key in state.translations) {
        return state.translations[key] ?? key;
      }
      return defaultTranslations[key] ?? key;
    },
    [state.translations],
  );

  const localeCode = state.locale?.locale ?? 'en';

  const value = useMemo<LocalizationContextValue>(
    () => ({
      ...state,
      t,
      localeCode,
    }),
    [state, t, localeCode],
  );

  return (
    <LocalizationContext.Provider value={value}>
      {children}
    </LocalizationContext.Provider>
  );
}

export function useTranslation(): LocalizationContextValue {
  const ctx = useContext(LocalizationContext);
  if (!ctx) {
    return {
      locale: null,
      translations: null,
      loading: false,
      error: true,
      t: (key: string) => defaultTranslations[key] ?? key,
      localeCode: 'en',
    };
  }
  return ctx;
}
