"use client";

import { createContext, useContext, useState, useEffect, useCallback, ReactNode } from "react";

import cs from "@/messages/cs.json";
import he from "@/messages/he.json";
import ru from "@/messages/ru.json";
import ua from "@/messages/ua.json";

export type Locale = "cs" | "he" | "ru" | "ua";

export const LOCALES: { code: Locale; label: string; flag: string; dir: "ltr" | "rtl" }[] = [
  { code: "cs", label: "\u010ce\u0161tina", flag: "\ud83c\udde8\ud83c\uddff", dir: "ltr" },
  { code: "he", label: "\u05e2\u05d1\u05e8\u05d9\u05ea", flag: "\ud83c\uddee\ud83c\uddf1", dir: "rtl" },
  { code: "ru", label: "\u0420\u0443\u0441\u0441\u043a\u0438\u0439", flag: "\ud83c\uddf7\ud83c\uddfa", dir: "ltr" },
  { code: "ua", label: "\u0423\u043a\u0440\u0430\u0457\u043d\u0441\u044c\u043a\u0430", flag: "\ud83c\uddfa\ud83c\udde6", dir: "ltr" },
];

type Messages = typeof cs;

const MESSAGES: Record<Locale, Messages> = { cs, he, ru, ua };

const STORAGE_KEY = "taskteam_language";

function getNestedValue(obj: unknown, path: string): string | undefined {
  const keys = path.split(".");
  let current: unknown = obj;
  for (const key of keys) {
    if (current == null || typeof current !== "object") return undefined;
    current = (current as Record<string, unknown>)[key];
  }
  return typeof current === "string" ? current : undefined;
}

interface I18nContextType {
  locale: Locale;
  setLocale: (locale: Locale) => void;
  t: (key: string) => string;
  dir: "ltr" | "rtl";
  isRTL: boolean;
}

const I18nContext = createContext<I18nContextType>({
  locale: "cs",
  setLocale: () => {},
  t: (key: string) => key,
  dir: "ltr",
  isRTL: false,
});

export function useTranslation() {
  return useContext(I18nContext);
}

export function I18nProvider({ children }: { children: ReactNode }) {
  const [locale, setLocaleState] = useState<Locale>("cs");
  const [mounted, setMounted] = useState(false);

  useEffect(() => {
    const stored = localStorage.getItem(STORAGE_KEY) as Locale | null;
    if (stored && MESSAGES[stored]) {
      setLocaleState(stored);
    }
    setMounted(true);
  }, []);

  const setLocale = useCallback((newLocale: Locale) => {
    setLocaleState(newLocale);
    if (typeof window !== "undefined") {
      localStorage.setItem(STORAGE_KEY, newLocale);
    }
  }, []);

  // Always use "cs" for translations until mounted to match SSR output
  const activeLocale = mounted ? locale : "cs";

  const t = useCallback(
    (key: string): string => {
      const value = getNestedValue(MESSAGES[activeLocale], key);
      if (value !== undefined) return value;
      // Fallback: return last segment of the key (the raw value) instead of "undefined"
      return key.split(".").pop() || key;
    },
    [activeLocale]
  );

  const localeInfo = LOCALES.find((l) => l.code === activeLocale) || LOCALES[0];
  const dir = localeInfo.dir;
  const isRTL = dir === "rtl";

  // Update html attributes when locale changes (only after mount)
  useEffect(() => {
    if (!mounted) return;
    document.documentElement.lang = locale;
    document.documentElement.dir = LOCALES.find((l) => l.code === locale)?.dir || "ltr";
  }, [locale, mounted]);

  return (
    <I18nContext.Provider value={{ locale: activeLocale, setLocale, t, dir, isRTL }}>
      {children}
    </I18nContext.Provider>
  );
}
