import React, { Component, PropTypes } from 'react';
import Radium from 'radium';
import { defaultStyle } from 'substyle';

import utils from './utils';

import Suggestion from "./Suggestion";
import LoadingIndicator from "./LoadingIndicator";

class SuggestionsOverlay extends Component {

  static propTypes = {
    suggestions: PropTypes.object.isRequired,

    isLoading: PropTypes.bool,

    onSelect: PropTypes.func,
  };

  static defaultProps = {
    suggestions: {},

    onSelect: () => null
  };

  componentDidUpdate() {
    let { suggestions } = this.refs
    if (!suggestions || suggestions.offsetHeight >= suggestions.scrollHeight) {
      return
    }
    let children = suggestions.children
    let height = suggestions.offsetHeight
    if (children[0]) {
      let childHeight = children[0].offsetHeight
      let windowCount = suggestions.offsetHeight / childHeight
      let currentWindow = Math.floor(this.props.focusIndex / windowCount)
      suggestions.scrollTop = currentWindow * suggestions.offsetHeight
    }
  }

  render() {
    // do not show suggestions until there is some data
    if(utils.countSuggestions(this.props.suggestions) === 0 && !this.props.isLoading) {
      return null;
    }

    return (
      <div
        {...substyle(this.props)}
        onMouseDown={this.props.onMouseDown}>

        <ul ref="suggestions" {...substyle(this.props, "list") }>
          { this.renderSuggestions() }
        </ul>

        { this.renderLoadingIndicator() }
      </div>
    );
  }

  renderSuggestions() {
    return utils.getSuggestions(this.props.suggestions).reduce((result, { suggestions, descriptor }) => [
      ...result,

      ...suggestions.map((suggestion, index) => this.renderSuggestion(
        suggestion,
        descriptor,
        result.length + index
      ))
    ], []);
  }

  renderSuggestion(suggestion, descriptor, index) {
    let id = this.getID(suggestion);
    let isFocused = (index === this.props.focusIndex);

    let { mentionDescriptor, query } = descriptor;

    return (
      <Suggestion { ...substyle(this.props, "item") }
        key={ id }
        id={ id }
        ref={isFocused ? "focused" : null}
        query={ query }
        index={ index }
        descriptor={ mentionDescriptor }
        suggestion={ suggestion }
        focused={ isFocused }
        onClick={ () => this.select(suggestion, descriptor) }
        onMouseEnter={ () => this.handleMouseEnter(index) } />
    );
  }

  getID(suggestion) {
    if(suggestion instanceof String) {
      return suggestion;
    }

    return suggestion.id;
  }

  renderLoadingIndicator () {
    if(!this.props.isLoading) {
      return;
    }

    return <LoadingIndicator { ...substyle(this.props, "loadingIndicator") } />
  }

  handleMouseEnter(index, ev) {
    if(this.props.onMouseEnter) {
      this.props.onMouseEnter(index);
    }
  }

  select(suggestion, descriptor) {
    this.props.onSelect(suggestion, descriptor);
  }

};

export default Radium(SuggestionsOverlay);

const substyle = defaultStyle({
  position: "absolute",
  zIndex: 1,
  backgroundColor: "white",
  marginTop: 14,
  minWidth: 100,

  list: {
    margin: 0,
    padding: 0,
    listStyleType: "none",
  }
});

@@ -501,16 +501,72 @@
 l%0A  %7D;%0A%0A
+  static state = %7B%0A    mouseOverSuggestions: false%0A  %7D%0A%0A
   compon
@@ -694,16 +694,51 @@
 llHeight
+ %7C%7C this.state.mouseOverSuggestions
 ) %7B%0A    
@@ -804,61 +804,103 @@
 let 
-height = suggestions.offsetHeight%0A    if (children%5B0%5D
+childrenOffset = 0%0A    let scrollTop = 0%0A    for (var i = 0; i %3C this.props.focusIndex + 1; i++
 ) %7B%0A
@@ -909,24 +909,24 @@
     
-let 
 child
-Heigh
+renOffse
 t 
++
 = ch
@@ -932,17 +932,17 @@
 hildren%5B
-0
+i
 %5D.offset
@@ -956,27 +956,34 @@
     
-  let windowCount =
+%7D%0A    if (childrenOffset %3E
  sug
@@ -1007,173 +1007,495 @@
 ight
- / childHeight%0A      let currentWindow = Math.floor(this.props.focusIndex / windowCount)%0A      suggestions.scrollTop = currentWindow * suggestions.offsetHeight%0A    %7D
+) %7B%0A      if (children%5Bthis.props.focusIndex + 1%5D) %7B%0A        scrollTop = childrenOffset - children%5Bthis.props.focusIndex + 1%5D.offsetHeight%0A      %7D else %7B%0A        scrollTop = childrenOffset%0A      %7D%0A    %7D%0A    else if (childrenOffset == suggestions.offsetHeight) %7B%0A      scrollTop = childrenOffset%0A    %7D%0A    suggestions.scrollTop = scrollTop%0A  %7D%0A%0A  onMouseEnter() %7B%0A    this.setState(%7B mouseOverSuggestions: true %7D)%0A  %7D%0A%0A  onMouseLeave() %7B%0A    this.setState(%7B mouseOverSuggestions: false %7D)
 %0A  %7D
@@ -1813,16 +1813,116 @@
 estions%22
+%0A          onMouseEnter=%7B::this.onMouseEnter%7D%0A          onMouseLeave=%7B::this.onMouseLeave%7D%0A         
  %7B...sub

Fix focus on selected suggestions.