"use client";

import {
  createContext,
  useCallback,
  useContext,
  useEffect,
  useMemo,
  useState,
} from "react";
import { useTranslation } from "react-i18next";
import "@/lib/i18n";
import {
  getDirection,
  type AppLanguage,
} from "@/lib/i18n/registry";
import {
  persistLanguagePreference,
  readStoredLanguagePreference,
  resolveBrowserLanguage,
} from "@/lib/i18n/clientLanguage";
import { syncDocumentLanguage } from "@/lib/i18n/syncDocumentLanguage";

type LanguageContextValue = {
  language: AppLanguage;
  dir: "rtl" | "ltr";
  isRtl: boolean;
  ready: boolean;
  setLanguage: (lang: AppLanguage) => Promise<void>;
};

const LanguageContext = createContext<LanguageContextValue | null>(null);

export function LanguageProvider({ children }: { children: React.ReactNode }) {
  const { i18n } = useTranslation();
  const [language, setLanguageState] = useState<AppLanguage>(() => {
    return readStoredLanguagePreference() ?? resolveBrowserLanguage();
  });
  const [ready, setReady] = useState(false);

  useEffect(() => {
    const stored = readStoredLanguagePreference();
    const initial = stored ?? resolveBrowserLanguage();

    if (!stored) {
      persistLanguagePreference(initial);
    }

    void i18n.changeLanguage(initial).finally(() => {
      setLanguageState(initial);
      syncDocumentLanguage(initial);
      setReady(true);
    });
  }, [i18n]);

  const setLanguage = useCallback(
    async (lang: AppLanguage) => {
      await i18n.changeLanguage(lang);
      persistLanguagePreference(lang);
      setLanguageState(lang);
      syncDocumentLanguage(lang);
    },
    [i18n]
  );

  const value = useMemo<LanguageContextValue>(
    () => ({
      language,
      dir: getDirection(language),
      isRtl: getDirection(language) === "rtl",
      ready,
      setLanguage,
    }),
    [language, ready, setLanguage]
  );

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

export function useAppLanguage() {
  const ctx = useContext(LanguageContext);
  if (!ctx) {
    throw new Error("useAppLanguage must be used within LanguageProvider");
  }
  return ctx;
}
