import { Url } from 'url';
import { Request, Response, RequestHandler, NextFunction } from 'express';
export { Request, Response, RequestHandler, NextFunction };

export type IUrlQuery = {
  [key: string]: string;
};

export type IDocumentGetInitialProps = {
  pathname: string; // path section of URL.
  query: IUrlQuery; // query string section of URL parsed as an object.
  asPath: string; // String of the actual path (including the query) shows in the browser.
  req: Request; // HTTP request object (server only).
  res: Response; // HTTP response object (server only).
  err: RequestError; // Error object if any error is encountered during the rendering
  renderPage: () => any;
};

export type RequestError = {
  statusCode: number;
};

export type IRegisterHttpHandler = (
  url: string,
  handler: RequestHandler,
) => IWebApp;

export type RedirectPath = (
  args: {
    url: Url;
    params: { [key: string]: string | number | boolean };
  },
) => string;

/**
 * A web-application configuration.
 */
export type IWebApp = {
  isStarted: boolean;
  use: (...handlers: Array<RequestHandler | IWebApp>) => IWebApp;
  redirect: (fromPath: string, toPath: RedirectPath | string) => IWebApp;
  file: (urlPath: string, filePath: string) => IWebApp;
  static: (urlPath: string, dirPath: string) => IWebApp;
  render: (urlPath: string, pagePath?: string) => IWebApp;
  get: IRegisterHttpHandler;
  post: IRegisterHttpHandler;
  put: IRegisterHttpHandler;
  delete: IRegisterHttpHandler;
  start: (port?: number) => Promise<IWebApp>;
};

export interface IWebAppOptions {
  dir?: string;
  static?: string;
  dev?: boolean; // Command-line: --dev
  port?: number; // Command-line: --port
  silent?: boolean;
}
