'use client';

import {
  createContext,
  useContext,
  useEffect,
  useMemo,
  useState,
  type ReactNode,
} from 'react';
import { DEFAULT_LOCALE, dict, type Dict, type Locale } from './dictionaries';

type Direction = 'rtl' | 'ltr';

type Ctx = {
  locale: Locale;
  dir: Direction;
  t: Dict;
  setLocale: (l: Locale) => void;
  toggle: () => void;
};

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

const STORAGE_KEY = 'sa.locale';

function dirFor(locale: Locale): Direction {
  return locale === 'fa' ? 'rtl' : 'ltr';
}

export function LocaleProvider({
  initialLocale,
  content,
  children,
}: {
  initialLocale?: Locale;
  /**
   * Server-resolved content (dict defaults merged with admin overrides).
   * When omitted we fall back to the in-code dictionary, so the provider keeps
   * working in isolation (tests, storybook, etc.).
   */
  content?: { fa: Dict; en: Dict };
  children: ReactNode;
}) {
  const [locale, setLocaleState] = useState<Locale>(initialLocale ?? DEFAULT_LOCALE);
  const source = content ?? (dict as unknown as { fa: Dict; en: Dict });

  // Hydrate from localStorage on the client.
  useEffect(() => {
    try {
      const saved = window.localStorage.getItem(STORAGE_KEY) as Locale | null;
      if (saved === 'fa' || saved === 'en') {
        setLocaleState(saved);
      }
    } catch {
      /* noop */
    }
  }, []);

  // Reflect locale + direction on the html element without a reload.
  useEffect(() => {
    const html = document.documentElement;
    html.lang = locale;
    html.dir = dirFor(locale);
    html.dataset.locale = locale;
  }, [locale]);

  const setLocale = (l: Locale) => {
    setLocaleState(l);
    try {
      window.localStorage.setItem(STORAGE_KEY, l);
    } catch {
      /* noop */
    }
  };

  const value = useMemo<Ctx>(
    () => ({
      locale,
      dir: dirFor(locale),
      t: source[locale],
      setLocale,
      toggle: () => setLocale(locale === 'fa' ? 'en' : 'fa'),
    }),
    [locale, source],
  );

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

export function useLocale() {
  const ctx = useContext(LocaleContext);
  if (!ctx) throw new Error('useLocale must be used inside <LocaleProvider>');
  return ctx;
}
