import React from 'react';
import map from 'lodash/map';
import reactMixin from 'react-mixin';
import OnClickOutside from 'react-onclickoutside';
import classnames from 'classnames';
import {fetchJsonp} from 'services/fetch';

class TickerAutocomplete extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      tickerInput: props.symbol || '',
      autocomplete: [],
      selected: 0,
    };

    this.handleClickOutside = this.handleClickOutside.bind(this);
  }

  componentWillReceiveProps(nextProps) {
    if (this.props.keepLastSearch && nextProps.symbol !== this.props.symbol) this.setState({tickerInput: (nextProps.symbol || '')});
  }

  handleClickOutside(e) {
    if (this.state.autocomplete) {
      this.updateAutocomplete();
    }
  }

  selectTicker() {
    const symbol = this.state.autocomplete[this.state.selected].symbol;
    this.props.onSelect(symbol);
    this.setState({tickerInput: this.props.keepLastSearch ? symbol : ''});
    this.updateAutocomplete();
  }

  updateAutocomplete(data = []) {
    this.setState({autocomplete: data, selected: 0});
    this.forceUpdate();
  }

  updateselected(i) {
    this.setState({selected: i});
  }

  tickerChange(e) {
    // Send back to the parent, if set
    if (this.props.onChange) {
      this.props.onChange(e);
    }

    const value = e.target.value.replace('"', '');
    this.setState({tickerInput: value});
    // Handle autocomplete
    if (!value.length) {
      this.updateAutocomplete();
    } else {
      fetchJsonp('https://data.benzinga.com/rest/v2/autocomplete?query=' + value, {timeout: 1000})
        .then(req => req.json())
        .then(json => this.updateAutocomplete(json.result))
        .catch(err => this.updateAutocomplete());
    }
  }

  tickerKeyDown(e) {
    const value = e.target.value;
    switch (e.keyCode) {
    case 13:  // Enter
      if (value.length && this.state.autocomplete.length) {
        e.preventDefault();
        this.selectTicker();
      }
      break;
    case 38:  // Up
      if (this.state.autocomplete.length && this.state.selected > 0) {
        e.preventDefault();
        this.dropdownScrollTo(this.state.selected - 1);
        this.setState({selected: this.state.selected - 1});
      }
      break;
    case 40:  // Down
      if (this.state.autocomplete.length && this.state.selected < this.state.autocomplete.length - 1) {
        e.preventDefault();
        this.dropdownScrollTo(this.state.selected + 1);
        this.setState({selected: this.state.selected + 1});
      }
      break;
    default:
      break;
    }
  }

  dropdownScrollTo(index) {
    if (!this.state.autocomplete.length) {
      return;
    }
    const drop = this.refs.dropdown;
    const rowHeight = drop.children[0].offsetHeight; // Add one for border
    const selectedRowTop = rowHeight * index;
    const selectedRowBottom = rowHeight * (index + 1);
    // Check if selected is below current scroll
    if (selectedRowBottom > drop.scrollTop + drop.clientHeight) {
      drop.scrollTop = selectedRowBottom - drop.clientHeight;
    }
    // Check if selected is above current scroll
    if (selectedRowTop < drop.scrollTop) {
      drop.scrollTop = selectedRowTop;
    }
  }

  render() {
    return (
      <div className="autocomplete-ticker">

        <input type="text" className="autocomplete-ticker__input" onChange={(e) => this.tickerChange(e)}
          onKeyDown={(e) => this.tickerKeyDown(e)} value={this.state.tickerInput} placeholder="Search by symbol or security name..." />

        <ul className={classnames('autocomplete-ticker__dropdown', {active: this.state.autocomplete.length})} ref="dropdown">
          {map(this.state.autocomplete, (s, k) =>
            <li key={k} className={classnames({selected: k === this.state.selected})} onMouseOver={() => this.updateselected(k)}
              onClick={() => this.selectTicker(s.symbol)}>
              <span className="autocomplete-ticker__dropdown-exchange">{s.exchange}</span>
              <span className="autocomplete-ticker__dropdown-symbol">{s.symbol}</span>
              <span className="autocomplete-ticker__dropdown-name">{s.name}</span>
            </li>
          )}
        </ul>

      </div>
    );
  }
}

TickerAutocomplete.propTypes = {
  onChange: React.PropTypes.func,
  onSelect: React.PropTypes.func,
  symbol: React.PropTypes.string,
  keepLastSearch: React.PropTypes.bool,
};

reactMixin.onClass(TickerAutocomplete, OnClickOutside);
export default TickerAutocomplete;
