import type { SupportedLocale } from '@heygermany/sdk/config'
import { DEFAULT_LOCALE, LOCALES } from '@/config'
import { mTextIn } from '@/i18n/messages'

type MessageKey = string

export const SITE_NAME = 'HeyGermany'
export const BRAND_ALT_NAME = 'Hey Germany'
export const CONTACT_EMAIL = 'info@hey-germany.com'
const viteEnv = (import.meta as ImportMeta & {
  env?: Record<string, string | undefined>
}).env

export const SITE_URL =
  viteEnv?.VITE_SITE_URL || process.env.VITE_SITE_URL || 'https://hey-germany.com'
export const DEFAULT_SITE_TITLE = `${SITE_NAME} | Nursing Career and Qualification Check in Germany`
export const DEFAULT_SITE_DESCRIPTION =
  'HeyGermany helps internationally qualified nurses check their qualifications and take the next step toward a nursing career in Germany.'
export const DEFAULT_OG_IMAGE = '/heygermany-logo.png'
export const NO_INDEX_METADATA = {
  robots: {
    index: false,
    follow: false,
    nocache: true,
    googleBot: {
      index: false,
      follow: false,
      noimageindex: true,
    },
  },
}

type CreatePageMetadataInput = {
  locale: string
  pathname?: string
  title: string
  description: string
  imagePath?: string
  index?: boolean
  availableLocales?: readonly SupportedLocale[]
  canonicalLocale?: SupportedLocale
}

function isSupportedLocale(locale: string): locale is SupportedLocale {
  return LOCALES.includes(locale as SupportedLocale)
}

function normalizePath(pathname: string): string {
  if (!pathname || pathname === '/') {
    return '/'
  }

  return pathname.startsWith('/') ? pathname : `/${pathname}`
}

function buildRobots(index: boolean) {
  return index
    ? {
        index: true,
        follow: true,
      }
    : NO_INDEX_METADATA.robots
}

export function normalizeLocale(locale: string): SupportedLocale {
  return isSupportedLocale(locale) ? locale : DEFAULT_LOCALE
}

export function getAbsoluteUrl(pathname: string): string {
  return new URL(pathname, SITE_URL).toString()
}

export function getLocalizedPath(locale: string, pathname = '/'): string {
  const normalizedLocale = normalizeLocale(locale)
  const normalizedPath = normalizePath(pathname)

  return normalizedPath === '/'
    ? `/${normalizedLocale}`
    : `/${normalizedLocale}${normalizedPath}`
}

export function withSiteName(title: string): string {
  return title.includes(SITE_NAME) ? title : `${title} | ${SITE_NAME}`
}

export function getMessage(locale: string, key: MessageKey): string {
  return mTextIn(normalizeLocale(locale), key)
}

function buildLanguageAlternates(
  pathname: string,
  locales: readonly SupportedLocale[]
): Record<string, string> | undefined {
  if (locales.length < 2) {
    return undefined
  }

  const alternates = Object.fromEntries(
    locales.map((locale) => [locale, getAbsoluteUrl(getLocalizedPath(locale, pathname))])
  ) as Record<string, string>

  alternates['x-default'] = getAbsoluteUrl(getLocalizedPath(DEFAULT_LOCALE, pathname))

  return alternates
}

export function createPageMetadata({
  locale,
  pathname = '/',
  title,
  description,
  imagePath = DEFAULT_OG_IMAGE,
  index = true,
  availableLocales = LOCALES,
  canonicalLocale,
}: CreatePageMetadataInput) {
  const resolvedLocale = normalizeLocale(locale)
  const resolvedCanonicalLocale = canonicalLocale ?? resolvedLocale
  const canonicalPath = getLocalizedPath(resolvedCanonicalLocale, pathname)
  const resolvedTitle = withSiteName(title)
  const imageUrl = getAbsoluteUrl(imagePath)
  const languages = buildLanguageAlternates(pathname, availableLocales)

  return {
    title: resolvedTitle,
    description,
    alternates: {
      canonical: getAbsoluteUrl(canonicalPath),
      ...(languages ? { languages } : {}),
    },
    openGraph: {
      title: resolvedTitle,
      description,
      url: getAbsoluteUrl(canonicalPath),
      siteName: SITE_NAME,
      type: 'website',
      images: [
        {
          url: imageUrl,
          alt: resolvedTitle,
        },
      ],
    },
    twitter: {
      card: 'summary_large_image',
      title: resolvedTitle,
      description,
      images: [imageUrl],
    },
    robots: buildRobots(index),
  }
}

export function createHomepageMetadata(locale: string) {
  const resolvedLocale = normalizeLocale(locale)

  const homepageMetadata: Partial<
    Record<SupportedLocale, { title: string; description: string }>
  > = {
    en: {
      title: DEFAULT_SITE_TITLE,
      description: DEFAULT_SITE_DESCRIPTION,
    },
    de: {
      title: `${SITE_NAME} | Pflegekarriere und Qualifikationscheck in Deutschland`,
      description:
        'HeyGermany unterstützt internationale Pflegefachkräfte dabei, ihre Qualifikation für Deutschland zu prüfen und den nächsten Schritt in ihre Pflegekarriere zu gehen.',
    },
  }

  const localizedBrandMetadata = homepageMetadata[resolvedLocale]

  return createPageMetadata({
    locale: resolvedLocale,
    title: localizedBrandMetadata?.title ?? `${SITE_NAME} | ${getMessage(locale, 'website.hero.title')}`,
    description: localizedBrandMetadata?.description ?? getMessage(locale, 'website.hero.subtitle'),
  })
}

export function getOrganizationStructuredData() {
  return {
    '@context': 'https://schema.org',
    '@type': 'Organization',
    '@id': `${SITE_URL}#organization`,
    name: SITE_NAME,
    alternateName: BRAND_ALT_NAME,
    url: SITE_URL,
    logo: {
      '@type': 'ImageObject',
      url: getAbsoluteUrl(DEFAULT_OG_IMAGE),
    },
    email: CONTACT_EMAIL,
    description: DEFAULT_SITE_DESCRIPTION,
    contactPoint: [
      {
        '@type': 'ContactPoint',
        contactType: 'customer support',
        email: CONTACT_EMAIL,
        url: SITE_URL,
        availableLanguage: LOCALES,
      },
    ],
    brand: {
      '@type': 'Brand',
      name: SITE_NAME,
      alternateName: BRAND_ALT_NAME,
    },
  }
}

export function getWebsiteStructuredData() {
  return {
    '@context': 'https://schema.org',
    '@type': 'WebSite',
    '@id': `${SITE_URL}#website`,
    url: SITE_URL,
    name: SITE_NAME,
    alternateName: BRAND_ALT_NAME,
    description: DEFAULT_SITE_DESCRIPTION,
    publisher: {
      '@id': `${SITE_URL}#organization`,
    },
    inLanguage: LOCALES,
  }
}
