import merge from "deepmerge"

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

import type {
  RequestOptionsWithJSONBody,
  RequestOptionsWithOutBody,
} from "@/types/fetch"
import type { Endpoint } from "./endpoints"

export { endpoints } from "./endpoints"

const defaultOptions: RequestInit = {
  cache: "no-store",
  headers: {
    "Content-Type": "application/json",
  },
  mode: "cors",
}

export async function get(
  endpoint: Endpoint,
  options: RequestOptionsWithOutBody,
  params?: URLSearchParams
) {
  const url = new URL(
    `${env.API_BASEURL}/${endpoint}${params ? `?${params.toString()}` : ""}`
  )
  return fetch(url, merge.all([defaultOptions, { method: "GET" }, options]))
}

export async function patch(
  endpoint: Endpoint,
  options: RequestOptionsWithJSONBody
) {
  const { body, ...requestOptions } = options
  return fetch(
    `${env.API_BASEURL}/${endpoint}`,
    merge.all([
      defaultOptions,
      { body: JSON.stringify(body), method: "PATCH" },
      requestOptions,
    ])
  )
}

export async function post(
  endpoint: Endpoint,
  options: RequestOptionsWithJSONBody
) {
  const { body, ...requestOptions } = options
  return fetch(
    `${env.API_BASEURL}/${endpoint}`,
    merge.all([
      defaultOptions,
      { body: JSON.stringify(body), method: "POST" },
      requestOptions,
    ])
  )
}

export async function remove(
  endpoint: Endpoint,
  options: RequestOptionsWithOutBody
) {
  return fetch(
    `${env.API_BASEURL}/${endpoint}`,
    merge.all([defaultOptions, { method: "DELETE" }, options])
  )
}
