import Route from 'ember-route';

/*
 * Many routes in web-client call `this.render` to get a specific view
 * and controller into the UI. Refactoring all these usages of views
 * controllers into components is non-trivial, so this implements a
 * patched version of `this.render` compatible with the new and idiomatically
 * preferred `renderComponentOutlet`.
 *
 * Here, `render` will first clear any entry on the component-outlet-service
 * with the name of the named outlet, then it will continue default behavior.
 */

Route.reopen({

  // options = {
  //   into: 'application',
  //   outlet: 'left',
  //   model: {}
  // }
  //
  // optionsForServiceDisconnect = {
  //   sourceTemplateName: 'application',
  //   outlet: 'left'
  // }
  _legacyRenderOptionsToDisconnectOptions(legacyRenderOptions) {
    return {
      sourceTemplateName: legacyRenderOptions.into || this.routeName.replace(/\./g, '/'),
      outlet: legacyRenderOptions.outlet || 'main'
    };
  },

  // options = {
  //   sourceTemplateName: 'application',
  //   outlet: 'left',
  //   model: {}
  // }
  //
  // optionsForDisconnect = {
  //   parentView: 'application',
  //   outlet: 'left'
  // }
  _renderComponentOptionsToLegacyDisconnectOptions(renderComponentOptions) {
    return {
      parentView: renderComponentOptions.sourceTemplateName,
      outlet: renderComponentOptions.outlet
    };
  },

  render(componentName, options={}) {
    let service = this.container.lookup('service:component-outlet');
    service.disconnect(this._legacyRenderOptionsToDisconnectOptions(options));
    return this._super(...arguments);
  },

  /*
   * renderComponentOutlet
   *
   * render a component into a {{component-outlet}} component.
   *
   * This is replacement for using this.render on routes (generally called
   * "named outlets"). this.render uses views and controllers, where this
   * function uses components for the same use-case.
   *
   * You can use this tool to replace content using a named outlet, making it
   * a good migration tool away from views and controllers.
   *
   * For example, you may toggle between controllers and an outlet:
   *
   *   if (this.isNavigating) {
   *     this.render('navigation', {outlet: 'left', into: 'application'});
   *     this.isNavigating = false;
   *   } else {
   *     this.renderComponentOutlet('some-other-ui', {sourceTemplateName: 'application', outlet: 'left'});
   *     this.isNavigating = true;
   *   }
   *
   * The hook takes two arguments, a component name and options.
   *
   *   * First arg is componentName, which one to render
   *   * Second arg is options.
   *     * options.sourceTemplateName - should be the template rendering into
   *     * options.outlet - the name of the outlet
   *     * options.model - an optional model to be passed as the model attr
   *       to the invoked component.
   *
   * See also app/components/component-outlet.js for futher information.
   */
  renderComponentOutlet(componentName, options) {
    this.disconnectOutlet(this._renderComponentOptionsToLegacyDisconnectOptions(options));
    let service = this.container.lookup('service:component-outlet');
    service.render(componentName, options);
  }

});
