import React from 'react';
import { translate, DEFAULT_LOCALE, type LocaleCode } from './messages';
import { useLocale } from './LocaleContext';

type ReplacementValues = Record<string, string | number>;

export type TranslateFn = {
  (key: string): string;
  (key: string, fallback: string): string;
  (key: string, replacements: ReplacementValues): string;
  (key: string, replacements: ReplacementValues, fallback: string): string;
};

function resolveTranslation(locale: LocaleCode, key: string, fallback?: string): string {
  return translate(locale, key) ?? translate(DEFAULT_LOCALE, key) ?? fallback ?? key;
}

function applyReplacements(value: string, replacements?: ReplacementValues): string {
  if (!replacements) {
    return value;
  }

  return Object.entries(replacements).reduce((acc, [token, replacement]) => {
    const pattern = new RegExp(`\\{${token}\\}`, 'g');
    return acc.replace(pattern, String(replacement));
  }, value);
}

export function useTranslation() {
  const { locale } = useLocale();

  const t = React.useCallback<TranslateFn>((key: string, arg2?: ReplacementValues | string, arg3?: string) => {
    let replacements: ReplacementValues | undefined;
    let fallback: string | undefined;

    if (typeof arg2 === 'string' || arg2 === undefined) {
      fallback = arg2 ?? arg3;
    } else {
      replacements = arg2;
      fallback = arg3;
    }

    const raw = resolveTranslation(locale, key, fallback);

    return applyReplacements(raw, replacements);
  }, [locale]);

  return React.useMemo(() => ({ t, locale }), [t, locale]);
}
