import type Application from '../Application';
import type { AsyncNewComponent, FlarumGenericRoute, NewComponent } from '../Application';
import DefaultResolver from '../resolvers/DefaultResolver';
import IExtender, { IExtensionModule } from './IExtender';

type HelperRoute = (...args: any) => string;

export default class Routes implements IExtender {
  private routes: Record<string, FlarumGenericRoute> = {};
  private helpers: Record<string, HelperRoute> = {};

  /**
   * Add a mithril route to the application.
   *
   * @param name The name of the route.
   * @param path The path of the route.
   * @param component must extend `Page` component.
   * @param resolverClass An optional custom route resolver class.
   */
  add(name: string, path: `/${string}`, component: NewComponent<any> | AsyncNewComponent<any>, resolverClass?: typeof DefaultResolver): Routes {
    const route: FlarumGenericRoute = { path, component };

    if (resolverClass) {
      route.resolverClass = resolverClass;
    }

    this.routes[name] = route;

    return this;
  }

  helper(name: string, callback: HelperRoute): Routes {
    this.helpers[name] = callback;

    return this;
  }

  extend(app: Application, extension: IExtensionModule) {
    Object.assign(app.routes, this.routes);
    Object.assign(app.route, this.helpers);
  }
}
