'use client';

import { createContext, useContext, useMemo, type ReactNode } from 'react';
import type { Locale, Messages } from '@/lib/i18n';

interface LocaleContextValue {
  locale: Locale;
  messages: Messages;
}

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

export function LocaleProvider({
  locale,
  messages,
  children
}: {
  locale: Locale;
  messages: Messages;
  children: ReactNode;
}) {
  const value = useMemo<LocaleContextValue>(() => ({ locale, messages }), [locale, messages]);
  return <LocaleContext.Provider value={value}>{children}</LocaleContext.Provider>;
}

function useLocaleContext(): LocaleContextValue {
  const ctx = useContext(LocaleContext);
  if (!ctx) {
    throw new Error('useTranslations/useLocale must be used within a LocaleProvider');
  }
  return ctx;
}

function resolve(messages: Messages, key: string): string | undefined {
  const value = key.split('.').reduce<unknown>((acc, part) => {
    if (acc && typeof acc === 'object' && part in (acc as Record<string, unknown>)) {
      return (acc as Record<string, unknown>)[part];
    }
    return undefined;
  }, messages as unknown);
  return typeof value === 'string' ? value : undefined;
}

function interpolate(template: string, vars?: Record<string, string | number>): string {
  if (!vars) {
    return template;
  }
  return Object.entries(vars).reduce(
    (acc, [name, value]) => acc.replaceAll(`{${name}}`, String(value)),
    template
  );
}

export type TranslateFn = (key: string, vars?: Record<string, string | number>) => string;

export function useTranslations(): TranslateFn {
  const { messages } = useLocaleContext();
  return (key, vars) => interpolate(resolve(messages, key) ?? key, vars);
}

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