import expressAsync from './expressAsync.js';

type HandlerOptions = {
  middleware?: any;
  func: ((req: any, res: any) => Promise<any>) | ((req: any, res: any, data: any) => Promise<any>);
};

/**
 * This function is a tautology, but it's useful for type checking
 * to ensure the handler is declared correctly.
 * It's meant to wrap the functions that get declared in other files
 */
export const declareHandler = (options: HandlerOptions): HandlerOptions => {
  return {
    func: expressAsync(options.func),
    middleware: options.middleware,
  };
};

/**
 * This will create a route and bind it to the handler function
 * @param routeFn This is the app.post or app.get function
 * @param route A string for the route
 * @param handler The handler object generated by declareHandler
 * @param data Optional data to pass to the handler function
 */
export const bind = (routeFn: Function, route: string, handler: HandlerOptions, data?: any) => {
  if (!data) {
    // If there's no data, just let the function pass the 2 standard variables
    if (handler.middleware) {
      routeFn(route, handler.middleware, handler.func);
    } else {
      routeFn(route, handler.func);
    }
  } else {
    // If there's data pass the data into the handler function
    if (handler.middleware) {
      routeFn(route, handler.middleware, (req: any, res: any) => handler.func(req, res, data));
    } else {
      routeFn(route, (req: any, res: any) => handler.func(req, res, data));
    }
  }
};
