import type { LoadTranslationsQuery } from '#graphql-operations'
import type { GraphqlResponse } from '#nuxt-graphql-middleware/response'
import { defineEasyTextsLoader } from 'nuxt-easy-texts/loader'

type MappedTranslations = Record<string, string | [string, string]>

function mapTranslations(
  response: GraphqlResponse<LoadTranslationsQuery>,
): MappedTranslations {
  return Object.entries(response.data.translations || {}).reduce<
    Record<string, string | [string, string]>
  >((acc, [fullKey, value]) => {
    const keyWithDots = fullKey.replace('__', '.')
    if (typeof value === 'string') {
      acc[keyWithDots] = value
    } else if (typeof value === 'object' && value.plural && value.singular) {
      acc[keyWithDots] = [value.singular, value.plural]
    }
    return acc
  }, {})
}

export default defineEasyTextsLoader(() => {
  const language = useCurrentLanguage()
  return {
    async load() {
      // During prerendering, we don't have Drupal available. The prerendered
      // pages don't need any texts, so this is fine.
      if (import.meta.prerender) {
        return {}
      }

      // With caching on the server.
      if (import.meta.server) {
        const event = useRequestEvent()
        const { value, addToCache } = await useDataCache<MappedTranslations>(
          'translations_' + language.value,
          event,
        )

        if (value) {
          return value
        }

        const data = await useGraphqlQuery('loadTranslations', null, {
          clientContext: {
            language: language.value,
            env: 'server',
          },
        })

        const mapped = mapTranslations(data)
        await addToCache(
          mapped,
          data.extensions?.cacheability?.tagsNuxt,
          60 * 60,
        )
        return mapped
      }

      return useGraphqlQuery('loadTranslations', null, {
        graphqlCaching: {
          client: true,
        },
      }).then(mapTranslations)
    },
    reloadTrigger() {
      return computed(() => language.value)
    },
  }
})
