import logger from '../modules/logger';
const grpc = require('@grpc/grpc-js');
const { BrowserWindow } = require('electron');
import * as electronStore from "./electronStore";
/**
 * Creates a gRPC metadata object that includes the user's token.
 * @param {Event} event - The event that triggered the gRPC call.
 * @return {Promise} A promise that resolves with the metadata object.
 * @example
 * const metadata = await createMetadata(event);
 * client[method](request, metadata, (error, response) => {
 *  // ...
 * });
 */
const createMetadata = async (event) => {
  const webContents = event.sender;
  const win = BrowserWindow.fromWebContents(webContents);
  const metadata = new grpc.Metadata();
  const user =electronStore.get('user') ;

  metadata.add('authorization', `Token ${user.token}`);
  return metadata;
};

/**
 * Invokes a gRPC method and returns a promise that resolves with the response.
 * If the gRPC method returns an error, the promise will reject with the error message.
 * @param {string} client - The name of the gRPC client to invoke.
 * @param {string} method - The name of the gRPC method to invoke.
 * @param {string} request - The request to pass to the gRPC method.
 * @param {string} event - The event to pass to the gRPC method.
 * @param {boolean} isInCludingMetadata - The isInCludingMetadata to pass to the gRPC method.
 * @return {Promise} A promise that resolves with the response or rejects with the error message.
 */

export const grpcClientCall = async (client, method, request, event, isInCludingMetadata = true) => {



  const metadata = isInCludingMetadata ? await createMetadata(event) : '';

  // check token
  event.sender.send('checkToken');

  return new Promise((resolve, reject) => {
    client[method](request, metadata, (error, response) => {
      if (error) {
        if (error.code === grpc.status.PERMISSION_DENIED) {
          const user = electronStore.get("user")
          user.token =  null
          electronStore.set("user",user)
          event.sender.send('user-data',  electronStore.get('user'));
      }



        reject(error);
      } else {

        // fucntion handle response add store electron
        resolve(response);
      }
    });
  });


};

// Define the interceptor
export const loggingInterceptor = (options, nextCall) => {
  return new grpc.InterceptingCall(nextCall(options), {
    start: function (metadata, listener, next) {
      const path = options.method_definition.path;
      logger.info(`Starting call ${path}`);
      logger.debug({ metadata }, 'Metadata: ');
      next(metadata, {
        onReceiveMessage: function (response, next) {
          logger.debug({ response }, 'Received message:');
          next(response);
        },
        onReceiveStatus: function (status, next) {
          if (status.code !== grpc.status.OK) {
            logger.error({ errorMessage: status.details }, `Received status error on ${path}:`);
          } else {
            logger.info({ status: 'success' }, `Received status for ${path} :`);
          }
          next(status);
        },
      });
    },
    sendMessage: function (request, next) {
      logger.debug({ request }, 'Sending message:');
      next(request);
    },
  });
};
