// Copyright 2015 The Vanadium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

'use strict';

/* jshint newcap: false */
/* global Mousetrap */

var _ = require('lodash');
var async = require('async');
var page = require('page');
var React = require('react');
var url = require('url');
var vanadium = require('vanadium');

var bm = require('./benchmark');
var defaults = require('./defaults');
var domLog = require('./dom_log');
var util = require('./util');
var h = util.h;

////////////////////////////////////////
// Constants

var DISP_TYPE_COLLECTION = 'mem-collection';
var DISP_TYPE_SYNCBASE = 'syncbase';

////////////////////////////////////////
// Global state

// Dispatcher and user's email address, both initialized by initDispatcher.
var disp, userEmail;

// Used for query params.
var u = url.parse(window.location.href, true);

// Mount table name.
var mtName = u.query.mt || (function() {
  var loc = window.location;
  return '/' + loc.hostname + ':' + (Number(loc.port) + 1);
}());

// See TODO in SyncbaseDispatcher.listIdToSgName to understand why we use an
// absolute name here.
var syncbaseName = u.query.sb || (mtName + '/syncbase');

////////////////////////////////////////
// Helpers

function noop() {}

function initVanadium(cb) {
  cb = util.logFn('initVanadium', cb);
  var vanadiumConfig = {
    logLevel: vanadium.vlog.levels.INFO,
    namespaceRoots: [mtName],
    proxy: u.query.proxy
  };
  vanadium.init(vanadiumConfig, cb);
}

function initDispatcher(dispType, syncbaseName, cb) {
  var clientCb = cb;
  cb = function(err, resDisp) {
    if (err) return clientCb(err);
    disp = resDisp;
    clientCb();
  };
  if (dispType === DISP_TYPE_COLLECTION) {
    defaults.initCollectionDispatcher(cb);
  } else if (dispType === DISP_TYPE_SYNCBASE) {
    initVanadium(function(err, rt) {
      if (err) return cb(err);
      userEmail = blessingToEmail(rt.accountName);
      defaults.initSyncbaseDispatcher(rt, syncbaseName, cb);
    });
  } else {
    process.nextTick(function() {
      cb(new Error('unknown dispType: ' + dispType));
    });
  }
}

function alertOnError(err) {
  if (!err) return;
  alert(err);
  throw err;
}

// HACKETY HACK for demo.
function emailToBlessing(email) {
  return 'dev.v.io/u/' + email;
}
function blessingToEmail(blessing) {
  var parts = blessing.split('/');
  console.assert(parts.length >= 3);
  return parts[2];
}

function activateInput(input) {
  input.focus();
  input.select();
}

function okCancelEvents(cbs, cancelOnBlur) {
  var ok = cbs.ok || noop;
  var cancel = cbs.cancel || noop;
  function done(e) {
    var value = e.target.value;
    if (value) {
      ok(value, e);
    } else {
      cancel(e);
    }
  }
  return {
    onKeyDown: function(e) {
      if (e.which === 27) {  // esc
        cancel(e);
      }
    },
    onKeyUp: function(e) {
      if (e.which === 13) {  // enter
        done(e);
      }
    },
    onBlur: function(e) {
      if (cancelOnBlur) {
        cancel(e);
      } else {
        done(e);
      }
    }
  };
}

////////////////////////////////////////
// Components

var TagsPane = React.createFactory(React.createClass({
  displayName: 'TagsPane',
  render: function() {
    var that = this;
    var tagFilter = this.props.tagFilter;
    var tagInfos = [], totalCount = 0;
    _.each(this.props.todos, function(todo) {
      _.each(todo.tags, function(tag) {
        var tagInfo = _.find(tagInfos, {tag: tag});
        if (!tagInfo) {
          tagInfos.push({tag: tag, count: 1, selected: tagFilter === tag});
        } else {
          tagInfo.count++;
        }
      });
      totalCount++;
    });
    tagInfos = _.sortBy(tagInfos, 'tag');
    // Add "All items" tag.
    tagInfos.unshift({
      tag: null,
      count: totalCount,
      selected: tagFilter === null
    });
    return h('div#tags-pane', [
      h('div.label', {key: 'label'}, 'Show:')
    ].concat(_.map(tagInfos, function(tagInfo) {
      var count = h('span.count', {key: 'count'}, '(' + tagInfo.count + ')');
      return h('div.tag' + (tagInfo.selected ? '.selected' : ''), {
        key: 'tag:' + (tagInfo.tag || ''),
        onClick: function() {
          var newTagFilter = tagFilter === tagInfo.tag ? null : tagInfo.tag;
          that.props.setTagFilter(newTagFilter);
        }
      }, [(tagInfo.tag || 'All items'), count]);
    })));
  }
}));

var TodoTags = React.createFactory(React.createClass({
  displayName: 'TodoTags',
  getInitialState: function() {
    return {
      addingTag: false
    };
  },
  componentDidUpdate: function(prevProps, prevState) {
    if (this.state.addingTag && !prevState.addingTag) {
      activateInput(this.getDOMNode().querySelector('#edittag-input'));
    }
  },
  render: function() {
    var that = this;
    var children = [];
    _.each(this.props.tags, function(tag) {
      children.push(h('div.tag.removable', {key: tag}, [
        h('div.name', {key: 'name'}, tag),
        h('div.remove', {
          key: 'remove',
          onClick: function(e) {
            disp.removeTag(that.props.todoId, tag, alertOnError);
          }
        })
      ]));
    });
    if (this.state.addingTag) {
      children.push(h('div.tag.edittag', {
        key: 'edittag'
      }, h('input#edittag-input', _.assign({
        type: 'text',
        defaultValue: ''
      }, okCancelEvents({
        ok: function(value) {
          disp.addTag(that.props.todoId, value, alertOnError);
          that.setState({addingTag: false});
        },
        cancel: function() {
          that.setState({addingTag: false});
        }
      })))));
    } else {
      children.push(h('div.tag.addtag', {
        key: 'addtag',
        onClick: function() {
          that.setState({addingTag: true});
        }
      }, '+tag'));
    }
    return h('div.item-tags', children);
  }
}));

var Todo = React.createFactory(React.createClass({
  displayName: 'Todo',
  getInitialState: function() {
    return {
      editingText: false
    };
  },
  componentDidUpdate: function(prevProps, prevState) {
    if (this.state.editingText && !prevState.editingText) {
      activateInput(this.getDOMNode().querySelector('#todo-input'));
    }
  },
  render: function() {
    var that = this, todo = this.props.todo, et = this.state.editingText;
    var hDescription;
    if (et) {
      hDescription = h('div.description', {
        key: 'description'
      }, h('input#todo-input', _.assign({
        type: 'text',
        defaultValue: todo.text
      }, okCancelEvents({
        ok: function(value) {
          disp.editTodoText(todo._id, value, alertOnError);
          that.setState({editingText: false});
        },
        cancel: function() {
          that.setState({editingText: false});
        }
      }))));
    } else {
      hDescription = h('div.description', {
        key: 'description',
        onDoubleClick: function() {
          that.setState({editingText: true});
        }
      }, todo.text);
    }
    var opts = (et ? '.edit' : '') + (todo.done ? '.done' : '');
    return h('li.todo-row' + opts, [
      h('div.destroy', {
        key: 'destroy',
        onClick: function() {
          disp.removeTodo(todo._id, alertOnError);
        }
      }),
      h('input.checkbox', {
        key: 'checkbox',
        type: 'checkbox',
        checked: todo.done,
        onChange: function() {
          disp.markTodoDone(todo._id, !todo.done, alertOnError);
        }
      }),
      hDescription,
      TodoTags({key: 'tags', todoId: todo._id, tags: todo.tags})
    ]);
  }
}));

var TodosPane = React.createFactory(React.createClass({
  displayName: 'TodosPane',
  render: function() {
    var that = this;
    var children = [];
    if (!this.props.listId) {
      children.push(h('div.msg', {key: 'msg'}, 'No list selected.'));
    } else if (!this.props.todos) {
      children.push(h('div.msg', {key: 'msg'}, 'Loading...'));
    } else {
      var tagFilter = this.props.tagFilter, items = [];
      _.each(this.props.todos, function(todo) {
        if (tagFilter === null || _.contains(todo.tags, tagFilter)) {
          items.push(Todo({key: todo._id, todo: todo}));
        }
      });
      children.push(h('div#new-todo', {key: 'new-todo'}, h('input', _.assign({
        type: 'text',
        placeholder: 'New item'
      }, okCancelEvents({
        ok: function(value, e) {
          disp.addTodo(that.props.listId, {
            text: value,
            tags: tagFilter ? [tagFilter] : [],
            done: false,
            timestamp: Date.now()
          }, alertOnError);
          e.target.value = '';
        }
      })))));
      children.push(h('ul#todo-list', {key: 'todo-list'}, items));
    }
    return h('div#todos-pane', children);
  }
}));

var List = React.createFactory(React.createClass({
  displayName: 'List',
  getInitialState: function() {
    return {
      editingName: false
    };
  },
  componentDidUpdate: function(prevProps, prevState) {
    if (this.state.editingName && !prevState.editingName) {
      activateInput(this.getDOMNode().querySelector('#list-name-input'));
    }
  },
  render: function() {
    var that = this, list = this.props.list;
    var children = [];
    // http://facebook.github.io/react/docs/forms.html#controlled-components
    if (this.state.editingName) {
      children.push(h('div.edit', {
        key: 'edit'
      }, h('input#list-name-input', _.assign({
        type: 'text',
        defaultValue: list.name
      }, okCancelEvents({
        ok: function(value) {
          disp.editListName(list._id, value, alertOnError);
          that.setState({editingName: false});
        },
        cancel: function() {
          that.setState({editingName: false});
        }
      })))));
    } else {
      if (this.props.useSyncbase) {
        children.push(h('div.status', {
          key: 'status',
          onClick: function(e) {
            e.stopPropagation();
            that.props.openStatusDialog(list._id);
          }
        }, h('div.circle' + (list.sg ? '.shared' : ''))));
      }
      children.push(h('div.display', {
        key: 'display'
      }, h('a.list-name' + (list.name ? '' : '.empty'), {
        href: '/lists/' + list._id,
        onClick: function(e) {
          e.preventDefault();
        }
      }, list.name)));
    }
    return h('div.list' + (that.props.selected ? '.selected' : ''), {
      onClick: function() {
        that.props.setListId(list._id);
      },
      onDoubleClick: function() {
        that.setState({editingName: true});
      }
    }, children);
  }
}));

var StatusPane = React.createFactory(React.createClass({
  displayName: 'StatusPane',
  componentDidMount: function() {
    var that = this;
    activateInput(this.getDOMNode().querySelector('#share-input'));
    Mousetrap.bind('esc', function() {
      that.props.close();
    });
  },
  componentWillUnmount: function() {
    Mousetrap.unbind('esc');
  },
  render: function() {
    var that = this, list = this.props.list, shared = Boolean(list.sg);
    var hShare;
    if (shared) {
      if (util.DEMO) {
        hShare = h('span', list.sg.name);
      } else {
        var loc = window.location;
        var encodedSgName = util.strToHex(list.sg.name);
        var shareUrl = '/share/' + encodedSgName + loc.search;
        hShare = h('a', {href: shareUrl}, shareUrl);
      }
    }
    return h('div#status-pane', {
      onClick: function(e) {
        e.stopPropagation();
        if (e.target === e.currentTarget) {
          that.props.close();
        }
      }
    }, h('div.status-dialog', [
      h('h3', {key: 'title'}, 'Share with others'),
      h('input#share-input', _.assign({
        key: 'input',
        placeholder: 'Add email address',
      }, okCancelEvents({
        ok: function(value, e) {
          e.target.value = '';
          // TODO(sadovsky): Better input validation.
          if (!value.includes('@') || !value.includes('.')) {
            alert('Invalid email address.');
            return;
          }
          var sgName = disp.listIdToSgName(list._id);
          if (shared) {
            disp.addToSyncgroupPerms(sgName, emailToBlessing(value),
                                     alertOnError);
          } else {
            disp.createSyncgroup(sgName, [
              emailToBlessing(userEmail),
              emailToBlessing(value)
            ], mtName, alertOnError);
          }
        },
        cancel: function(e) {
          e.target.value = '';
        }
      }, true))),
      !shared ? null : h('div.shared-with', {key: 'shared-with'}, [
        h('div.subtitle', {key: 'subtitle'}, 'Currently shared with'),
        h('div.emails', {
          key: 'emails'
        }, _.map(list.sg.spec.perms.get('Admin')['in'], function(blessing) {
          return blessingToEmail(blessing);
        }).join(', '))
      ]),
      !shared ? null : h('div.url', {key: 'url'}, [
        h('div.subtitle', {key: 'subtitle'}, 'Thing to share with invitees'),
        h('div.value', {key: 'value'}, hShare)
      ]),
      h('div.close', {
        key: 'close',
        onClick: function() {
          that.props.close();
        }
      })
    ]));
  }
}));

var ListsPane = React.createFactory(React.createClass({
  displayName: 'ListsPane',
  render: function() {
    var that = this;
    var children = [h('div.lists-title', {key: 'title'}, 'Todo Lists')];
    if (!this.props.lists) {
      children.push(h('div.msg', {key: 'msg'}, 'Loading...'));
    } else {
      children.push(h('div', {
        key: 'lists'
      }, _.map(this.props.lists, function(list) {
        return List({
          key: list._id,
          list: list,
          selected: that.props.listId === list._id,
          useSyncbase: that.props.useSyncbase,
          setListId: that.props.setListId,
          openStatusDialog: that.props.openStatusDialog
        });
      })));
      children.push(h('div.input-row', {
        key: 'new-list'
      }, h('input', _.assign({
        type: 'text',
        placeholder: 'New list'
      }, okCancelEvents({
        ok: function(value, e) {
          disp.addList({name: value}, function(err, listId) {
            alertOnError(err);
            that.props.setListId(listId);
          });
          e.target.value = '';
        }
      })))));
      if (util.DEMO && that.props.useSyncbase) {
        children.push(h('div.input-row', {
          key: 'join-list'
        }, h('input', _.assign({
          type: 'text',
          placeholder: 'Join list'
        }, okCancelEvents({
          ok: function(value, e) {
            that.props.joinSyncgroup(value.trim(), alertOnError);
            e.target.value = '';
          }
        })))));
      }
    }
    if (that.props.useSyncbase) {
      children.push(h('div.user-id', {'data-text': userEmail}, userEmail));
    }
    return h('div#lists-pane', children);
  }
}));

var DispType = React.createFactory(React.createClass({
  render: function() {
    var that = this;
    return h('div#disp-type.' + this.props.dispType, {
      onClick: function() {
        that.props.toggleDispType();
      }
    }, this.props.dispType);
  }
}));

var Page = React.createFactory(React.createClass({
  displayName: 'Page',
  getInitialState: function() {
    return {
      dispInitialized: false,
      // Note, SG data is attached to individual list items.
      lists: {seq: 0, items: null},  // all lists
      todos: {},  // map of listId to {seq, items}
      listId: this.props.initialListId,  // current list
      tagFilter: null,  // current tag
      showStatusDialog: false
    };
  },
  getLists_: function(cb) {
    disp.getLists(function(err, lists) {
      if (err) return cb(err);
      // Sort lists by name in the UI.
      return cb(null, _.sortBy(lists, 'name'));
    });
  },
  getTodos_: function(listId, cb) {
    if (!listId) {
      return process.nextTick(cb);
    }
    disp.getTodos(listId, function(err, todos) {
      if (err) return cb(err);
      // Sort todos by timestamp in the UI.
      return cb(null, _.sortBy(todos, 'timestamp'));
    });
  },
  setListId_: function(listId) {
    if (listId === this.state.listId) return;
    this.setState({
      listId: listId,
      tagFilter: null
    });
  },
  updateURL: function() {
    var listId = this.state.listId;
    var pathname = !listId ? '/' : '/lists/' + listId;
    // Note, this doesn't trigger a re-render; it's purely visual.
    window.history.replaceState({}, '', pathname + window.location.search);
  },
  // Updates state.lists. Calls cb once the setState call has completed.
  // TODO(sadovsky): If possible, simplify how we deal with concurrent state
  // updates, here and elsewhere. The current approach is fairly subtle and
  // error-prone. Our goal is simple: never show stale data, even in the
  // presence of sync.
  updateLists_: function(cb) {
    var that = this;
    var listsSeq = this.state.lists.seq + 1;
    this.getLists_(function(err, lists) {
      if (err) return cb(err);
      // Use setState(cb) form to ensure atomicity.
      // References: https://goo.gl/CZ82Vp and https://goo.gl/vVCp8B
      that.setState(function(state) {
        if (listsSeq <= state.lists.seq) {
          return {};
        }
        return {lists: {seq: listsSeq, items: lists}};
      }, cb);
    });
  },
  // Updates state.todos[listId]. Calls cb once the setState call has completed.
  updateTodos_: function(listId, cb) {
    var that = this;
    var stateTodos = this.state.todos[listId];
    var todosSeq = (stateTodos ? stateTodos.seq : 0) + 1;
    this.getTodos_(listId, function(err, todos) {
      if (err) return cb(err);
      // Use setState(cb) form to ensure atomicity.
      // References: https://goo.gl/CZ82Vp and https://goo.gl/vVCp8B
      that.setState(function(state) {
        var stateTodos = state.todos[listId];
        if (stateTodos && todosSeq <= stateTodos.seq) {
          return {};
        }
        state.todos[listId] = {seq: todosSeq, items: todos};
        return {todos: state.todos};
      }, cb);
    });
  },
  // Joins the specified syncgroup and displays the associated list.
  joinSyncgroup_: function(sgName, cb) {
    var that = this;
    console.assert(this.props.dispType === DISP_TYPE_SYNCBASE);
    disp.joinSyncgroup(sgName, function(err) {
      // Note, joinSyncgroup is a noop (no error) if the caller is already a
      // member, which is the desired behavior here.
      if (err) return cb(err);
      var listId = disp.sgNameToListId(sgName);
      // TODO(sadovsky): Wait for all items to get synced before attempting to
      // read them?
      that.updateTodos_(listId, function(err) {
        if (err) return cb(err);
        // Note, componentDidUpdate() will update the url.
        that.setState({listId: listId}, cb);
      });
    });
  },
  componentWillMount: function() {
    var that = this, props = this.props;
    if (props.benchmark) {
      initVanadium(function(err, rt) {
        alertOnError(err);
        bm.runBenchmark(rt, props.syncbaseName, alertOnError);
      });
      return;
    }
    initDispatcher(props.dispType, props.syncbaseName, function(err) {
      alertOnError(err);
      that.setState({dispInitialized: true}, function() {
        if (props.joinSgName) {
          that.joinSyncgroup_(props.joinSgName, alertOnError);
        }
      });
    });
  },
  componentDidMount: function() {
    console.assert(!this.state.dispInitialized);
  },
  componentDidUpdate: function(prevProps, prevState) {
    var that = this;
    this.updateURL();

    // Only run the code below when disp has just been initialized.
    if (prevState.dispInitialized || !this.state.dispInitialized) {
      return;
    }

    // Returns the list id for the list that should be displayed.
    function getListId() {
      var listId = that.state.listId, lists = that.state.lists.items;
      // If listId refers to an unknown list, set it to null.
      if (!_.includes(_.pluck(lists, '_id'), listId)) {
        listId = null;
      }
      // If listId is not set, set it to the id of the first list.
      if (!listId && lists.length > 0) {
        listId = lists[0]._id;
      }
      return listId;
    }

    // TODO(sadovsky): Only read (and only redraw) what's needed based on what
    // changed.
    disp.on('change', function(fromSync) {
      var onChangeDone = util.logFn('onChange', alertOnError);
      that.updateLists_(function(err) {
        alertOnError(err);
        if (fromSync) {
          var listIds = _.pluck(that.state.lists.items, '_id');
          async.each(listIds, function(listId, cb) {
            that.updateTodos_(listId, cb);
          }, onChangeDone);
        } else {
          var listId = getListId();
          that.updateTodos_(listId, onChangeDone);
        }
      });
    });

    disp.on('watchError', function(err) {
      alertOnError(new Error('Error in Syncbase watch stream. Data may be stale. Please refresh this page.\n' + err));  // jshint ignore:line
    });

    // Load initial lists and todos. Note that changes can come in concurrently
    // via sync.
    this.updateLists_(function(err) {
      alertOnError(err);
      // Set initial listId if needed.
      var listId = getListId();
      if (listId !== that.state.listId) {
        that.setState({listId: listId});
      }
      // Get todos for all lists.
      var listIds = _.pluck(that.state.lists.items, '_id');
      async.each(listIds, function(listId, cb) {
        that.updateTodos_(listId, cb);
      }, function(err) {
        alertOnError(err);
      });
    });
  },
  render: function() {
    if (this.props.benchmark) {
      return null;
    }

    var that = this, listId = this.state.listId;
    var useSyncbase = this.props.dispType === DISP_TYPE_SYNCBASE;
    // If currTodos is {}, todos.items will be undefined, as desired.
    var currTodos = this.state.todos[listId] || {};
    return h('div#page-pane', [
      DispType({
        key: 'DispType',
        dispType: this.props.dispType,
        toggleDispType: function() {
          var newDispType = DISP_TYPE_SYNCBASE;
          if (that.props.dispType === DISP_TYPE_SYNCBASE) {
            newDispType = DISP_TYPE_COLLECTION;
          }
          window.location.replace('/?d=' + newDispType);
        }
      }),
      ListsPane({
        key: 'ListsPane',
        lists: this.state.lists.items,
        listId: listId,
        useSyncbase: useSyncbase,
        setListId: this.setListId_,
        openStatusDialog: function(listId) {
          console.assert(useSyncbase);
          if (that.state.showStatusDialog) {
            return;
          }
          // Note, setState just schedules render, so setListId's state update
          // will be merged with ours.
          that.setListId_(listId);
          that.setState({showStatusDialog: true});
        },
        joinSyncgroup: function(sgName, cb) {
          that.joinSyncgroup_(sgName, cb);
        }
      }),
      h('div#tags-and-todos-pane', {key: 'tags-and-todos-pane'}, [
        TagsPane({
          key: 'TagsPane',
          todos: currTodos.items,
          tagFilter: this.state.tagFilter,
          setTagFilter: function(tagFilter) {
            that.setState({tagFilter: tagFilter});
          }
        }),
        TodosPane({
          key: 'TodosPane',
          todos: currTodos.items,
          listId: listId,
          tagFilter: this.state.tagFilter
        })
      ]),
      !this.state.showStatusDialog ? null : StatusPane({
        key: 'status',
        list: _.find(this.state.lists.items, {_id: listId}),
        close: function() {
          that.setState({showStatusDialog: false});
        }
      })
    ]);
  }
}));

////////////////////////////////////////
// Initialization

// DOM log module. Developers can press Ctrl+Shift+L (or Meta+Shift+L) to toggle
// visibility of the log.
domLog.init();

function render(props) {
  var defaultDispType = util.DEMO ? DISP_TYPE_SYNCBASE : DISP_TYPE_COLLECTION;
  props = _.assign({
    dispType: u.query.d || defaultDispType,
    syncbaseName: syncbaseName,
    benchmark: Boolean(u.query.bm)
  }, props);
  React.render(Page(props), document.querySelector('#page'));
}

// Configure Page.js routes. Note, ctx here is a Page.js context object, not a
// Vanadium context object.
page('/', function(ctx) {
  render();
});
page('/lists/:listId', function(ctx) {
  render({initialListId: ctx.params.listId});
});
page('/share/:encodedSgName', function(ctx) {
  render({joinSgName: util.hexToStr(ctx.params.encodedSgName)});
});

// Start Page.js router.
// https://visionmedia.github.io/page.js/
page({click: false});
