import "server-only"

import deepmerge from "deepmerge"

import { arrayMerge } from "@/utils/merge"

import { request } from "./request"

import type { BatchRequestDocument } from "graphql-request"

import type { Data } from "@/types/request"
import type { CacheTime } from "@/services/dataCache"

export async function batchRequest<T>(
  queries: (BatchRequestDocument & {
    cacheOptions?: {
      key: string | string[]
      ttl: CacheTime
    }
  })[]
): Promise<Data<T>> {
  try {
    const response = await Promise.allSettled(
      queries.map((query) =>
        request<T>(query.document, query.variables, query.cacheOptions)
      )
    )

    let data = {} as T
    const reasons: PromiseRejectedResult["reason"][] = []
    response.forEach((res) => {
      if (res.status === "fulfilled") {
        data = deepmerge(data, res.value.data, { arrayMerge })
      } else {
        reasons.push(res.reason)
      }
    })

    if (reasons.length) {
      reasons.forEach((reason) => {
        console.error(`Batch request failed`, reason)
      })
    }

    return { data }
  } catch (error) {
    console.error("Error in batched graphql request")
    console.error(error)
    throw new Error("Something went wrong")
  }
}
