"use client";

import { createContext, useContext, useEffect, useMemo, useState } from "react";
import { translations, type Dictionary, type Locale } from "@/lib/i18n/translations";

const STORAGE_KEY = "toknext-locale";

interface LanguageContextValue {
  locale: Locale;
  setLocale: (locale: Locale) => void;
  t: Dictionary;
}

const LanguageContext = createContext<LanguageContextValue | null>(null);

export function LanguageProvider({ children }: { children: React.ReactNode }) {
  const [locale, setLocaleState] = useState<Locale>("en");

  // Read the saved preference after mount only — reading localStorage during
  // the initial render would make the server-rendered HTML (always "en")
  // mismatch the client's first paint if a visitor had picked "es" before.
  useEffect(() => {
    const saved = window.localStorage.getItem(STORAGE_KEY);
    if (saved === "en" || saved === "es") {
      // eslint-disable-next-line react-hooks/set-state-in-effect -- syncing from localStorage (an external system) after mount, by design, to avoid an SSR hydration mismatch
      setLocaleState(saved);
      return;
    }
    // No saved preference: default new visitors to their browser language.
    if (navigator.language?.toLowerCase().startsWith("es")) {
      setLocaleState("es");
    }
  }, []);

  // Keep the <html lang> attribute in sync for screen readers and browser
  // translation prompts, since this is a client-only locale switch (no
  // /en, /es routes).
  useEffect(() => {
    document.documentElement.lang = locale;
  }, [locale]);

  function setLocale(next: Locale) {
    setLocaleState(next);
    window.localStorage.setItem(STORAGE_KEY, next);
  }

  const value = useMemo<LanguageContextValue>(
    () => ({ locale, setLocale, t: translations[locale] }),
    [locale],
  );

  return <LanguageContext.Provider value={value}>{children}</LanguageContext.Provider>;
}

export function useLanguage() {
  const ctx = useContext(LanguageContext);
  if (!ctx) throw new Error("useLanguage must be used within a LanguageProvider");
  return ctx;
}
