import { useAsyncData } from '#imports'
import { computed, unref } from 'vue'
import { EMPTY_GUIDES_EXPORT, loadGuidesLocaleExport } from '~/content/guides-export'
import {
  buildContentRouteSeo,
  resolveContentLocalizedEntry,
  resolveContentRouteGroup,
  resolveContentRoutePath,
} from '~/content/site-route-groups'
import { useResolvedPage } from '~/content/pages'
import { usePublicLocale } from '~/composables/usePublicLocale'
import { resolvePublicUiValue } from '~/i18n/public-ui'
import { DEFAULT_PUBLIC_LOCALE, normalizePublicLocale, PUBLIC_PAGE_PATHS, toPublicLocaleCode } from '~/utils/public-locales'

function uniqueValues(values = []) {
  return [...new Set(values.map((value) => String(value || '').trim()).filter(Boolean))]
}

function guideLookupCandidates(identifier, locale = DEFAULT_PUBLIC_LOCALE) {
  if (typeof identifier === 'string') {
    const normalized = String(identifier || '').trim()
    const pathSlug = normalized.split('/').filter(Boolean).at(-1) || ''

    return uniqueValues([
      normalized,
      pathSlug,
      `${pathSlug}__${normalizePublicLocale(locale)}`,
    ])
  }

  const path = String(identifier?.path || '').trim()
  const pathSlug = path.split('/').filter(Boolean).at(-1) || ''
  const requestedLocale = normalizePublicLocale(identifier?.locale || locale)

  return uniqueValues([
    identifier?.contentKey,
    identifier?.content_key,
    identifier?.slug,
    identifier?.publicSlug,
    identifier?.id,
    path,
    pathSlug,
    identifier?.slug ? `${identifier.slug}__${requestedLocale}` : '',
    identifier?.publicSlug ? `${identifier.publicSlug}__${requestedLocale}` : '',
    pathSlug ? `${pathSlug}__${requestedLocale}` : '',
  ])
}

function lookupGuideValue(lookup = {}, candidates = []) {
  for (const candidate of candidates) {
    if (lookup?.[candidate]) {
      return lookup[candidate]
    }
  }

  return null
}

function resolveGuidePayloadEntry(payload = EMPTY_GUIDES_EXPORT, identifier, locale = DEFAULT_PUBLIC_LOCALE) {
  const candidates = guideLookupCandidates(identifier, locale)
  const directMatch = lookupGuideValue(payload.guidesBySlug || {}, candidates)

  if (directMatch) {
    return directMatch
  }

  const routeGroup = resolveContentRouteGroup('guide', identifier)

  if (!routeGroup?.contentKey) {
    return null
  }

  return (payload.guideItems || []).find((item) => String(item?.contentKey || '') === routeGroup.contentKey) || null
}

function formatGuideDate(value, locale = DEFAULT_PUBLIC_LOCALE) {
  if (!value) {
    return resolvePublicUiValue(locale, 'guides.routeGuide')
  }

  const normalizedLocale = normalizePublicLocale(locale)

  return new Intl.DateTimeFormat(toPublicLocaleCode(normalizedLocale), {
    month: 'short',
    day: 'numeric',
    year: 'numeric',
  }).format(new Date(value))
}

function decorateGuide(item, currentLocale = DEFAULT_PUBLIC_LOCALE) {
  if (!item) {
    return null
  }

  const requestedLocale = normalizePublicLocale(currentLocale)
  const sourceLocale = normalizePublicLocale(item?.locale || requestedLocale)
  const routeGroup = resolveContentRouteGroup('guide', item)
  const localizedRouteEntry = resolveContentLocalizedEntry(routeGroup, requestedLocale)
  const resolvedPath = resolveContentRoutePath(routeGroup, requestedLocale, item?.path || '')
  const seo = buildContentRouteSeo(routeGroup, requestedLocale, item?.seo || {})

  return {
    ...item,
    availableLocales: routeGroup?.availableLocales || [sourceLocale],
    available_locales: routeGroup?.available_locales || [sourceLocale],
    localized: routeGroup?.localized || [],
    redirectFrom: routeGroup?.redirectFrom || [],
    redirect_from: routeGroup?.redirect_from || [],
    path: resolvedPath || item?.path || '',
    resolvedPath: resolvedPath || item?.path || '',
    seo,
    canonical: localizedRouteEntry?.canonical || seo?.canonical || '',
    sourceLocale,
    sourceLocaleCode: toPublicLocaleCode(sourceLocale),
    isFallback: sourceLocale !== requestedLocale,
    date: formatGuideDate(item?.publishedAt, requestedLocale),
    readTime: item?.readTimeMinutes ? `${item.readTimeMinutes} min read` : null,
  }
}

function resolveGuideEntityFromPayload(payload = EMPTY_GUIDES_EXPORT, identifier, locale = DEFAULT_PUBLIC_LOCALE) {
  return decorateGuide(resolveGuidePayloadEntry(payload, identifier, locale), locale)
}

function pagePathsByLocale(contentKey = 'blog') {
  return PUBLIC_PAGE_PATHS?.[contentKey] || {}
}

export function resolveGuidesPagePath(locale = DEFAULT_PUBLIC_LOCALE) {
  const normalizedLocale = normalizePublicLocale(locale)
  const paths = pagePathsByLocale('blog')

  return paths[normalizedLocale]
    || paths[DEFAULT_PUBLIC_LOCALE]
    || Object.values(paths).find((value) => String(value || '').trim() !== '')
    || '/'
}

export function resolveGuidesSectionPathsByLocale(page = null) {
  const localizedEntries = Array.isArray(page?.localized) ? page.localized : []

  if (localizedEntries.length) {
    return Object.fromEntries(
      localizedEntries
        .filter((entry) => entry?.locale && entry?.path)
        .map((entry) => [normalizePublicLocale(entry.locale), entry.path]),
    )
  }

  return Object.fromEntries(
    Object.entries(pagePathsByLocale('blog'))
      .filter(([, value]) => String(value || '').trim() !== '')
      .map(([locale, path]) => [normalizePublicLocale(locale), path]),
  )
}

export function buildGuidesPageSeo(page, origin = '') {
  const seo = page?.seo || {}
  const path = page?.path || ''

  return {
    title: seo.title || page?.title || '',
    description: seo.description || page?.excerpt || '',
    ogTitle: seo.ogTitle || seo.title || page?.title || '',
    ogDescription: seo.ogDescription || seo.description || page?.excerpt || '',
    ogImage: seo.ogImage || page?.heroImage || page?.featuredImage || '',
    canonical: seo.canonical || (path ? `${origin}${path}` : ''),
    robots: seo.robots || 'index,follow',
    hreflang: Array.isArray(seo?.hreflang) ? seo.hreflang : [],
    xDefault: seo.xDefault || (page?.localized || []).find((entry) => normalizePublicLocale(entry?.locale) === DEFAULT_PUBLIC_LOCALE)?.href || '',
  }
}

export function buildGuideDetailSeo(guide, origin = '') {
  const seo = guide?.seo || {}
  const path = guide?.resolvedPath || guide?.path || ''

  return {
    title: seo.title || guide?.title || '',
    description: seo.description || guide?.excerpt || '',
    ogTitle: seo.ogTitle || seo.title || guide?.title || '',
    ogDescription: seo.ogDescription || seo.description || guide?.excerpt || '',
    ogImage: seo.ogImage || guide?.heroImage || '',
    canonical: seo.canonical || (path ? `${origin}${path}` : ''),
    robots: seo.robots || 'index,follow',
    hreflang: Array.isArray(seo?.hreflang) ? seo.hreflang : [],
    xDefault: seo.xDefault || guide?.xDefault || guide?.x_default || '',
  }
}

export async function useGuidesContent() {
  const { locale } = usePublicLocale()
  const guidesPage = useResolvedPage('blog')
  const { data: guidesExport } = await useAsyncData(
    () => `guides-export:${normalizePublicLocale(locale.value)}`,
    () => loadGuidesLocaleExport(locale.value),
    {
      watch: [locale],
      default: () => EMPTY_GUIDES_EXPORT,
    },
  )

  const scenicRoutes = computed(() => (guidesExport.value?.scenicRoutes || [])
    .map((item) => decorateGuide(item, locale.value))
    .filter(Boolean))

  const guidesIndex = computed(() => guidesExport.value?.guidesIndex || [])
  const guidesUi = computed(() => ({
    dateFallback: guidesPage.value?.structuredContent?.ui?.dateFallback,
    recommendedVehicleLabel: guidesPage.value?.structuredContent?.ui?.recommendedVehicleLabel,
    emptyTitle: guidesPage.value?.structuredContent?.ui?.emptyTitle,
    emptyDescription: guidesPage.value?.structuredContent?.ui?.emptyDescription,
  }))

  function useResolvedGuideDetail(slugRef) {
    return computed(() => resolveGuideEntityFromPayload(guidesExport.value || EMPTY_GUIDES_EXPORT, unref(slugRef), locale.value))
  }

  return {
    guidesIndex,
    guidesPage,
    guidesUi,
    scenicRoutes,
    useResolvedGuideDetail,
  }
}
