import { ApolloClient, type FieldPolicy, HttpLink, InMemoryCache } from "@apollo/client"
import { sendMessage } from "./messaging"

const dateField: FieldPolicy<Date> = {
  read: date => (typeof date === "string" ? new Date(date) : date),
}

export const client = new ApolloClient({
  cache: new InMemoryCache({
    typePolicies: {
      Preferences: {
        keyFields: [],
      },
      File: {
        merge: true,
        fields: {
          createdAt: dateField,
          updatedAt: dateField,
          lastRequestedAt: dateField,
        },
      },
      Query: {
        fields: {
          file(_, { args, toReference }) {
            return toReference({ __typename: "File", id: args!.id })
          },
          favicon(_, { args, toReference }) {
            return toReference({ __typename: "Favicon", url: args!.url })
          },
        },
      },
    },
  }),

  link: new HttpLink({
    uri: `${location.origin}/api`,
    async fetch(_, init) {
      const body = JSON.parse(init!.body as string)
      if (process.env.NODE_ENV === "development") {
        // const { operationName, variables, ...rest } = body
        // console.log("gql", { ...rest, variables });
      }
      const [result, error] = await sendMessage({
        method: "gql",
        body,
      })

      if (process.env.NODE_ENV === "development" && error) {
        if (result?.errors) console.error(result.errors)
        console.error(error)
      }

      return {
        ok: !error,
        redirected: false,
        status: error ? 400 : 200,
        json: async () => result,
        text: async () => JSON.stringify(result),
      } as Response
    },
  }),
})
