import { useSyncExternalStore } from 'react'
import { DEFAULT_LOCALE, LOCALES, type SupportedLocale } from '@/config'

export const supportedLocales = LOCALES
export const defaultLocale = DEFAULT_LOCALE
export type Locale = SupportedLocale

const LANGUAGE_STORAGE_KEY = 'heygermany.language'
const RTL_LOCALES = new Set(['ar', 'he', 'fa', 'ur'])

let activeLocale: Locale = defaultLocale
const listeners = new Set<() => void>()

export const getLocale = (): Locale => activeLocale

export function localeDir(locale: string = defaultLocale): 'rtl' | 'ltr' {
  return RTL_LOCALES.has(locale.split('-')[0]) ? 'rtl' : 'ltr'
}

const normalizeLanguage = (value: string | null | undefined): Locale | undefined => {
  const short = value?.slice(0, 2).toLowerCase()
  return supportedLocales.includes(short as Locale) ? (short as Locale) : undefined
}

export function detectInitialLocale(): Locale {
  if (typeof window === 'undefined') {
    return defaultLocale
  }

  return (
    normalizeLanguage(window.localStorage.getItem(LANGUAGE_STORAGE_KEY)) ??
    normalizeLanguage(window.navigator.language) ??
    normalizeLanguage(window.document.documentElement.lang) ??
    defaultLocale
  )
}

export function setActiveLocale(next: Locale): void {
  if (next === activeLocale) {
    return
  }

  activeLocale = next

  if (typeof window !== 'undefined') {
    window.localStorage.setItem(LANGUAGE_STORAGE_KEY, next)
    window.document.documentElement.lang = next
  }

  for (const listener of listeners) {
    listener()
  }
}

export function setRouteLocale(next: Locale): void {
  if (next === activeLocale) {
    return
  }

  activeLocale = next

  if (typeof window !== 'undefined') {
    window.document.documentElement.lang = next
  }

  for (const listener of listeners) {
    listener()
  }
}

function subscribe(listener: () => void): () => void {
  listeners.add(listener)
  return () => listeners.delete(listener)
}

activeLocale = detectInitialLocale()

export function useLocale(): { locale: Locale; dir: 'ltr' | 'rtl'; setLocale: (locale: Locale) => void } {
  const locale = useSyncExternalStore<Locale>(subscribe, () => activeLocale, () => activeLocale)
  return {
    locale,
    dir: localeDir(locale),
    setLocale: setActiveLocale,
  }
}

export function isI18nDebug(): boolean {
  if (typeof process !== 'undefined' && process.env?.I18N_DEBUG === '1') {
    return true
  }

  if (typeof window === 'undefined') {
    return false
  }

  const params = new URLSearchParams(window.location.search)
  if (params.has('i18n-debug')) {
    return params.get('i18n-debug') !== '0'
  }

  return window.localStorage?.getItem('i18n-debug') === '1'
}

export function maskI18n(value: string): string {
  return isI18nDebug() ? value.replace(/\S/g, '█') : value
}
