"use client";

import type { Locale } from "@/i18n/config";
import type { Messages } from "@/lib/i18n";
import { getNested } from "@/lib/i18n";
import {
  createContext,
  useCallback,
  useContext,
  useMemo,
  type ReactNode,
} from "react";

type LocaleContextValue = {
  locale: Locale;
  messages: Messages;
  t: (path: string, vars?: Record<string, string>) => string;
};

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

function interpolate(
  template: string,
  vars: Record<string, string> | undefined,
): string {
  if (!vars) return template;
  return template.replace(/\{(\w+)\}/g, (_, key: string) => {
    return vars[key] ?? `{${key}}`;
  });
}

export function LocaleProvider({
  locale,
  messages,
  children,
}: {
  locale: Locale;
  messages: Messages;
  children: ReactNode;
}) {
  const t = useCallback(
    (path: string, vars?: Record<string, string>) => {
      const raw = getNested(
        messages as unknown as Record<string, unknown>,
        path,
      );
      if (typeof raw !== "string") return path;
      return interpolate(raw, vars);
    },
    [messages],
  );

  const value = useMemo(
    () => ({ locale, messages, t }),
    [locale, messages, t],
  );

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

export function useLocaleContext() {
  const ctx = useContext(LocaleContext);
  if (!ctx) {
    throw new Error("useLocaleContext must be used within LocaleProvider");
  }
  return ctx;
}

export function useT() {
  return useLocaleContext().t;
}

export function useMessages() {
  return useLocaleContext().messages;
}

export function useLocale() {
  return useLocaleContext().locale;
}
