import React from 'react';
import { connect } from 'react-redux';
import PropTypes from 'prop-types';
import { withRoomContext } from '../RoomContext';
import * as requestActions from '../redux/requestActions';

const BotMessageRegex = new RegExp('^@bot (.*)');

class ChatInput extends React.Component {
	constructor(props) {
		super(props);

		this.state =
		{
			text: ''
		};

		// TextArea element got via React ref.
		// @type {HTMLElement}
		this._textareaElem = null;
	}

	render() {
		const {
			connected,
			chatDataProducer,
			botDataProducer,
			sendUserInfo
		} = this.props;

		const { text } = this.state;

		const disabled = !connected || (!chatDataProducer && !botDataProducer);

		return (
			<div data-component='ChatInput'>
				<textarea
					ref={(elem) => { this._textareaElem = elem; }}
					placeholder={disabled ? '当前聊天不可用' : '说点什么...'}
					dir='auto'
					autoComplete='off'
					disabled={disabled}
					value={text || ''}
					onChange={this.handleChange.bind(this)}
					onKeyPress={this.handleKeyPress.bind(this, sendUserInfo)}
				/>
				<div className='sendOut' onClick={() => {
					this.sendOut(sendUserInfo);
				}}>发送</div>
			</div>
		);
	}

	handleChange(event) {
		const text = event.target.value;

		this.setState({ text });
	}

	handleKeyPress(sendUserInfo, event) {

		// If Shift + Enter do nothing.
		if (event.key !== 'Enter' || (event.shiftKey || event.ctrlKey))
			return;

		// Don't add the sending Enter into the value.
		event.preventDefault();

		this.sendOut(sendUserInfo)
	}

	sendOut(sendUserInfo) {
		let text = this.state.text.trim();

		this.setState({ text: '' });

		if (text) {
			const { roomClient } = this.props;
			const match = BotMessageRegex.exec(text);

			// Chat message.
			if (!match) {
				text = text.trim();
				roomClient.sendChatMessage(text);
				sendUserInfo(text);
			}
			// Message to the bot.
			else {
				text = match[1].trim();

				roomClient.sendBotMessage(text);
			}
		}
	}
}

ChatInput.propTypes =
{
	roomClient: PropTypes.any.isRequired,
	connected: PropTypes.bool.isRequired,
	chatDataProducer: PropTypes.any,
	botDataProducer: PropTypes.any
};

const mapStateToProps = (state) => {
	const dataProducersArray = Object.values(state.dataProducers);
	const chatDataProducer = dataProducersArray
		.find((dataProducer) => dataProducer.label === 'chat');
	const botDataProducer = dataProducersArray
		.find((dataProducer) => dataProducer.label === 'bot');

	return {
		connected: state.room.state === 'connected',
		chatDataProducer,
		botDataProducer
	};
};

const mapDispatchToProps = (dispatch) => {
	return {
		sendUserInfo: (text) => {
			dispatch(requestActions.notify({
				type: 'userMessage',
				isMe: true,
				text: text,
			}));
		}
	};
};

const ChatInputContainer = withRoomContext(connect(
	mapStateToProps,
	mapDispatchToProps,
)(ChatInput));

export default ChatInputContainer;
