"use client";

/**
 * Water Log — React context for the current language.
 *
 * Wraps a `LangProvider` around a tree of components that need to
 * read or change the active language. The provider keeps `lang` in
 * React state, persists every change to the `wl_lang` cookie, and
 * exposes a `setLang` callback.
 *
 * The provider does NOT call `detectInitialLang()` itself — callers
 * pass `initialLang` in (typically computed in a `useState`
 * initializer so SSR and the first client render agree).
 */

import {
  createContext,
  useCallback,
  useContext,
  useMemo,
  useState,
  type ReactNode,
} from "react";
import {
  type Lang,
  type Labels,
  getT,
  setLangCookie,
} from "./i18n";

type LangContextValue = {
  lang: Lang;
  /** Pre-resolved label dictionary for the current lang. */
  t: Labels;
  setLang: (lang: Lang) => void;
  toggleLang: () => void;
};

const LangContext = createContext<LangContextValue | null>(null);

export function LangProvider({
  initialLang,
  children,
}: {
  initialLang: Lang;
  children: ReactNode;
}) {
  const [lang, setLangState] = useState<Lang>(initialLang);

  const setLang = useCallback((next: Lang) => {
    setLangState(next);
    setLangCookie(next);
  }, []);

  const toggleLang = useCallback(() => {
    setLangState((prev) => {
      const next: Lang = prev === "en" ? "es" : "en";
      setLangCookie(next);
      return next;
    });
  }, []);

  const value = useMemo<LangContextValue>(
    () => ({ lang, t: getT(lang), setLang, toggleLang }),
    [lang, setLang, toggleLang],
  );

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

/**
 * Read the current language + labels from context. Throws if used
 * outside a `<LangProvider>` — that's almost certainly a bug.
 */
export function useLang(): LangContextValue {
  const ctx = useContext(LangContext);
  if (!ctx) {
    throw new Error(
      "useLang() must be called inside <LangProvider>. " +
        "Wrap your tree (e.g. MobileWaterApp) in <LangProvider initialLang={...}>.",
    );
  }
  return ctx;
}