import "server-only"

import { GraphQLClient } from "graphql-request"

import { env } from "@/env/server"

import type { DocumentNode } from "graphql"

import type { Data } from "@/types/request"

export async function request<T>(
  client: GraphQLClient,
  query: string | DocumentNode,
  variables?: {},
  next?: NextFetchRequestConfig
): Promise<Data<T>> {
  try {
    if (next) {
      client.requestConfig.next = next
    }

    if (env.PRINT_QUERY) {
      const print = (await import("graphql/language/printer")).print
      const rawResponse = await client.rawRequest<T>(
        print(query as DocumentNode),
        variables,
        {
          access_token: env.CMS_ACCESS_TOKEN,
          "Content-Type": "application/json",
        }
      )

      /**
       * TODO: Send to Monitoring (Logging and Metrics)
       */
      console.log({
        complexityLimit: rawResponse.headers.get("x-query-complexity"),
      })
      console.log({
        referenceDepth: rawResponse.headers.get("x-reference-depth"),
      })
      console.log({ resolverCost: rawResponse.headers.get("x-resolver-cost") })

      return {
        data: rawResponse.data,
      }
    }

    const print = (await import("graphql/language/printer")).print
    const nr = Math.random()
    console.log(`START REQUEST ${nr}`)
    console.time(`OUTGOING REQUEST ${nr}`)
    console.log(`Sending reqeust to ${env.CMS_URL}`)
    console.log(`Query:`, print(query as DocumentNode))
    console.log(`Variables:`, variables)

    const response = await client.request<T>({
      document: query,
      requestHeaders: {
        access_token: env.CMS_ACCESS_TOKEN,
        "Content-Type": "application/json",
      },
      variables,
    })

    console.timeEnd(`OUTGOING REQUEST ${nr}`)
    console.log({ response })

    return { data: response }
  } catch (error) {
    console.error(error)
    throw new Error("Something went wrong")
  }
}
