// @flow
import React, { Component } from 'react'
import { withStyles } from 'material-ui/styles'
import Autosuggest from 'react-autosuggest'
import Input from 'material-ui/Input'
import { MenuItem } from 'material-ui/Menu'
import match from 'autosuggest-highlight/match'
import parse from 'autosuggest-highlight/parse'
import ContactList from 'models/ContactList'
import Contact from 'models/Contact'

class RecipientsInputAutocomplete extends Component {
  state = {
    value: '',
    suggestions: [],
  }

  props: {
    contactList: ContactList,
    onRecipientSelect: (contact: Contact) => any,
    inputRef: any,
    selected: Contact[]
  }

  handleSuggestionsFetchRequested({ value }) {
    this.setState({
      suggestions: this.props.contactList.autoComplete(value, this.props.selected),
    })
  }

  handleSuggestionsClearRequested() {
    this.setState({
      suggestions: [],
    })
  }

  handleSuggestionSelected(event, { suggestion }) {
    event.preventDefault()
    event.stopPropagation()

    this.props.onRecipientSelect(suggestion)

    this.setState({
      value: '',
      suggestions: []
    })
  }

  handleChange(event, { newValue }) {
    this.setState({
      value: newValue,
    })
  }

  render() {
    const { classes, inputRef } = this.props

    return (
      <Autosuggest
        ref={inputRef ? inputRef : () => {} }
        theme={{
          container: classes.container,
          suggestionsContainerOpen: classes.suggestionsContainerOpen,
          suggestionsList: classes.suggestionsList,
          suggestion: classes.suggestion,
        }}
        renderInputComponent={renderInput}
        suggestions={this.state.suggestions}
        onSuggestionsFetchRequested={::this.handleSuggestionsFetchRequested}
        onSuggestionsClearRequested={::this.handleSuggestionsClearRequested}
        onSuggestionSelected={::this.handleSuggestionSelected}
        getSuggestionValue={getSuggestionValue}
        renderSuggestion={renderSuggestion}
        highlightFirstSuggestion
        inputProps={{
          autoFocus: true,
          placeholder: 'Search a contact...',
          value: this.state.value,
          onChange: ::this.handleChange,
        }}
      />
    )
  }
}

function renderInput(inputProps) {
  const { home, value, ref, ...other } = inputProps

  return (
    <Input
      autoFocus={home}
      value={value}
      inputRef={ref}
      inputProps={{...other}}
      disableUnderline
    />
  )
}

function renderSuggestion(suggestion: Contact, { query, isHighlighted }) {
  const matches = match(suggestion.identity, query)
  const parts = parse(suggestion.identity, matches)

  return (
    <MenuItem selected={isHighlighted} component="div">
      <div>
        {parts.map((part, index) => {
          return part.highlight
            ? <span key={index} style={{ fontWeight: 300 }}>
                {part.text}
              </span>
            : <strong key={index} style={{ fontWeight: 500 }}>
              {part.text}
            </strong>
        })}
      </div>
    </MenuItem>
  )
}

function getSuggestionValue(suggestion: Contact) {
  return suggestion.identity
}

const style = theme => {
  const backgroundColor = theme.palette.background.emphasize

  return {
    container: {
      flexGrow: 1,
      position: 'relative',
    },
    suggestionsContainerOpen: {
      position: 'absolute',
      left: 0,
      right: 0,
      color: theme.palette.getContrastText(backgroundColor),
      backgroundColor,
      zIndex: 1,
    },
    suggestion: {
      display: 'block',
    },
    suggestionsList: {
      margin: 0,
      padding: 0,
      listStyleType: 'none',
    },
  }
}

export default withStyles(style)(RecipientsInputAutocomplete)
