text: import React, { Component } from 'react'
  import PropTypes from 'prop-types'
  import sanitizeHtml from 'sanitize-html'
  import FileTransfer from 'components/FileTransfer'
  import { CornerDownRight } from 'react-feather'
  import { connect } from 'react-redux'
  import { clearActivities, showNotice } from '../../actions'
  import { getSelectedText, hasTouchSupport } from '../../utils/dom'
  // Disable for now
  // import autosize from 'autosize'
  
  export class Chat extends Component {
    constructor(props) {
      super(props)
      this.state = {
        message: '',
        touchSupport: hasTouchSupport,
        shiftKeyDown: false,
      }
  
      this.commands = [{
        command: 'nick',
        description: 'Changes nickname.',
        paramaters: ['{username}'],
        usage: '/nick {username}',
        scope: 'global',
        action: (params) => {                      // eslint-disable-line
          let newUsername = params.join(' ') || '' // eslint-disable-line
  
          // Remove things that arent digits or chars
          newUsername = newUsername.replace(/[^A-Za-z0-9]/g, '-')
  
          const errors = []
  
          if (!newUsername.trim().length) {
            errors.push('Имя пользователя не может быть пустым')
          }
  
          if (newUsername.toString().length > 16) {
            errors.push('Имя пользователя не может быть более 16 символов')
          }
  
          if (!newUsername.match(/^[A-Z]/i)) {
            errors.push('Имя пользователя должно начинатся с буквы')
          }
  
          if (errors.length) {
            return this.props.showNotice({
              message: `${errors.join(', ')}`,
              level: 'error',
            })
          }
  
          this.props.sendSocketMessage({
            type: 'CHANGE_USERNAME',
            payload: {
              id: this.props.userId,
              newUsername,
              currentUsername: this.props.username,
            },
          })
        },
      }, {
        command: 'help',
        description: 'Shows a list of commands.',
        paramaters: [],
        usage: '/help',
        scope: 'local',
        action: (params) => { // eslint-disable-line
          const validCommands = this.commands.map(command => `/${command.command}`)
          this.props.showNotice({
            message: `Команды : ${validCommands.sort().join(', ')}`,
            level: 'info',
          })
        },
      }, {
        command: 'me',
        description: 'Invoke virtual action',
        paramaters: ['{action}'],
        usage: '/me {action}',
        scope: 'global',
        action: (params) => { // eslint-disable-line
          const actionMessage = params.join(' ')
          if (!actionMessage.trim().length) {
            return false
          }
  
          this.props.sendSocketMessage({
            type: 'USER_ACTION',
            payload: {
              action: actionMessage,
            },
          })
        },
      }, {
        command: 'clear',
        description: 'Clears the chat screen',
        paramaters: [],
        usage: '/clear',
        scope: 'local',
        action: (params = null) => { // eslint-disable-line
          this.props.clearActivities()
        },
      }]
    }
  
    componentDidMount() {
      if (!hasTouchSupport) {
        // Disable for now due to vary issues:
        // Paste not working, shift+enter line breaks
        // autosize(this.textInput);
        this.textInput.addEventListener('autosize:resized', () => {
          this.props.scrollToBottom()
        })
      }
    }
  
    componentWillReceiveProps(nextProps) {
      if (nextProps.focusChat) {
        if (!getSelectedText()) {
          // Don't focus for now, evaulate UX benfits
          // this.textInput.focus()
        }
      }
    }
  
    componentDidUpdate(nextProps, nextState) {
      if (!nextState.message.trim().length) {
        // autosize.update(this.textInput)
      }
    }
  
    handleKeyUp(e) {
      if (e.key === 'Shift') {
        this.setState({
          shiftKeyDown: false,
        })
      }
    }
  
    handleKeyPress(e) {
      if (e.key === 'Shift') {
        this.setState({
          shiftKeyDown: true,
        })
      }
      // Fix when autosize is enabled - line breaks require shift+enter twice
      if (e.key === 'Enter' && !hasTouchSupport && !this.state.shiftKeyDown) {
        e.preventDefault()
        if (this.canSend()) {
          this.sendMessage()
        } else {
          this.setState({
            message: '',
          })
        }
      }
    }
  
    executeCommand(command) {
      const commandToExecute = this.commands.find(cmnd => cmnd.command === command.command)
  
      if (commandToExecute) {
        const { params } = command
        const commandResult = commandToExecute.action(params)
  
        return commandResult
      }
  
      return null
    }
  
    handleSendClick() {
      this.sendMessage.bind(this)
      this.textInput.focus()
    }
  
    handleFormSubmit(evt) {
      evt.preventDefault()
      this.sendMessage()
    }
  
    parseCommand(message) {
      const commandTrigger = {
        command: null,
        params: [],
      }
  
      if (message.charAt(0) === '/') {
        const parsedCommand = message.replace('/', '').split(' ')
        commandTrigger.command = sanitizeHtml(parsedCommand[0]) || null
        // Get params
        if (parsedCommand.length >= 2) {
          for (let i = 1; i < parsedCommand.length; i++) {
            commandTrigger.params.push(parsedCommand[i])
          }
        }
  
        return commandTrigger
      }
  
      return false
    }
  
    sendMessage() {
      if (!this.canSend()) {
        return
      }
  
      const { message } = this.state
      const isCommand = this.parseCommand(message)
  
      if (isCommand) {
        const res = this.executeCommand(isCommand)
        if (res === false) {
          return
        }
      } else {
        this.props.sendSocketMessage({
          type: 'SEND_MESSAGE',
          payload: {
            text: message,
            timestamp: Date.now(),
          },
        })
      }
  
      this.setState({
        message: '',
      })
    }
  
    handleInputChange(evt) {
      this.setState({
        message: evt.target.value,
      })
    }
  
    canSend() {
      return this.state.message.trim().length
    }
  
    render() {
      const touchSupport = this.state.touchSupport
  
      return (
        <form onSubmit={this.handleFormSubmit.bind(this)} className="chat-preflight-container">
          <textarea
            rows="1"
            onKeyUp={this.handleKeyUp.bind(this)}
            onKeyDown={this.handleKeyPress.bind(this)}
            ref={(input) => { this.textInput = input }}
            autoFocus
            className="chat"
            value={this.state.message}
            placeholder="Пишите"
            onChange={this.handleInputChange.bind(this)} />
          <div className="input-controls">
            <FileTransfer sendSocketMessage={this.props.sendSocketMessage} />
            {touchSupport &&
              <button onClick={this.handleSendClick.bind(this)} className={`icon is-right send btn btn-link ${this.canSend() ? 'active' : ''}`}>
                <CornerDownRight className={this.canSend() ? '' : 'disabled'} />
              </button>
            }
          </div>
        </form>
      )
    }
  }
  
  Chat.propTypes = {
    sendSocketMessage: PropTypes.func.isRequired,
    showNotice: PropTypes.func.isRequired,
    userId: PropTypes.string.isRequired,
    username: PropTypes.string.isRequired,
    clearActivities: PropTypes.func.isRequired,
    focusChat: PropTypes.bool.isRequired,
    scrollToBottom: PropTypes.func.isRequired,
  }
  
  const mapStateToProps = state => ({
    username: state.user.username,
    userId: state.user.id,
  })
  
  const mapDispatchToProps = {
    clearActivities,
    showNotice,
  }
  
  export default connect(
    mapStateToProps,
    mapDispatchToProps
  )(Chat)
  