/**
 * Locale primitives with NO dependency on the message catalogues, so the detection rules
 * can be exercised on their own (see scripts/test-registration.mjs → section 8).
 */
export const LOCALES = ['de', 'en'] as const
export type Locale = (typeof LOCALES)[number]

/** German is the default and the fallback everywhere. */
export const DEFAULT_LOCALE: Locale = 'de'

export const isLocale = (value: unknown): value is Locale =>
  value === 'de' || value === 'en'

/**
 * Picks a locale from an Accept-Language header.
 *
 * German wins whenever the header is absent, unparsable or ambiguous: English is only
 * chosen when it is present with a STRICTLY higher quality value than German (which
 * includes the case where German is not listed at all). A bare `*` is ignored — a
 * wildcard states no preference, and no preference means German.
 *
 *   "de-DE,de;q=0.9,en;q=0.8"  → de   (German preferred)
 *   "en-GB,en;q=0.9"           → en   (no German at all)
 *   "en;q=0.9,de;q=0.9"        → de   (tie → German)
 *   "*"  /  ""  /  "fr-FR"     → de   (ambiguous or unsupported)
 */
export const localeFromAcceptLanguage = (header: string): Locale => {
  let deQ = -1
  let enQ = -1

  for (const part of String(header || '').split(',')) {
    const [rawTag, ...params] = part.trim().split(';')
    const tag = String(rawTag || '').trim().toLowerCase()
    if (!tag || tag === '*') continue

    let q = 1
    for (const param of params) {
      const [key, value] = param.split('=')
      if (String(key || '').trim().toLowerCase() === 'q') {
        const parsed = Number.parseFloat(String(value || '').trim())
        if (Number.isFinite(parsed)) q = parsed
      }
    }
    if (q <= 0) continue

    const base = tag.split('-')[0]
    if (base === 'de') deQ = Math.max(deQ, q)
    else if (base === 'en') enQ = Math.max(enQ, q)
  }

  return enQ > deQ ? 'en' : DEFAULT_LOCALE
}
