import { cache as reactCache } from "react";
import { HttpLink,ApolloLink } from "@apollo/client";
import { SetContextLink } from "@apollo/client/link/context";
import {
  ApolloClient,
  InMemoryCache,
} from "@apollo/client-integration-nextjs";
import { getSession } from "next-auth/react";
import { getCartToken } from "@/utils/getCartToken";
import { BagistoSession } from "@/types/types";

// 这里注册的是客户端使用的apollo client

let sessionCache: { session: BagistoSession | null; timestamp: number } | null = null;
const SESSION_CACHE_TTL = 5000;

const getSessionForRequest = reactCache(async () => {
  return (await getSession()) as BagistoSession | null;
});

async function getCachedSession(): Promise<BagistoSession | null> {
  if (typeof window === "undefined") {
    return getSessionForRequest();
  }

  const now = Date.now();

  if (sessionCache && now - sessionCache.timestamp < SESSION_CACHE_TTL) {
    return sessionCache.session;
  }
  const session = (await getSession()) as BagistoSession | null;
  sessionCache = { session, timestamp: now };
  return session;
}

export default function makeClient() {
    const httpLink = new HttpLink({
        uri: "/api/graphql",
        credentials: "include",

        /*fetchOptions: {
            // Optional: Next.js-specific fetch options
            // Note: This doesn't work with `export const dynamic = "force-static"`
        },*/
  });


  const authLink = new SetContextLink(async (prevContext) => {
      
      const session = await getCachedSession();
      const userToken = session?.user?.accessToken;
      const guestToken = !userToken ? getCartToken() : null;
      const token = userToken || guestToken;
  
      return {
        headers: {
          ...prevContext.headers,
          ...(token && { Authorization: `Bearer ${token}` }),
          "Content-Type": "application/json",
        },
      };
    });

    const link = ApolloLink.from([authLink, httpLink]);
    return new ApolloClient({
        // ssrMode,
        link,
        cache: new InMemoryCache(),
        // defaultOptions: {
        //     watchQuery: {
        //         fetchPolicy: "cache-first",
        //         nextFetchPolicy: "cache-first",
        //     },
        //     query: {
        //         fetchPolicy: "cache-first",
        //     },
        // },
    });
}
