import { defineGraphqlServerOptions } from 'nuxt-graphql-middleware/server-options'
import { extractCacheability } from '~~/server/utils/cacheability'
import { defaultLangcode, langcodes } from '#nuxt-language-negotiation/config'
import type { GraphqlCacheability } from '~~/server/helpers'
import { buildProxyRequestHeaders } from '~~/shared/request'

export default defineGraphqlServerOptions<{
  extensions: {
    cacheability: GraphqlCacheability | null
  }
}>({
  graphqlEndpoint(_event, _operation, _operationName, context) {
    const config = useRuntimeConfig()
    const clientContextLanguage = context?.client?.language
    if (
      clientContextLanguage &&
      langcodes.includes(clientContextLanguage as any)
    ) {
      return `${config.backendUrl}/${clientContextLanguage}/graphql`
    }

    return `${config.backendUrl}/${defaultLangcode}/graphql`
  },
  serverFetchOptions(event) {
    const config = useRuntimeConfig()

    return {
      headers: {
        ...buildProxyRequestHeaders(event),
        'x-drupal-graphql-token': config.drupalGraphqlToken,
      },
    }
  },
  onServerResponse(
    event,
    graphqlResponse,
    _operation,
    _operationName,
    context,
  ) {
    // Pass the set-cookie header from the GraphQL response to the client.
    const setCookie = graphqlResponse.headers.getSetCookie()

    for (const cookie of setCookie) {
      appendResponseHeader(event, 'set-cookie', cookie)
    }

    const cacheability = extractCacheability(graphqlResponse, event)

    const hasMessages = !!(
      graphqlResponse._data?.data &&
      'messengerMessages' in graphqlResponse._data.data &&
      graphqlResponse._data.data.messengerMessages?.length
    )

    // Mark as uncacheable if the response contains Drupal messages.
    if (hasMessages) {
      cacheability.isCacheable = false
    }

    const isServerRequest = context?.client?.env === 'server'

    // This is only provided when the request originates from SSR.
    // We pass information about the cacheability along the GraphQL response,
    // so that the Nuxt app is able to use this to determine if the
    // rendered page can be cached or not.
    const addCacheability = isServerRequest || import.meta.dev

    // Return the GraphQL response.
    return {
      data: graphqlResponse._data!.data,
      errors: graphqlResponse._data!.errors,
      extensions: {
        cacheability: addCacheability ? cacheability : null,
      },
    }
  },
  onServerError(event, error) {
    setResponseStatus(event, 500)
    console.log('onServerError', error)
    return {
      data: null,
      errors: [],
    }
  },
})
