import { cookies, headers } from 'next/headers';
import deMessages from '@/messages/de.json';
import enMessages from '@/messages/en.json';
import legalDe from '@/messages/legal-de.json';
import legalEn from '@/messages/legal-en.json';
import { env } from './env';

export type Locale = 'de' | 'en';

export const LOCALE_COOKIE_NAME = 'nexumi_locale';

export const MESSAGES = {
  de: { ...deMessages, legal: legalDe },
  en: { ...enMessages, legal: legalEn }
} as const;

export type Messages = (typeof MESSAGES)['en'];

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);
  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 function t(locale: Locale, key: string, vars?: Record<string, string | number>): string {
  const dict = MESSAGES[locale] ?? MESSAGES[env.DEFAULT_LOCALE];
  return interpolate(resolve(dict, key) ?? key, vars);
}

function isLocale(value: string | undefined): value is Locale {
  return value === 'de' || value === 'en';
}

function localeFromAcceptLanguage(header: string | null): Locale | undefined {
  if (!header) {
    return undefined;
  }

  const preferred = header
    .split(',')
    .map((part) => {
      const [tag, qValue] = part.trim().split(';q=');
      return { lang: tag.trim().toLowerCase().slice(0, 2), q: qValue ? Number(qValue) : 1 };
    })
    .filter((entry) => entry.lang.length === 2 && !Number.isNaN(entry.q))
    .sort((a, b) => b.q - a.q);

  for (const entry of preferred) {
    if (isLocale(entry.lang)) {
      return entry.lang;
    }
  }

  return undefined;
}

/**
 * Resolves the active locale for the current request from the
 * `nexumi_locale` cookie, then Accept-Language, then the server default.
 */
export async function getLocale(): Promise<Locale> {
  const cookieStore = await cookies();
  const cookieLocale = cookieStore.get(LOCALE_COOKIE_NAME)?.value;
  if (isLocale(cookieLocale)) {
    return cookieLocale;
  }

  const headerList = await headers();
  const fromHeader = localeFromAcceptLanguage(headerList.get('accept-language'));
  if (fromHeader) {
    return fromHeader;
  }

  return env.DEFAULT_LOCALE;
}
