import { BrowserWindow, ipcMain } from "electron";
import log from "electron-log/main";
import { GraphQLClient, RequestMiddleware } from "graphql-request";
import errorTypeCheck from "../../util/errorTypeCheck.js";
import ipcTypes from "../../util/ipcTypes.json";
import store from "../store/store.js";

const requestMiddleware: RequestMiddleware = async (request) => {
  const token = await getTokenFromRenderer();
  log.info(
    `%c[Graphql Request]%c${request.operationName}`,
    "color: red",
    "color: green",
    request,
  );

  return {
    ...request,
    headers: { ...request.headers, Authorization: `Bearer ${token}` },
  };
};

const client: GraphQLClient = new GraphQLClient(
  store.get("app.isTest") || false
    ? import.meta.env.VITE_GRAPHQL_ENDPOINT_TEST
    : import.meta.env.VITE_GRAPHQL_ENDPOINT,
  {
    requestMiddleware,
  },
);

export async function getTokenFromRenderer(): Promise<string> {
  return new Promise((resolve) => {
    try {
      const mainWindow = BrowserWindow.getAllWindows()[0]; //TODO: Filter to only main window once a proper key has been set.
      //TODO: Verify that this will work if the app is minimized/closed.
      mainWindow.webContents.send(ipcTypes.toRenderer.user.getToken);
    } catch (error) {
      log.error(
        "Unable to send request to renderer process for token",
        errorTypeCheck(error),
      );
    }

    // Set up one-time listener for the response
    ipcMain.once(ipcTypes.toMain.user.getTokenResponse, (_, token: string) => {
      resolve(token);
    });
  });
}

export default client;
