import { useRequestHeaders } from '#imports'
import { DEFAULT_PUBLIC_LOCALE, PUBLIC_LOCALES, normalizePublicLocale } from '~/utils/public-locales'

const supportedLocaleSet = new Set(PUBLIC_LOCALES.map((item) => item.locale))

const legacyLocaleMap = {
  ge: 'ka',
}

function readCookieValue(name, cookieHeader = '') {
  const pattern = new RegExp(`(?:^|;\\s*)${name.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')}=([^;]*)`)
  const match = String(cookieHeader || '').match(pattern)

  if (!match?.[1]) {
    return ''
  }

  try {
    return decodeURIComponent(match[1])
  }
  catch {
    return match[1]
  }
}

function resolveSupportedLocaleTag(tag = '') {
  const normalized = String(tag || '').trim().toLowerCase()

  if (!normalized) {
    return null
  }

  const legacyLocale = legacyLocaleMap[normalized]

  if (legacyLocale && supportedLocaleSet.has(legacyLocale)) {
    return legacyLocale
  }

  if (supportedLocaleSet.has(normalized)) {
    return normalized
  }

  const baseLocale = normalized.split('-')[0]

  return supportedLocaleSet.has(baseLocale) ? baseLocale : null
}

function parseAcceptLanguage(header = '') {
  return String(header || '')
    .split(',')
    .map((entry, index) => {
      const [tagPart, ...params] = entry.trim().split(';')
      const tag = tagPart.trim()
      const qualityParam = params.find((item) => item.trim().startsWith('q='))
      const quality = qualityParam ? Number.parseFloat(qualityParam.split('=')[1]) : 1

      if (!tag) {
        return null
      }

      return {
        index,
        locale: resolveSupportedLocaleTag(tag),
        quality: Number.isFinite(quality) ? quality : 1,
      }
    })
    .filter((entry) => entry?.locale)
    .sort((left, right) => right.quality - left.quality || left.index - right.index)
    .map((entry) => entry.locale)
}

export function resolveBrowserPreferredPublicLocale() {
  const requestHeaders = import.meta.server
    ? useRequestHeaders(['accept-language', 'cookie'])
    : {}
  const cookieHeader = String(requestHeaders.cookie || '')
  const explicitCookieLocale = readCookieValue('bent-preferred-language', cookieHeader)

  if (explicitCookieLocale) {
    return normalizePublicLocale(explicitCookieLocale)
  }

  const headerLocales = parseAcceptLanguage(requestHeaders['accept-language'] || '')

  if (headerLocales.length) {
    return headerLocales[0] || DEFAULT_PUBLIC_LOCALE
  }

  if (import.meta.client) {
    const navigatorLocales = Array.isArray(navigator.languages) && navigator.languages.length
      ? navigator.languages
      : [navigator.language || '']

    const clientLocales = parseAcceptLanguage(navigatorLocales.join(','))

    return clientLocales[0] || DEFAULT_PUBLIC_LOCALE
  }

  return DEFAULT_PUBLIC_LOCALE
}
