import React, { Component } from 'react';
import _ from 'lodash';
import { connect } from 'react-redux';
import PropTypes from 'prop-types';
import { submit, isSubmitting, isValid } from 'redux-form';
import { View } from 'react-native';
import { Text, Dialogue } from 'nixplay-ui-kit';
import { ModalForm } from '~comp/Forms/modalForm';

import i18n from '~/locale/i18n';

import { REJECT_FRIEND_INVITE, SHOW_TOAST_ERROR } from '~/store/actionTypes';
import { FRIEND_STATUS_PENDING } from '~/store/contentTypes';

export class FriendsActionsComponent extends Component {
	static propTypes = {
		actions: PropTypes.array,
		route: PropTypes.string.isRequired,
		event: PropTypes.string.isRequired,
		status: PropTypes.string.isRequired,
		toastError: PropTypes.func.isRequired,
	}

	static defaultProps = {
		actions: [
			REJECT_FRIEND_INVITE,
		],
	}

	constructor(props) {
		super(props);

		this.state = {
			selectedInvite: {},
			onActionSuccess: () => {},
		};

		this.dialogue = this.dialogue.bind(this);
		this.closeAction = this.closeAction.bind(this);
		this.submitRejectInvite = this.submitRejectInvite.bind(this);
		this.submitUnfriend = this.submitUnfriend.bind(this);
		this.actionExists = this.actionExists.bind(this);

		this.onSubmitFail = (errors) => {
			const { _error: error } = errors;
			this.props.toastError({
				text: typeof error.toString === 'function' ? error.toString() : error,
			});
		};
	}

	dialogue(action) {
		switch (action) {
			case REJECT_FRIEND_INVITE:
				return this.rejectInviteDialogue;
			default:
				return this.modalNameForm;
		}
	}

	doAction(action, invite, onActionSuccess) {
		if (this.props.actions.indexOf(action) < 0) return;
		this.setState({
			selectedAction: action,
			selectedInvite: invite,
			onActionSuccess,
		}, () => {
			this.dialogue(action).open();
		});
	}

	closeAction(callback) {
		this.dialogue(this.state.selectedAction).close();
		this.setState({
			selectedAction: '',
			selectedInvite: -1,
			onActionSuccess: () => {},
		}, () => {
			if (typeof callback === 'function') callback();
		});
	}

	submitUnfriend(values, dispatch) {
		return new Promise((resolve, reject) => {
			dispatch({
				type: this.state.selectedInvite.type,
				payload: {
					lookupKey: this.state.selectedInvite.requester,
					resolve,
					reject,
				},
			});
		});
	}

	submitRejectInvite(values, dispatch) {
		return new Promise((resolve, reject) => {
			dispatch({
				...values,
				type: this.state.selectedAction,
				payload: {
					requester: this.state.selectedInvite.requester,
					type: this.state.selectedInvite.type,
					resolve,
					reject,
				},
			});
		});
	}

	actionExists(actions) {
		return (_.intersection(this.props.actions, actions)).length > 0;
	}

	render() {
		let bodyMessage = i18n.tWithComponent(
			'friends.rejectFriendInviteConfirm',
			{
				requesterName: (this.state.selectedInvite) ? `${this.state.selectedInvite.requesterFirstName} ${this.state.selectedInvite.requesterLastName}` : '',
			},
			[
				(text) => (<Text key={text} color="blue" fontSize="small">{text}</Text>),
			],
			(text) => (<Text key={text} fontSize="small">{text}</Text>),
		);
		let alertButton = 'common.decline';
		let eventAction = this.submitUnfriend;
		if (this.props.event === 'unfriend') {
			bodyMessage = i18n.tWithComponent(
				'friends.removeFriendConfirm',
				{
					requesterName: (this.state.selectedInvite) ? `${this.state.selectedInvite.requesterFirstName} ${this.state.selectedInvite.requesterLastName}` : '',
				},
				[
					(text) => (<Text key={text} color="blue" fontSize="small">{text}</Text>),
				],
				(text) => (<Text key={text} fontSize="small">{text}</Text>),
			);
			alertButton = 'common.remove';
		}
		if (this.props.status === FRIEND_STATUS_PENDING) {
			eventAction = this.submitRejectInvite;
			bodyMessage = i18n.t('friends.withdrawFriendInviteConfirm');
			alertButton = 'common.ok';
		} else if (_.isEmpty(this.props.status)) {
			eventAction = this.submitRejectInvite;
		}
		return (
			<View>
				{this.actionExists([REJECT_FRIEND_INVITE]) &&
				<ModalForm
					ref={(ref) => { this.rejectInviteDialogue = ref; }}
					form={`${this.props.route}RejectInviteForm`}
					onSubmit={eventAction}
					onSubmitSuccess={() => {
						this.state.onActionSuccess.call();
						this.closeAction();
					}}
					onSubmitFail={(errors) => {
						this.onSubmitFail(errors);
						this.rejectInviteDialogue.reset();
						this.closeAction(this.state.onActionSuccess);
					}}
					onCancel={this.closeAction}
					submitText={i18n.t(alertButton)}
					submitColor="red"
				>
					<Dialogue.Title>{i18n.t('common.confirmation')}</Dialogue.Title>
					<Dialogue.Description>{bodyMessage}</Dialogue.Description>
				</ModalForm>}
			</View>
		);
	}
}

const mapStateToProps = (state, ownProps) => {
	const { route, event } = ownProps;
	let userStatus = '';
	if (_.has(ownProps, 'status')) {
		userStatus = ownProps.status;
	}
	return {
		nameFormMeta: {
			submitting: isSubmitting(`${route}NameForm`)(state),
			valid: isValid(`${route}NameForm`)(state),
		},
		deleteFormMeta: {
			submitting: isSubmitting(`${route}DeleteForm`)(state),
		},
		event,
		status: userStatus,
	};
};

const mapActionsToProps = (dispatch, ownProps) => {
	const { route } = ownProps;
	return {
		submitNameForm() {
			dispatch(submit(`${route}NameForm`));
		},
		submitDeleteForm() {
			dispatch(submit(`${route}DeleteForm`));
		},
		toastError(payload) {
			dispatch({ type: SHOW_TOAST_ERROR, payload });
		},
	};
};


export default connect(
	mapStateToProps,
	mapActionsToProps,
	null,
	{ forwardRef: true },
)(FriendsActionsComponent);
