export const APP_LOCALE_COOKIE = 'beaver_locale';
export const APP_LOCALE_STORAGE_KEY = 'beaver_locale';

export const APP_LOCALES = ['zh-CN', 'en-US'] as const;

export type AppLocale = (typeof APP_LOCALES)[number];

export function isAppLocale(value: string | null | undefined): value is AppLocale {
  return value === 'zh-CN' || value === 'en-US';
}

export function normalizeAppLocale(value?: string | null): AppLocale {
  const probe = value?.trim().toLowerCase() || '';
  if (probe.startsWith('en')) {
    return 'en-US';
  }
  return 'zh-CN';
}

function readCookieLocale(): string | null {
  if (typeof document === 'undefined') {
    return null;
  }

  const match = document.cookie
    .split('; ')
    .find((item) => item.startsWith(`${APP_LOCALE_COOKIE}=`));
  if (!match) {
    return null;
  }
  return decodeURIComponent(match.slice(APP_LOCALE_COOKIE.length + 1));
}

export function readBrowserAppLocale(): AppLocale {
  if (typeof window === 'undefined') {
    return 'zh-CN';
  }

  const fromDocument = document.documentElement.lang;
  if (fromDocument) {
    return normalizeAppLocale(fromDocument);
  }

  const fromStorage = window.localStorage.getItem(APP_LOCALE_STORAGE_KEY);
  if (fromStorage) {
    return normalizeAppLocale(fromStorage);
  }

  const fromCookie = readCookieLocale();
  if (fromCookie) {
    return normalizeAppLocale(fromCookie);
  }

  return normalizeAppLocale(window.navigator.language);
}

export function persistAppLocale(locale: AppLocale): void {
  if (typeof window === 'undefined') {
    return;
  }

  document.documentElement.lang = locale;
  window.localStorage.setItem(APP_LOCALE_STORAGE_KEY, locale);
  document.cookie = `${APP_LOCALE_COOKIE}=${encodeURIComponent(locale)}; path=/; max-age=31536000; samesite=lax`;
}

export function getCurrentAppLocale(): AppLocale {
  if (typeof window === 'undefined') {
    return 'zh-CN';
  }
  return readBrowserAppLocale();
}

export function pickAppText<T>(locale: AppLocale, zhValue: T, enValue: T): T {
  return locale === 'en-US' ? enValue : zhValue;
}
