/**
 * Generate values  based on the Observable and object template.
 * Similar to `Bacon.combineTemplate`.
 *
 * ```
 *   var combineTemplate = require('rx.observable.combinetemplate')
 *
 *   // observables
 *   var password, username, firstname, lastname;
 *
 *   // combine and publish structure!
 *   var loginInfo = combineTemplate({
 *     magicNumber: 3,
 *     userid: username,
 *     passwd: password,
 *     name: { first: firstname, last: lastname }
 *   });
 *
 *   loginInfo.subscribe((v) => {
 *     console.log(v);
 *   });
 * ```
 *
 * @param {Object} templateObject
 * @returns {Rx.Observable}
 */
function combineTemplate(templateObject) {
  templateObject = templateObject || {};

  // TODO avoid clone `Rx.Observable`
  var clonedTemplate = clone(templateObject);
  var collections = collectTargetObservablesAndContext(templateObject);

  return Rx.Observable.combineLatest(
    collections.targets,
    createCombineObserver(collections.contexts, clonedTemplate)
  );
}
export default function model(events) {
  const ENDPOINT = 'http://jsonplaceholder.typicode.com/users/';
  const endpoint$ = events.DOM.submitGetUserInfo$
    .withLatestFrom(events.DOM.changeUserId$,
      (submit, userid) => {
        return userid ? ENDPOINT + userid : ENDPOINT + '';
      });

  const userId$ = events.DOM.changeUserId$
    .map( (userid) => userid)
    .startWith('');

  const userInfo$ = events.HTTP.user$
    .startWith({});

  const user$ = Observable
    .combineLatest(userId$, userInfo$,
      (id, info) => {
        const u = {id: ''};
        if (id) {
          u.id = id;
          if (info) {
            u.query = ENDPOINT + id;
            u.name = info.name;
            u.email = info.email;
            u.site = info.website;
          }
        }
        return u;
      });


  // return states
  return {
    DOM: {
      user$: user$
    },
    HTTP: {
      user$: endpoint$
    }
  };
}