import React, { Component } from 'react';
import PropTypes from 'prop-types';
import {
	ScrollView, Text, View, StyleSheet, FlatList, LayoutAnimation, SafeAreaView
} from 'react-native';
import { connect } from 'react-redux';
import Icon from 'react-native-vector-icons/MaterialIcons';
import equal from 'deep-equal';

import Navigation from '../lib/Navigation';
import { setStackRoot as setStackRootAction } from '../actions';
import { logout as logoutAction } from '../actions/login';
import Avatar from '../containers/Avatar';
import Status from '../containers/status';
import Touch from '../utils/touch';
import { STATUS_COLORS } from '../constants/colors';
import RocketChat from '../lib/rocketchat';
import log from '../utils/log';
import I18n from '../i18n';
import scrollPersistTaps from '../utils/scrollPersistTaps';
import { getReadableVersion } from '../utils/deviceInfo';

const styles = StyleSheet.create({
	container: {
		flex: 1,
		backgroundColor: '#fff'
	},
	item: {
		flexDirection: 'row',
		alignItems: 'center'
	},
	itemLeft: {
		marginHorizontal: 10,
		width: 30,
		alignItems: 'center'
	},
	itemText: {
		marginVertical: 16,
		fontWeight: 'bold',
		color: '#292E35'
	},
	itemSelected: {
		backgroundColor: '#F7F8FA'
	},
	separator: {
		borderBottomWidth: StyleSheet.hairlineWidth,
		borderColor: '#ddd',
		marginVertical: 4
	},
	header: {
		paddingVertical: 16,
		flexDirection: 'row',
		alignItems: 'center'
	},
	headerTextContainer: {
		flex: 1,
		flexDirection: 'column',
		alignItems: 'flex-start'
	},
	headerUsername: {
		flexDirection: 'row',
		alignItems: 'center'
	},
	avatar: {
		marginHorizontal: 10
	},
	status: {
		borderRadius: 12,
		width: 12,
		height: 12,
		marginRight: 5
	},
	currentServerText: {
		fontWeight: 'bold'
	},
	version: {
		marginHorizontal: 5,
		marginBottom: 5,
		fontWeight: '600',
		color: '#292E35',
		fontSize: 13
	}
});
const keyExtractor = item => item.id;

@connect(state => ({
	Site_Name: state.settings.Site_Name,
	stackRoot: state.app.stackRoot,
	user: {
		id: state.login.user && state.login.user.id,
		language: state.login.user && state.login.user.language,
		status: state.login.user && state.login.user.status,
		username: state.login.user && state.login.user.username,
		token: state.login.user && state.login.user.token
	},
	baseUrl: state.settings.Site_Url || state.server ? state.server.server : ''
}), dispatch => ({
	logout: () => dispatch(logoutAction()),
	setStackRoot: stackRoot => dispatch(setStackRootAction(stackRoot))
}))
export default class Sidebar extends Component {
	static propTypes = {
		baseUrl: PropTypes.string,
		componentId: PropTypes.string,
		Site_Name: PropTypes.string.isRequired,
		stackRoot: PropTypes.string.isRequired,
		user: PropTypes.object,
		logout: PropTypes.func.isRequired,
		setStackRoot: PropTypes.func
	}

	constructor(props) {
		super(props);
		this.state = {
			showStatus: false,
			status: []
		};
		Navigation.events().bindComponent(this);
	}

	componentDidMount() {
		this.setStatus();
	}

	componentWillReceiveProps(nextProps) {
		const { user } = this.props;
		if (nextProps.user && user && user.language !== nextProps.user.language) {
			this.setStatus();
		}
	}

	shouldComponentUpdate(nextProps, nextState) {
		const { status, showStatus } = this.state;
		const {
			Site_Name, stackRoot, user, baseUrl
		} = this.props;
		if (nextState.showStatus !== showStatus) {
			return true;
		}
		if (nextProps.Site_Name !== Site_Name) {
			return true;
		}
		if (nextProps.stackRoot !== stackRoot) {
			return true;
		}
		if (nextProps.Site_Name !== Site_Name) {
			return true;
		}
		if (nextProps.baseUrl !== baseUrl) {
			return true;
		}
		if (nextProps.user && user) {
			if (nextProps.user.language !== user.language) {
				return true;
			}
			if (nextProps.user.status !== user.status) {
				return true;
			}
			if (nextProps.user.username !== user.username) {
				return true;
			}
		}
		if (!equal(nextState.status, status)) {
			return true;
		}
		return false;
	}

	handleChangeStack = (event) => {
		const { stack } = event;
		this.setStack(stack);
	}

	navigationButtonPressed = ({ buttonId }) => {
		if (buttonId === 'cancel') {
			const { componentId } = this.props;
			Navigation.dismissModal(componentId);
		}
	}

	setStatus = () => {
		this.setState({
			status: [{
				id: 'online',
				name: I18n.t('Online')
			}, {
				id: 'busy',
				name: I18n.t('Busy')
			}, {
				id: 'away',
				name: I18n.t('Away')
			}, {
				id: 'offline',
				name: I18n.t('Invisible')
			}]
		});
	}

	setStack = async(stack) => {
		const { stackRoot, setStackRoot } = this.props;
		if (stackRoot !== stack) {
			await Navigation.setStackRoot('AppRoot', {
				component: {
					id: stack,
					name: stack
				}
			});
			setStackRoot(stack);
		}
	}

	closeDrawer = () => {
		Navigation.toggleDrawer();
	}

	toggleStatus = () => {
		LayoutAnimation.easeInEaseOut();
		this.setState(prevState => ({ showStatus: !prevState.showStatus }));
	}

	sidebarNavigate = (stack) => {
		this.closeDrawer();
		this.setStack(stack);
	}

	renderSeparator = key => <View key={key} style={styles.separator} />;

	renderItem = ({
		text, left, onPress, testID, current
	}) => (
		<Touch
			key={text}
			onPress={onPress}
			underlayColor='rgba(255, 255, 255, 0.5)'
			activeOpacity={0.3}
			testID={testID}
		>
			<View style={[styles.item, current && styles.itemSelected]}>
				<View style={styles.itemLeft}>
					{left}
				</View>
				<Text style={styles.itemText}>
					{text}
				</Text>
			</View>
		</Touch>
	)

	renderStatusItem = ({ item }) => {
		const { user } = this.props;
		return (
			this.renderItem({
				text: item.name,
				left: <View style={[styles.status, { backgroundColor: STATUS_COLORS[item.id] }]} />,
				current: user.status === item.id,
				onPress: () => {
					this.closeDrawer();
					this.toggleStatus();
					if (user.status !== item.id) {
						try {
							RocketChat.setUserPresenceDefaultStatus(item.id);
						} catch (e) {
							log('setUserPresenceDefaultStatus', e);
						}
					}
				}
			})
		);
	}

	renderNavigation = () => {
		const { stackRoot } = this.props;
		const { logout } = this.props;
		return (
			[
				this.renderItem({
					text: I18n.t('Chats'),
					left: <Icon name='chat-bubble' size={20} />,
					onPress: () => this.sidebarNavigate('RoomsListView'),
					testID: 'sidebar-chats',
					current: stackRoot === 'RoomsListView'
				}),
				this.renderItem({
					text: I18n.t('Profile'),
					left: <Icon name='person' size={20} />,
					onPress: () => this.sidebarNavigate('ProfileView'),
					testID: 'sidebar-profile',
					current: stackRoot === 'ProfileView'
				}),
				this.renderItem({
					text: I18n.t('Settings'),
					left: <Icon name='settings' size={20} />,
					onPress: () => this.sidebarNavigate('SettingsView'),
					testID: 'sidebar-settings',
					current: stackRoot === 'SettingsView'
				}),
				this.renderSeparator('separator-logout'),
				this.renderItem({
					text: I18n.t('Logout'),
					left: <Icon name='exit-to-app' size={20} />,
					onPress: () => logout(),
					testID: 'sidebar-logout'
				})
			]
		);
	}

	renderStatus = () => {
		const { status } = this.state;
		const { user } = this.props;
		return (
			<FlatList
				key='status-list'
				data={status}
				extraData={user}
				renderItem={this.renderStatusItem}
				keyExtractor={keyExtractor}
			/>
		);
	}

	render() {
		const { showStatus } = this.state;
		const { user, Site_Name, baseUrl } = this.props;

		if (!user) {
			return null;
		}
		return (
			<SafeAreaView testID='sidebar-view' style={styles.container}>
				<ScrollView style={styles.container} {...scrollPersistTaps}>
					<Touch
						onPress={() => this.toggleStatus()}
						underlayColor='rgba(255, 255, 255, 0.5)'
						activeOpacity={0.3}
						testID='sidebar-toggle-status'
					>
						<View style={styles.header}>
							<Avatar
								text={user.username}
								size={30}
								style={styles.avatar}
								baseUrl={baseUrl}
								user={user}
							/>
							<View style={styles.headerTextContainer}>
								<View style={styles.headerUsername}>
									<Status style={styles.status} id={user.id} />
									<Text numberOfLines={1}>{user.username}</Text>
								</View>
								<Text style={styles.currentServerText} numberOfLines={1}>{Site_Name}</Text>
							</View>
							<Icon
								name={showStatus ? 'keyboard-arrow-up' : 'keyboard-arrow-down'}
								size={30}
								style={{ paddingHorizontal: 10 }}
							/>
						</View>
					</Touch>

					{this.renderSeparator('separator-header')}

					{!showStatus ? this.renderNavigation() : null}
					{showStatus ? this.renderStatus() : null}
				</ScrollView>
				<Text style={styles.version}>
					{getReadableVersion}
				</Text>
			</SafeAreaView>
		);
	}
}