// 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.

var mercury = require('mercury');
var insertCss = require('insert-css');

var PropertyValueEvent = require('../../lib/mercury/property-value-event');

var exists = require('../../lib/exists');

var namespaceService = require('../../services/namespace/service');
var smartService = require('../../services/smart/service');
var stateService = require('../../services/state/service');

var browseRoute = require('../../routes/browse');
var bookmarksRoute = require('../../routes/bookmarks');
var recommendationsRoute = require('../../routes/recommendations');

var ItemDetails = require('./item-details/index');
var Views = require('./views/index');
var Bookmarks = require('./bookmarks/index');
var Recommendations = require('./recommendations/index');

var browseNamespace = require('./browse-namespace');
var getNamespaceSuggestions = require('./get-namespace-suggestions');

var log = require('../../lib/log')('components:browse');

var css = require('./index.css');
var h = mercury.h;

module.exports = create;
module.exports.render = render;
module.exports.renderHeader = renderHeader;

// While there could be any number of children at the current namespace, only
// show up to 5 suggestions at a time. Rely on the filter to find the rest.
var NAMESPACE_AUTOCOMPLETE_MAX_ITEMS = 5;

/*
 * Browse component provides user interfaces for browsing the Vanadium namespace
 */
function create() {
  loadLearners();

  var selectedItemDetails = new ItemDetails();
  var bookmarks = new Bookmarks();
  var recommendations = new Recommendations();
  var views = new Views();

  var state = mercury.varhash({
    /*
     * Vanadium namespace being displayed and queried
     * Note: This value is persisted between namespace browser sessions.
     * @type {string}
     */
    namespace: mercury.value(''),

    /*
     * Glob query applied to the Vanadium namespace
     * @type {string}
     */
    globQuery: mercury.value(''),

    /*
     * List of direct descendants of the namespace input prefix.
     * Used to make suggestions when interacting with the namespace input.
     * TODO(alexfandrianto): Currently uses obj.mountedName to access the name
     * of the descendant instead of storing the name directly. Works around
     * namespaceService's glob, which updates its returned result over time.
     * @type {Array<Object>}
     */
    namespaceSuggestions: mercury.array([]),

    /*
     * The namespace input prefix is the last namespace value that triggered
     * a glob for direct descendants. Initially, it is null. Upon update of the
     * namespace input prefix, new children will be globbed.
     * @type {string | null}
     */
    namespacePrefix: mercury.value(null),

    /*
     * State of the bookmarks component
     */
    bookmarks: bookmarks.state,

    /*
     * State of the recommendation component
     */
    recommendations: recommendations.state,

    /*
     * State of the views component
     */
    views: views.state,

    /*
     * State of the selected item-details component
     */
    selectedItemDetails: selectedItemDetails.state,

    /*
     * Name of currently selected item
     */
    selectedItemName: mercury.value(''),

    /*
     * Whether loading items has finished.
     * @type {Boolean}
     */
    isFinishedLoadingItems: mercury.value(false),

    /*
     * Specifies what sub page is currently displayed.
     * One of: views, bookmarks, recommendations
     */
    subPage: mercury.value('views'),

    /*
     * Whether the side panel is collapsed or expanded
     * @type {Boolean}
     */
    sidePanelCollapsed: mercury.value(false),

    /*
     * Width of the side panel
     * Note: This value is persisted between namespace browser sessions.
     * @type {String}
     */
    sidePanelWidth: mercury.value('50%')

  });

  var events = mercury.input([
    /*
     * Indicates a request to browse the Vanadium namespace
     * Data of form:
     * {
     *   namespace: '/namespace-root:8881/name/space',
     *   globQuery: '*',
     * }
     * is expected as data for the event
     */
    'browseNamespace',

    /*
     * View components events.
     */
    'views',

    /*
     * Indicates a request to obtain the direct descendants of the given name.
     */
    'getNamespaceSuggestions',

    /*
     * Selects an item.
     * Data of form:
     * {
     *    name: 'object/name'
     * }
     */
    'selectItem',

    /*
     * Events for the ItemDetails component
     */
    'selectedItemDetails',

    /*
     * Displays an error
     * Data of should be an Error object.
     */
    'error',

    /*
     * Displays a toast
     * Data of form:
     * {
          text: 'Saved',
          type: 'error',
          action: function undo(){ // },
          actionText: 'UNDO'
     * }
     */
    'toast',

    /*
     * Event for toggling the expand/collapse state of the sidebar details panel
     */
    'toggleSidePanel',

    /*
     * Drag to resize the side details panel
     */
    'slideSidePanel'
  ]);

  wireUpEvents(state, events);
  events.selectedItemDetails = selectedItemDetails.events;
  events.views = views.events;
  selectedItemDetails.events.toast = events.toast;

  return {
    state: state,
    events: events
  };
}

/*
 * Loads the learners into the smart service upon creation of this component.
 * TODO(aghassemi), TODO(alexfandrianto) Move this into service layers, similar
 * to how `learner-shortcut` is now loaded in the recommendations service.
 */
function loadLearners() {
  smartService.loadOrCreate(
    'learner-method-input',
    smartService.constants.LEARNER_METHOD_INPUT, {
      minThreshold: 0.2,
      maxValues: -1
    }
  ).catch(function(err) {
    log.error(err);
  });
  smartService.loadOrCreate(
    'learner-method-invocation',
    smartService.constants.LEARNER_METHOD_INVOCATION, {
      minThreshold: 0.25,
      maxValues: 1
    }
  ).catch(function(err) {
    log.error(err);
  });
}

/*
 * Renders the top bar, where the user can specify a namespace root.
 */
function renderHeader(browseState, browseEvents, navEvents) {
  return h('div.header-content', [
    renderNamespaceBox(browseState, browseEvents, navEvents)
  ]);
}

function renderSidePanelToggle(browseState, browseEvents) {
  var cssClass = '.core-header.side-panel-toggle';
  if (browseState.sidePanelCollapsed) {
    cssClass += '.collapsed';
  }
  return h('paper-fab' + cssClass, {
    attributes: {
      'mini': true,
      'title': browseState.sidePanelCollapsed ?
        'Show side panel' : 'Hide side panel',
      'icon': browseState.sidePanelCollapsed ?
        'chevron-left' : 'chevron-right',
    },
    'ev-click': mercury.event(browseEvents.toggleSidePanel, {
      collapsed: !browseState.sidePanelCollapsed
    })
  });
}

/*
 * Renders the main body.
 * A toolbar is rendered on top of the mainView and sideView showing the current
 * position in the namespace as well as a globquery searchbox.
 * The mainView contains the shortcuts and names at this point in the namespace.
 * The sideView displays the detail information of the selected name.
 */
function render(browseState, browseEvents, navEvents) {
  insertCss(css);

  var expandCollapse = renderSidePanelToggle(browseState, browseEvents);

  var sideView = [
    expandCollapse,
    ItemDetails.render(
      browseState.selectedItemDetails,
      browseEvents.selectedItemDetails,
      browseState,
      navEvents
    )
  ];

  var mainView;
  switch (browseState.subPage) {
    case 'views':
      mainView = Views.render(browseState.views, browseEvents.views,
        browseState, browseEvents, navEvents);
      break;
    case 'bookmarks':
      mainView = Bookmarks.render(browseState.bookmarks,
        browseState, browseEvents, navEvents);
      break;
    case 'recommendations':
      mainView = Recommendations.render(browseState.recommendations,
        browseState, browseEvents, navEvents);
      break;
    default:
      log.error('Unsupported subPage ' + browseState.subPage);
  }

  // add progressbar and wrap in a container
  var progressbar;
  if (!browseState.isFinishedLoadingItems) {
    progressbar = h('core-tooltip.progress-tooltip', {
      attributes: {
        'label': 'Loading items...',
        'position': 'bottom'
      }
    }, h('paper-progress.delayed', {
      attributes: {
        'indeterminate': true,
        'aria-label': 'Loading items'
      }
    }));
  }

  mainView = h('div.browse-main-wrapper', [
    progressbar,
    mainView
  ]);

  var view = [
    h('core-toolbar.browse-toolbar.core-narrow', [
      renderToolbar(browseState, navEvents)
    ]),
    h('core-drawer-panel', {
      attributes: {
        'id': 'sidebarDrawer',
        'rightDrawer': true,
        'drawerWidth': browseState.sidePanelCollapsed ?
          '0%' : browseState.sidePanelWidth,
        'responsiveWidth': '0px'
      }
    }, [
      h('core-header-panel.browse-main-panel', {
        attributes: {
          'main': true
        }
      }, [
        mainView
      ]),
      h('core-header-panel.browse-details-sidebar', {
        attributes: {
          'drawer': true
        }
      }, [
        h('div.resize-handle', {
          'ev-mousedown': function(e) {
            browseEvents.slideSidePanel({
              rawEvent: e,
              collapsed: browseState.sidePanelCollapsed
            });
          }
        }),
        sideView
      ])
    ])
  ];

  return h('core-drawer-panel', {
    attributes: {
      'drawerWidth': '0px'
    }
  }, [
    h('core-header-panel', {
      attributes: {
        'main': true
      }
    }, [
      view
    ])
  ]);
}

/*
 * Renders the addressbar for entering namespace
 */
function renderNamespaceBox(browseState, browseEvents, navEvents) {
  // Trigger an actual navigation event when value of the inputs change
  var changeEvent = new PropertyValueEvent(function(val) {
    var namespace = browseState.namespace;
    if (exists(val)) {
      namespace = val;
    }
    navEvents.navigate({
      path: browseRoute.createUrl(browseState, {
        namespace: namespace
      })
    });
  }, 'value', true);

  // Change the namespace suggestions if the user types into the namespace box.
  // Ideally, this would be the input event handler. See inputEvent below.
  var trueInputEvent = new PropertyValueEvent(function(val) {
    browseEvents.getNamespaceSuggestions(val);
  }, 'value', false);

  // TODO(alexfandrianto): A workaround for Mercury/Polymer. The
  // paper-autocomplete's input value updates after Mercury captures the event.
  // If we defer handling the event, then the input has time to update itself to
  // the correct, new value.
  var inputEvent = function(ev) {
    setTimeout(trueInputEvent.handleEvent.bind(trueInputEvent, ev), 0);
  };

  // The focus event also retrieves namespace suggestions.
  var focusEvent = inputEvent;

  var children = browseState.namespaceSuggestions.map(
    function renderChildItem(child) {
      return h('paper-item', child.mountedName);
    }
  );

  return h('div.namespace-box',
    h('div', {
      attributes: {
        'layout': 'true',
        'horizontal': 'true'
      }
    }, [
      h('core-tooltip.icontooltip', {
          attributes: {
            'label': 'Reload'
          },
          'position': 'bottom'
        },
        h('paper-icon-button.icon', {
          attributes: {
            'icon': 'refresh',
            'label': 'Reload'
          },
          'ev-click': mercury.send(navEvents.reload)
        })
      ),
      h('core-tooltip.nstooltip', {
          attributes: {
            'label': 'Enter a name to browse, e.g. house/living-room'
          },
          'position': 'bottom'
        },
        h('paper-autocomplete.autocomplete', {
          attributes: {
            'name': 'namespace',
            'value': browseState.namespace,
            'delimiter': '/',
            'flex': 'true',
            'spellcheck': 'false',
            'maxItems': NAMESPACE_AUTOCOMPLETE_MAX_ITEMS
          },
          'ev-focus': focusEvent,
          'ev-input': inputEvent,
          'ev-change': changeEvent
        }, children)
      )
    ])
  );
}

function createActionIcon(tooltip, icon, href, isSelected) {
  var view = h('core-tooltip', {
      'label': tooltip,
      'position': 'bottom'
    },
    h('a', {
      attributes: {
        'href': href
      }
    }, h('paper-icon-button.icon' + (isSelected ? '.selected' : ''), {
      attributes: {
        'icon': icon
      }
    }))
  );

  return view;
}

/*
 * Renders the view switchers for different views and bookmarks, recommendations
 */
function renderToolbar(browseState, navEvents) {

  var selectedActionKey = browseState.subPage;
  if (browseState.subPage === 'views') {
    selectedActionKey = browseState.views.viewType;
  }

  var switchGroup = h('div.icon-group', [
    createActionIcon('Tree view', 'list',
      browseRoute.createUrl(browseState, {
        viewType: 'tree'
      }), selectedActionKey === 'tree'
    ),
    createActionIcon('Radial view', 'image:filter-tilt-shift',
      browseRoute.createUrl(browseState, {
        viewType: 'visualize'
      }), selectedActionKey === 'visualize'
    ),
    createActionIcon('Grid view', 'apps',
      browseRoute.createUrl(browseState, {
        viewType: 'grid'
      }), selectedActionKey === 'grid'
    )
  ]);
  var breadcrumbs = renderBreadcrumbs(browseState, navEvents);
  var ruler = h('div.vertical-ruler');
  var bookmarkGroup = h('div.icon-group', [
    createActionIcon('Bookmarks', 'bookmark-outline',
      bookmarksRoute.createUrl(),
      selectedActionKey === 'bookmarks'
    ),
    createActionIcon('Recent', 'schedule',
      recommendationsRoute.createUrl(),
      selectedActionKey === 'recommendations')
  ]);
  var searchGroup = renderSearch(browseState, navEvents);

  var view = h('div.browse-toolbar-layout', {
    attributes: {
      'layout': 'true',
      'horizontal': 'true'
    }
  }, [
    switchGroup,
    ruler,
    breadcrumbs,
    ruler,
    bookmarkGroup,
    ruler,
    searchGroup
  ]);

  return view;
}


/*
 * Renders the globquery searchbox, used to filter the globbed names.
 */
function renderSearch(browseState, navEvents) {
  // Trigger an actual navigation event when value of the inputs change
  var changeEvent = new PropertyValueEvent(function(val) {
    navEvents.navigate({
      path: browseRoute.createUrl(browseState, {
        globQuery: val,
        // TODO(aghassemi): We only support grid view for search, we could
        // potentially support other views such as tree too but it's tricky.
        viewType: 'grid'
      })
    });
  }, 'value', true);

  var clearSearch;
  if (browseState.globQuery) {
    clearSearch = h('paper-icon-button.icon.clear-search', {
      attributes: {
        'icon': 'clear',
        'label': 'Clear search'
      },
      'ev-click': mercury.event(navEvents.navigate, {
        path: browseRoute.createUrl(browseState)
      })
    });
  }
  return h('div.search-box',
    h('core-tooltip.tooltip', {
        attributes: {
          'label': 'Enter Glob query for searching, e.g., */*/a*'
        },
        'position': 'bottom'
      },
      h('div', {
        attributes: {
          'layout': 'true',
          'horizontal': 'true'
        }
      }, [
        h('core-icon.icon', {
          attributes: {
            'icon': 'search'
          }
        }),
        h('paper-input.input', {
          attributes: {
            'flex': 'true',
            'spellcheck': 'false',
            'label': 'Glob Search'
          },
          'name': 'globQuery',
          'value': browseState.globQuery,
          'ev-change': changeEvent
        }),
        clearSearch
      ])
    )
  );
}

/*
 * Renders the current name being browsed, split into parts.
 * Starts at the top of the name and goes all the way to the selected item.
 * Each name part is a link to a parent.
 */
function renderBreadcrumbs(browseState, navEvents) {

  var name = browseState.selectedItemName || browseState.namespace;
  var isRooted = namespaceService.util.isRooted(name);
  var namespaceParts = namespaceService.util.parseName(name);
  var parentParts = namespaceService.util.parseName(browseState.namespace);
  var breadCrumbs = [];
  if (!isRooted) {
    // Add a relative root (empty namespace)
    var rootUrl = browseRoute.createUrl(browseState, {
      namespace: ''
    });
    breadCrumbs.push(h('li.breadcrumb-item.relative-name' +
      (parentParts.length ? '.breadcrumb-item-prefix' : ''), [
        //TODO(aghassemi) refactor link generation code
        h('a', {
          'href': rootUrl,
          'ev-click': mercury.event(navEvents.navigate, {
            path: rootUrl
          })
        }, '<Home>')
      ]));
  }

  parentParts.pop(); // remove last part (current view root)

  for (var i = 0; i < namespaceParts.length; i++) {
    var namePart = namespaceParts[i].trim();
    var fullName = (isRooted ? '/' : '') +
      namespaceService.util.join(namespaceParts.slice(0, i + 1));

    var url = browseRoute.createUrl(browseState, {
      namespace: fullName
    });

    var isPartOfParent = parentParts.indexOf(namePart) > -1;
    var cssClass = 'breadcrumb-item';
    if (isPartOfParent) {
      cssClass += '.breadcrumb-item-prefix';
    }
    var listItem = h('li.' + cssClass, [
      h('a', {
        'href': url,
        'ev-click': mercury.event(navEvents.navigate, {
          path: url
        })
      }, namePart)
    ]);

    breadCrumbs.push(listItem);
  }

  var bc = h('ul.breadcrumbs', breadCrumbs);

  return h('div.breadcrumbs-wrapper', bc);
}

// Wire up events that we know how to handle
function wireUpEvents(state, events) {
  events.browseNamespace(browseNamespace.bind(null, state, events));
  events.getNamespaceSuggestions(getNamespaceSuggestions.bind(null, state));
  events.selectItem(function(data) {
    state.selectedItemName.set(data.name);
    events.selectedItemDetails.displayItemDetails(data);
  });

  events.toggleSidePanel(function(data) { // hide side panel
    state.sidePanelCollapsed.set(data.collapsed);
    var drawer = document.querySelector('#sidebarDrawer');
    if (!drawer) {
      return;
    }
    //Fire a window resize event when animation ends so components can adjust
    //based on the new view port size
    // TODO(aghassemi): specific to webkit
    drawer.addEventListener('webkitTransitionEnd', fireResizeEvent);
  });

  events.slideSidePanel(function(data) { // resize side panel
    // ignore if not primary button, or if side panel is collapsed
    if (data.rawEvent.button !== 0 || data.collapsed) {
      return;
    }
    var dragX = data.rawEvent.clientX; // initial position of drag target
    var drawer = document.querySelector('#sidebarDrawer');
    var oldP = +drawer.getAttribute('drawerWidth').replace('%', '');
    var oldW = drawer.offsetWidth; // width of both panels in pixels
    drawer.querySelector('::shadow core-selector').
    classList.remove('transition');
    window.addEventListener('mousemove', slideMove);
    window.addEventListener('mouseup', slideEnd);

    function slideMove(e) { // move
      var dx = e.clientX - dragX;
      var newP = Math.min(Math.max(oldP - (dx * 100 / oldW), 10), 90);
      drawer.setAttribute('drawerWidth', newP.toFixed(2) + '%');
      e.preventDefault(); // avoid selecting text
    }

    function slideEnd(e) { // release
        window.removeEventListener('mouseup', slideEnd);
        window.removeEventListener('mousemove', slideMove);
        drawer.querySelector('::shadow core-selector').
        classList.add('transition');
        var drawerWidth = drawer.getAttribute('drawerWidth');

        // async call to persist the drawer width
        stateService.saveSidePanelWidth(drawerWidth);

        state.sidePanelWidth.set(drawerWidth);
        state.sidePanelCollapsed.set(false);
        fireResizeEvent(null);
      } // end slideEnd
  }); // end events.slideSidePanel

  function fireResizeEvent(e) { // resize on end animation
    var evt = document.createEvent('UIEvents');
    evt.initUIEvent('resize', true, false, window, 0);
    window.dispatchEvent(evt);
    if (e !== null) { // not if called by slideEnd
      // TODO(aghassemi): specific to webkit
      document.querySelector('#sidebarDrawer').
      removeEventListener('webkitTransitionEnd', fireResizeEvent);
    }
  }

}